diff --git a/examples/hello.v b/examples/hello.v index 48942a5..c97c934 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -55,6 +55,7 @@ fn main(a int) int { str := 'hello' len := str.len str.len = str.len + 1 + x += 1 // str.len += 1 } diff --git a/src/parser.zig b/src/parser.zig index 9c0d436..f3f8605 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -688,7 +688,7 @@ pub const Parser = struct { fn parseAssignment(self: *@This()) anyerror!*Expr { // there can be two assignments coming out of this function: // - a mutable/immutable variable declaration with := - // - an assignment to a variable with = + // - an assignment to a variable with =, +=, -= // one is a statement, other is an expression. since the normal result // of this is an Expr, we wrap variable assignments in an Expr as well. @@ -701,7 +701,9 @@ pub const Parser = struct { var expr = try self.parseOr(); - if (self.check(.ColonEqual) or self.check(.Equal)) { + if (self.compareAnyOf(&[_]TokenType{ + .ColonEqual, .Equal, .PlusEqual, .MinusEqual, + })) { return try self.finishAssignment(expr, mutable); } @@ -713,22 +715,61 @@ pub const Parser = struct { _ = try self.nextToken(); var value = try self.parseAssignment(); + // TODO convert binary's op field from Token to + // something else, maybe enum'd + switch (expr.*) { .Variable => { switch (op.ttype) { .ColonEqual => return try self.mkVarDecl(expr.Variable, value, mutable), .Equal => return try self.mkAssign(expr.Variable, value), + + .PlusEqual => { + var plus_op = try self.mkToken(.Plus, "+", op.line); + return try self.mkAssign( + expr.Variable, + try self.mkBinary(expr, plus_op, value), + ); + }, + + .MinusEqual => { + var new_op = try self.mkToken(.Minus, "-", op.line); + return try self.mkAssign( + expr.Variable, + try self.mkBinary(expr, new_op, value), + ); + }, + else => unreachable, } }, .Get => |get| { - if (op.ttype == .ColonEqual) { - self.doError("can not initialize struct field"); - return Result.CompileError; - } + switch (op.ttype) { + .ColonEqual => { + self.doError("can not initialize struct field"); + return Result.CompileError; + }, - return try self.mkSet(get.struc, get.name, value); + //.PlusEqual => { + // var plus_op = try self.mkToken(.Plus, "+", op.line); + // return try self.mkAssign( + // expr.Variable, + // try self.mkBinary(expr, plus_op, value), + // ); + //}, + + //.MinusEqual => { + // var new_op = try self.mkToken(.Minus, "-", op.line); + // return try self.mkSet( + // get.struc, get.name, + // try self.mkBinary(expr, new_op, value), + // ); + //}, + + .Equal => return try self.mkSet(get.struc, get.name, value), + else => unreachable, + } }, else => |expr_typ| {