From bb66477d1423f16c77986b48acd6156222d7d195 Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Mon, 2 Jun 2025 18:47:24 +0200 Subject: add variable declarations --- src/parse.zig | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/parse.zig') diff --git a/src/parse.zig b/src/parse.zig index cadc489..e240ce3 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -11,6 +11,12 @@ pub const Stmt = struct { pub const Type = union(enum) { expr: *const Expr, + declare_var: DeclareVar, + + pub const DeclareVar = struct { + ident: Lexer.Location, + value: *const Expr, + }; }; pub fn fmt(self: Stmt, file_source: []const u8) Format { @@ -24,6 +30,7 @@ pub const Stmt = struct { _ = options; return switch (self.type) { .expr => |expr| writer.print("{};", .{expr.fmt(file_source)}), + .declare_var => |declare_var| writer.print("let {s} = {};", .{ declare_var.ident.getIdent(file_source), declare_var.value.fmt(file_source) }), }; } }.format); @@ -48,9 +55,7 @@ pub const Expr = struct { plus, minus, - pub fn format(self: Op, comptime f: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { - _ = f; - _ = options; + pub fn format(self: Op, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { try writer.writeByte(switch (self) { .plus => '+', .minus => '-', @@ -70,10 +75,8 @@ pub const Expr = struct { } const Format = std.fmt.Formatter(struct { - fn format(data: struct { Expr, []const u8 }, comptime f: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + fn format(data: struct { Expr, []const u8 }, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { const self, const file_source = data; - _ = f; - _ = options; switch (self.type) { .integer_literal => try writer.print("{}", .{self.loc.getInt(file_source)}), .bin_op => |bin_op| try writer.print("({} {} {})", .{ bin_op.lhs.fmt(file_source), bin_op.op, bin_op.rhs.fmt(file_source) }), @@ -93,12 +96,28 @@ pub fn statements(allocator: Allocator, lexer: *Lexer) ![]Stmt { } pub fn statement(allocator: Allocator, lexer: *Lexer) !Stmt { - var expr = try expression(allocator, lexer); - const semicolon: Lexer.Token = if (lexer.peek().type == .semicolon) lexer.next() else return error.ExpectedSemicolon; - return .{ - .loc = expr.loc.combine(semicolon.loc), - .type = .{ .expr = expr }, - }; + switch (lexer.peek().type) { + .let => { + const let = lexer.next(); + const ident = try mustEat(lexer, .identifier); + _ = try mustEat(lexer, .equal); + const value = try expression(allocator, lexer); + const semicolon = try mustEat(lexer, .semicolon); + return .{ + .loc = let.loc.combine(semicolon.loc), + .type = .{ .declare_var = .{ .ident = ident.loc, .value = value } }, + }; + }, + else => { + var expr = try expression(allocator, lexer); + const semicolon = lexer.next(); + if (semicolon.type != .semicolon) return error.ExpectedSemicolon; + return .{ + .loc = expr.loc.combine(semicolon.loc), + .type = .{ .expr = expr }, + }; + }, + } } pub fn expression(allocator: Allocator, lexer: *Lexer) error{ OutOfMemory, ExpectedRightParen, UnexpectedToken }!*Expr { @@ -159,6 +178,13 @@ pub fn primaryExpr(allocator: Allocator, lexer: *Lexer) !*Expr { }); } +fn mustEat(lexer: *Lexer, ty: Lexer.Token.Type) !Lexer.Token { + const token = lexer.next(); + std.debug.print("Expected {}. Got {}\n", .{ ty, token.type }); + if (token.type != ty) return error.UnexpectedToken; + return token; +} + fn allocate(T: type, allocator: Allocator, t: T) !*T { const res = try allocator.create(T); res.* = t; -- cgit v1.2.3