add boolean AND and boolean OR
This commit is contained in:
parent
9b3e9e8139
commit
1ab966b853
5 changed files with 64 additions and 5 deletions
|
@ -17,4 +17,7 @@ fn main(a int) int {
|
||||||
} else {
|
} else {
|
||||||
println(50)
|
println(50)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a && b
|
||||||
|
a || b
|
||||||
}
|
}
|
||||||
|
|
10
src/ast.zig
10
src/ast.zig
|
@ -46,6 +46,13 @@ pub const UnaryExpr = struct {
|
||||||
right: *Expr,
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// looks like a BinaryExpr, but is not a BinaryExpr
|
||||||
|
pub const LogicalExpr = struct {
|
||||||
|
left: *Expr,
|
||||||
|
op: Token,
|
||||||
|
right: *Expr,
|
||||||
|
};
|
||||||
|
|
||||||
pub const LiteralExpr = union(enum) {
|
pub const LiteralExpr = union(enum) {
|
||||||
Bool: bool,
|
Bool: bool,
|
||||||
Integer: []const u8,
|
Integer: []const u8,
|
||||||
|
@ -66,6 +73,7 @@ pub const ExprType = enum {
|
||||||
|
|
||||||
Binary,
|
Binary,
|
||||||
Unary,
|
Unary,
|
||||||
|
Logical,
|
||||||
Literal,
|
Literal,
|
||||||
Variable,
|
Variable,
|
||||||
Grouping,
|
Grouping,
|
||||||
|
@ -82,6 +90,7 @@ pub const Expr = union(ExprType) {
|
||||||
|
|
||||||
Binary: BinaryExpr,
|
Binary: BinaryExpr,
|
||||||
Unary: UnaryExpr,
|
Unary: UnaryExpr,
|
||||||
|
Logical: LogicalExpr,
|
||||||
Literal: LiteralExpr,
|
Literal: LiteralExpr,
|
||||||
|
|
||||||
Variable: Token,
|
Variable: Token,
|
||||||
|
@ -239,6 +248,7 @@ fn parenthetize(name: []const u8, exprs: []*Expr) void {
|
||||||
pub fn printExpr(expr: *Expr) void {
|
pub fn printExpr(expr: *Expr) void {
|
||||||
switch (expr.*) {
|
switch (expr.*) {
|
||||||
.Binary => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
.Binary => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
||||||
|
.Logical => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
||||||
.Unary => |unary| parenthetize(unary.op.lexeme, &[_]*Expr{unary.right}),
|
.Unary => |unary| parenthetize(unary.op.lexeme, &[_]*Expr{unary.right}),
|
||||||
.Grouping => |expr_ptr| parenthetize("group", &[_]*Expr{expr_ptr}),
|
.Grouping => |expr_ptr| parenthetize("group", &[_]*Expr{expr_ptr}),
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,19 @@ pub const Parser = struct {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mkLogical(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr {
|
||||||
|
var expr = try self.allocator.create(Expr);
|
||||||
|
expr.* = Expr{
|
||||||
|
.Logical = ast.LogicalExpr{
|
||||||
|
.left = left,
|
||||||
|
.op = op,
|
||||||
|
.right = right,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
fn mkAssign(self: *Parser, name: Token, value: *Expr) !*Expr {
|
fn mkAssign(self: *Parser, name: Token, value: *Expr) !*Expr {
|
||||||
var expr = try self.allocator.create(Expr);
|
var expr = try self.allocator.create(Expr);
|
||||||
expr.* = Expr{
|
expr.* = Expr{
|
||||||
|
@ -518,7 +531,7 @@ pub const Parser = struct {
|
||||||
mutable = true;
|
mutable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var expr = try self.parseEquality();
|
var expr = try self.parseOr();
|
||||||
std.debug.warn("lvalue: {}, cur: {}\n", expr, self.peek());
|
std.debug.warn("lvalue: {}, cur: {}\n", expr, self.peek());
|
||||||
|
|
||||||
var value: *Expr = undefined;
|
var value: *Expr = undefined;
|
||||||
|
@ -545,10 +558,38 @@ pub const Parser = struct {
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parseOr(self: *@This()) !*Expr {
|
||||||
|
var expr = try self.parseAnd();
|
||||||
|
|
||||||
|
while (self.check(.Or)) {
|
||||||
|
var op = self.peek();
|
||||||
|
_ = try self.nextToken();
|
||||||
|
|
||||||
|
var right = try self.parseAnd();
|
||||||
|
expr = try self.mkLogical(expr, op, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseAnd(self: *@This()) !*Expr {
|
||||||
|
var expr = try self.parseEquality();
|
||||||
|
|
||||||
|
while (self.check(.And)) {
|
||||||
|
var op = self.peek();
|
||||||
|
_ = try self.nextToken();
|
||||||
|
|
||||||
|
var right = try self.parseEquality();
|
||||||
|
expr = try self.mkLogical(expr, op, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
fn parseEquality(self: *@This()) !*Expr {
|
fn parseEquality(self: *@This()) !*Expr {
|
||||||
var expr = try self.parseComparison();
|
var expr = try self.parseComparison();
|
||||||
|
|
||||||
while (self.peek().ttype == .EqualEqual) {
|
while (self.check(.EqualEqual)) {
|
||||||
var op = self.peek();
|
var op = self.peek();
|
||||||
_ = try self.nextToken();
|
_ = try self.nextToken();
|
||||||
|
|
||||||
|
|
|
@ -288,8 +288,6 @@ pub const Scanner = struct {
|
||||||
'.' => self.makeToken(.Dot),
|
'.' => self.makeToken(.Dot),
|
||||||
';' => self.makeToken(.Semicolon),
|
';' => self.makeToken(.Semicolon),
|
||||||
',' => self.makeToken(.Comma),
|
',' => self.makeToken(.Comma),
|
||||||
'&' => self.makeToken(.Ampersand),
|
|
||||||
'|' => self.makeToken(.Pipe),
|
|
||||||
'?' => self.makeToken(.QuestionMark),
|
'?' => self.makeToken(.QuestionMark),
|
||||||
'$' => self.makeToken(.DollarSign),
|
'$' => self.makeToken(.DollarSign),
|
||||||
|
|
||||||
|
@ -299,6 +297,12 @@ pub const Scanner = struct {
|
||||||
|
|
||||||
':' => self.makeMatchToken('=', .ColonEqual, .Colon),
|
':' => self.makeMatchToken('=', .ColonEqual, .Colon),
|
||||||
|
|
||||||
|
// we use the existing .And and .Or tokens
|
||||||
|
// representing the and and or keywords to
|
||||||
|
// also have || and &&
|
||||||
|
'&' => self.makeMatchToken('&', .And, .Address),
|
||||||
|
'|' => self.makeMatchToken('|', .Or, .Pipe),
|
||||||
|
|
||||||
'!' => self.makeMatchToken('=', .BangEqual, .Bang),
|
'!' => self.makeMatchToken('=', .BangEqual, .Bang),
|
||||||
'=' => self.makeMatchToken('=', .EqualEqual, .Equal),
|
'=' => self.makeMatchToken('=', .EqualEqual, .Equal),
|
||||||
'>' => self.makeMatchToken('=', .GreaterEqual, .Greater),
|
'>' => self.makeMatchToken('=', .GreaterEqual, .Greater),
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub const TokenType = enum {
|
||||||
Semicolon,
|
Semicolon,
|
||||||
Comma,
|
Comma,
|
||||||
Colon,
|
Colon,
|
||||||
Ampersand,
|
Address,
|
||||||
Pipe,
|
Pipe,
|
||||||
QuestionMark,
|
QuestionMark,
|
||||||
DollarSign,
|
DollarSign,
|
||||||
|
@ -65,6 +65,7 @@ pub const TokenType = enum {
|
||||||
Module,
|
Module,
|
||||||
Mut,
|
Mut,
|
||||||
Or,
|
Or,
|
||||||
|
And,
|
||||||
Return,
|
Return,
|
||||||
Struct,
|
Struct,
|
||||||
Type,
|
Type,
|
||||||
|
|
Loading…
Reference in a new issue