add assignment to struct fields

This commit is contained in:
Luna 2019-08-26 13:29:45 -03:00
parent d55137a7c7
commit 45b027e90f
4 changed files with 53 additions and 8 deletions

View file

@ -46,5 +46,7 @@ fn main(a int) int {
y: 20 y: 20
} }
p.x = 69
println(egg.scramble(3).with(cheddar)) println(egg.scramble(3).with(cheddar))
} }

View file

@ -81,6 +81,7 @@ pub const ExprType = enum {
Grouping, Grouping,
Get, Get,
Set,
}; };
pub const VarDecl = struct { pub const VarDecl = struct {
@ -111,6 +112,12 @@ pub const GetExpr = struct {
name: Token, name: Token,
}; };
pub const SetExpr = struct {
struc: *Expr,
field: Token,
value: *Expr,
};
pub const Expr = union(ExprType) { pub const Expr = union(ExprType) {
Assign: AssignExpr, Assign: AssignExpr,
VarDecl: VarDecl, VarDecl: VarDecl,
@ -124,7 +131,9 @@ pub const Expr = union(ExprType) {
Variable: Token, Variable: Token,
Grouping: *Expr, Grouping: *Expr,
Call: CallExpr, Call: CallExpr,
Get: GetExpr, Get: GetExpr,
Set: SetExpr,
}; };
pub const Block = std.ArrayList(*Stmt); pub const Block = std.ArrayList(*Stmt);

View file

@ -185,6 +185,14 @@ pub fn printExpr(expr: *Expr) void {
warn(".{})", get.name.lexeme); warn(".{})", get.name.lexeme);
}, },
.Set => |set| {
warn("(set ");
printExpr(set.struc);
warn(" {} ", set.field.lexeme);
printExpr(set.value);
warn(")");
},
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)), else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
} }
} }

View file

@ -287,6 +287,19 @@ pub const Parser = struct {
return expr; return expr;
} }
fn mkSet(self: *@This(), struc: *Expr, field: Token, value: *Expr) !*Expr {
var expr = try self.allocator.create(Expr);
expr.* = Expr{
.Set = ast.SetExpr{
.struc = struc,
.field = field,
.value = value,
},
};
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{
@ -598,15 +611,28 @@ pub const Parser = struct {
_ = try self.nextToken(); _ = try self.nextToken();
value = try self.parseAssignment(); value = try self.parseAssignment();
if (ast.ExprType(expr.*) != .Variable) { switch (expr.*) {
self.doError("Invalid assignment target"); .Variable => {
return Result.CompileError; switch (op.ttype) {
} .ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable),
.Equal => return try self.mkAssign(expr.Variable, value),
else => unreachable,
}
},
switch (op.ttype) { .Get => |get| {
.ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable), if (op.ttype == .ColonEqual) {
.Equal => return try self.mkAssign(expr.Variable, value), self.doError("can not initialize struct field");
else => unreachable, return Result.CompileError;
}
return try self.mkSet(get.struc, get.name, value);
},
else => |expr_typ| {
self.doError("Invalid assignment target {}", expr_typ);
return Result.CompileError;
},
} }
} }