From 0ecfb750817b153a53c7297e366505fe2f1178f8 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 26 Aug 2019 13:15:08 -0300 Subject: [PATCH] add struct field getting --- examples/hello.v | 12 ++++++------ src/ast.zig | 7 +++++++ src/ast_printer.zig | 8 ++++++++ src/parser.zig | 29 ++++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/examples/hello.v b/examples/hello.v index af539b5..74308b6 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -5,6 +5,11 @@ const ( Businesses = 4 ) +struct Point { + x int + y int +} + fn main(a int) int { 1 + 2 + 3 + 4 1 + 1 * 1 @@ -41,10 +46,5 @@ fn main(a int) int { y: 20 } - //println(p.x) + println(p.x) } - -struct Point { - x int - y int -} diff --git a/src/ast.zig b/src/ast.zig index c031733..acce1d1 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -80,6 +80,7 @@ pub const ExprType = enum { Struct, Grouping, + Get, }; pub const VarDecl = struct { @@ -105,6 +106,11 @@ pub const StructExpr = struct { inits: StructInitList, }; +pub const GetExpr = struct { + struc: *Expr, + name: Token, +}; + pub const Expr = union(ExprType) { Assign: AssignExpr, VarDecl: VarDecl, @@ -118,6 +124,7 @@ pub const Expr = union(ExprType) { Variable: Token, Grouping: *Expr, Call: CallExpr, + Get: GetExpr, }; pub const Block = std.ArrayList(*Stmt); diff --git a/src/ast_printer.zig b/src/ast_printer.zig index a44aa33..1574a5b 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -4,6 +4,8 @@ const Token = tokens.Token; usingnamespace @import("ast.zig"); +const warn = std.debug.warn; + fn printIdent(ident: usize) void { var i: usize = 0; while (i < ident) : (i += 1) { @@ -177,6 +179,12 @@ pub fn printExpr(expr: *Expr) void { std.debug.warn("))"); }, + .Get => |get| { + warn("("); + printExpr(get.struc); + warn(".{})", get.name.lexeme); + }, + else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)), } } diff --git a/src/parser.zig b/src/parser.zig index f300ddc..21b761b 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -89,7 +89,11 @@ pub const Parser = struct { } fn consume(self: *Parser, ttype: TokenType, comptime msg: []const u8) !Token { - if (self.check(ttype)) return try self.nextToken(); + if (self.check(ttype)) { + var tok = self.peek(); + _ = try self.nextToken(); + return tok; + } try self.tokenError(self.peek(), msg); return Result.CompileError; @@ -271,6 +275,18 @@ pub const Parser = struct { return expr; } + fn mkGet(self: *@This(), struc: *Expr, name: Token) !*Expr { + var expr = try self.allocator.create(Expr); + expr.* = Expr{ + .Get = ast.GetExpr{ + .struc = struc, + .name = name, + }, + }; + + return expr; + } + fn mkBool(self: *Parser, val: bool) !*ast.Expr { var expr = try self.allocator.create(Expr); expr.* = Expr{ @@ -724,8 +740,14 @@ pub const Parser = struct { expr = try self.finishCall(expr); } else if (self.check(.Dot)) { _ = try self.consumeSingle(.Dot); - _ = try self.consumeSingle(.LeftBrace); - expr = try self.finishStructVal(expr); + + if (self.check(.LeftBrace)) { + _ = try self.consumeSingle(.LeftBrace); + expr = try self.finishStructVal(expr); + } else { + var name = try self.consume(.Identifier, "Expect property name after '.'"); + expr = try self.mkGet(expr, name); + } } else { break; } @@ -752,6 +774,7 @@ pub const Parser = struct { } } + // TODO shouldnt consume() return the current token, not nextToken? var paren = try self.consume(.RightParen, "Expected ')' after arguments"); return self.mkCall(callee, paren, args);