add assignment to struct fields
This commit is contained in:
parent
d55137a7c7
commit
45b027e90f
4 changed files with 53 additions and 8 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.*)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue