add struct field getting

This commit is contained in:
Luna 2019-08-26 13:15:08 -03:00
parent c2499f96c9
commit 0ecfb75081
4 changed files with 47 additions and 9 deletions

View file

@ -5,6 +5,11 @@ const (
Businesses = 4 Businesses = 4
) )
struct Point {
x int
y int
}
fn main(a int) int { fn main(a int) int {
1 + 2 + 3 + 4 1 + 2 + 3 + 4
1 + 1 * 1 1 + 1 * 1
@ -41,10 +46,5 @@ fn main(a int) int {
y: 20 y: 20
} }
//println(p.x) println(p.x)
} }
struct Point {
x int
y int
}

View file

@ -80,6 +80,7 @@ pub const ExprType = enum {
Struct, Struct,
Grouping, Grouping,
Get,
}; };
pub const VarDecl = struct { pub const VarDecl = struct {
@ -105,6 +106,11 @@ pub const StructExpr = struct {
inits: StructInitList, inits: StructInitList,
}; };
pub const GetExpr = struct {
struc: *Expr,
name: Token,
};
pub const Expr = union(ExprType) { pub const Expr = union(ExprType) {
Assign: AssignExpr, Assign: AssignExpr,
VarDecl: VarDecl, VarDecl: VarDecl,
@ -118,6 +124,7 @@ pub const Expr = union(ExprType) {
Variable: Token, Variable: Token,
Grouping: *Expr, Grouping: *Expr,
Call: CallExpr, Call: CallExpr,
Get: GetExpr,
}; };
pub const Block = std.ArrayList(*Stmt); pub const Block = std.ArrayList(*Stmt);

View file

@ -4,6 +4,8 @@ const Token = tokens.Token;
usingnamespace @import("ast.zig"); usingnamespace @import("ast.zig");
const warn = std.debug.warn;
fn printIdent(ident: usize) void { fn printIdent(ident: usize) void {
var i: usize = 0; var i: usize = 0;
while (i < ident) : (i += 1) { while (i < ident) : (i += 1) {
@ -177,6 +179,12 @@ pub fn printExpr(expr: *Expr) void {
std.debug.warn("))"); std.debug.warn("))");
}, },
.Get => |get| {
warn("(");
printExpr(get.struc);
warn(".{})", get.name.lexeme);
},
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)), else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
} }
} }

View file

@ -89,7 +89,11 @@ pub const Parser = struct {
} }
fn consume(self: *Parser, ttype: TokenType, comptime msg: []const u8) !Token { 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); try self.tokenError(self.peek(), msg);
return Result.CompileError; return Result.CompileError;
@ -271,6 +275,18 @@ pub const Parser = struct {
return expr; 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 { fn mkBool(self: *Parser, val: bool) !*ast.Expr {
var expr = try self.allocator.create(Expr); var expr = try self.allocator.create(Expr);
expr.* = Expr{ expr.* = Expr{
@ -724,8 +740,14 @@ pub const Parser = struct {
expr = try self.finishCall(expr); expr = try self.finishCall(expr);
} else if (self.check(.Dot)) { } else if (self.check(.Dot)) {
_ = try self.consumeSingle(.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 { } else {
break; 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"); var paren = try self.consume(.RightParen, "Expected ')' after arguments");
return self.mkCall(callee, paren, args); return self.mkCall(callee, paren, args);