diff options
Diffstat (limited to 'src/parse.zig')
-rw-r--r-- | src/parse.zig | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/parse.zig b/src/parse.zig index 92fb219..8347687 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -43,11 +43,12 @@ pub const Stmt = struct { pub const Type = union(enum) { expr: *const Expr, - declare_var: DeclareVar, + assign_var: AssignVar, block: Block, - pub const DeclareVar = struct { + pub const AssignVar = struct { ident: Lexer.Location, + is_decl: bool, value: *const Expr, }; }; @@ -57,9 +58,10 @@ pub const Stmt = struct { return switch (self.type) { .expr => |expr| writer.print("{}", .{fmt(expr, source, indent)}), .block => |b| writer.print("{}", .{fmt(b, source, indent)}), - .declare_var => |declare_var| writer.print("let {s} = {}", .{ - declare_var.ident.getIdent(source), - fmt(declare_var.value, source, indent), + .assign_var => |assign_var| writer.print("{s}{s} = {}", .{ + if (assign_var.is_decl) "let " else "", + assign_var.ident.getIdent(source), + fmt(assign_var.value, source, indent), }), }; } @@ -129,7 +131,7 @@ pub const Expr = struct { } }; -const ParseError = error{ OutOfMemory, ExpectedRightParen, UnexpectedToken }; +const ParseError = error{ OutOfMemory, ExpectedRightParen, UnexpectedToken, InvalidAssignTarget }; pub fn block(allocator: Allocator, lexer: *Lexer) !Block { const left_curly = try mustEat(lexer, .left_curly); @@ -153,7 +155,7 @@ pub fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt { const value = try expression(allocator, lexer); return .{ .loc = let.loc.combine(value.loc), - .type = .{ .declare_var = .{ .ident = ident.loc, .value = value } }, + .type = .{ .assign_var = .{ .ident = ident.loc, .is_decl = true, .value = value } }, }; }, .left_curly => { @@ -164,10 +166,22 @@ pub fn statement(allocator: Allocator, lexer: *Lexer) ParseError!Stmt { }; }, else => { - const expr = try expression(allocator, lexer); + const lhs = try expression(allocator, lexer); + if (lexer.peek().type == .equal) { + _ = try mustEat(lexer, .equal); + const value = try expression(allocator, lexer); + if (lhs.type != .identifier) { + std.debug.print("Invalid assign target. Found '{s}', expected an identifier.", .{@tagName(lhs.type)}); + return error.InvalidAssignTarget; + } + return .{ + .loc = lhs.loc, + .type = .{ .assign_var = .{ .ident = lhs.loc, .is_decl = false, .value = value } }, + }; + } return .{ - .loc = expr.loc, - .type = .{ .expr = expr }, + .loc = lhs.loc, + .type = .{ .expr = lhs }, }; }, } @@ -247,7 +261,7 @@ pub fn parsePrimaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr { .integer_literal => .{ .loc = token.loc, .type = .integer_literal }, .identifier => .{ .loc = token.loc, .type = .identifier }, else => |t| { - std.debug.print("Expected '(', integer literal, or identifier. Got {}\n", .{t}); + std.debug.print("Expected '(', integer literal, or identifier. Got '{s}'\n", .{@tagName(t)}); return error.UnexpectedToken; }, }); |