diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 2abf804b5d..3076321bb9 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,7 +11,7 @@ import ( pub type Expr = BinaryExpr | UnaryExpr | IfExpr | StringLiteral | IntegerLiteral | FloatLiteral | Ident -pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt +pub type Stmt = VarDecl | FnDecl | Return | Module | Import | ExprStmt | AssignStmt // Stand-alone expression in a statement list. pub struct ExprStmt { pub: @@ -101,12 +101,12 @@ pub: pub struct BinaryExpr { pub: - tok_kind token.TokenKind - // op BinaryOp - op token.TokenKind - left Expr +// tok_kind token.TokenKind +// op BinaryOp + op token.TokenKind + left Expr // left_type Type - right Expr + right Expr // right_type Type } @@ -118,18 +118,25 @@ pub: left Expr } -struct IfExpr { +pub struct IfExpr { tok_kind token.TokenKind cond Expr body []Stmt else_ []Stmt } -struct ReturnStmt { +pub struct ReturnStmt { tok_kind token.TokenKind // or pos results []Expr } +pub struct AssignStmt { +pub: + left Expr + right Expr + op token.TokenKind +} + // string representaiton of expr pub fn (x Expr) str() string { match x { diff --git a/vlib/v/cgen/cgen.v b/vlib/v/cgen/cgen.v index e888af22be..2df99c070f 100644 --- a/vlib/v/cgen/cgen.v +++ b/vlib/v/cgen/cgen.v @@ -32,6 +32,12 @@ pub fn (g mut Gen) writeln(s string) { fn (g mut Gen) stmt(node ast.Stmt) { match node { + ast.AssignStmt { + g.expr(it.left) + g.write(' $it.op.str() ') + g.expr(it.right) + g.writeln(';') + } ast.FnDecl { g.writeln('$it.typ.name ${it.name}() { ') for stmt in it.stmts { diff --git a/vlib/v/cgen/tests/2.c b/vlib/v/cgen/tests/2.c index cb29fee31b..855757c610 100644 --- a/vlib/v/cgen/tests/2.c +++ b/vlib/v/cgen/tests/2.c @@ -9,5 +9,5 @@ void function2() { f64 f = 10.1; string s = tos3("hi"); int m = 10; - m += 10; + x += 10; } diff --git a/vlib/v/cgen/tests/2.v b/vlib/v/cgen/tests/2.v index 052cfef3e3..44cc7baeb0 100644 --- a/vlib/v/cgen/tests/2.v +++ b/vlib/v/cgen/tests/2.v @@ -6,10 +6,10 @@ fn function1() int { // comment fn function2() { - x := 0 + mut x := 0 f := 10.1 s := 'hi' m := 10 - m += 10 + x += 10 //c := 0 } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 00be54da1d..2aaf437df3 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -133,9 +133,15 @@ fn (p mut Parser) check_name() string { } pub fn (p mut Parser) stmt() ast.Stmt { + // println('stmt at ' + p.tok.str()) // `x := ...` - if p.tok.kind == .name && p.peek_tok.kind == .decl_assign { - return p.var_decl() + if p.tok.kind == .name { + if p.peek_tok.kind == .decl_assign { + return p.var_decl() + } + else if p.peek_tok.is_assign() { + return p.assign_stmt() + } } match p.tok.kind { .key_module { @@ -162,18 +168,27 @@ pub fn (p mut Parser) stmt() ast.Stmt { } } +pub fn (p mut Parser) assign_stmt() ast.AssignStmt { + left_expr,left_type := p.expr(0) + op := p.tok.kind + println('assignn_stmt() ' + op.str()) + p.next() + right_expr,right_type := p.expr(0) + return ast.AssignStmt{ + left: left_expr + right: right_expr + op: op + } +} + // Implementation of Pratt Precedence pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { - println('expr at ' + p.tok.str()) + // println('expr at ' + p.tok.str()) // null denotation (prefix) mut node := ast.Expr{} mut typ := types.void_type match p.tok.kind { .name { - // `x := ...` - // if p.peek_tok.kind == .decl_assign { - // return p.var_decl() - // } // name expr node = ast.Ident{ name: p.tok.lit @@ -215,6 +230,16 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { if prev_tok.is_right_assoc() { mut expr := ast.Expr{} expr,t2 = p.expr(prev_tok.precedence() - 1) + /* + if prev_tok.is_assign() { + return ast.AssignStmt { + left: node + op: prev_tok.kind + right: expr + }, types.void_type + } + */ + node = ast.BinaryExpr{ left: node // left_type: t1 diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 8f90f56f22..df1813ecf0 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -267,8 +267,8 @@ pub fn is_decl(t TokenKind) bool { return t in [.key_enum, .key_interface, .key_fn, .key_struct, .key_type, .key_const, .key_import_const, .key_pub, .eof] } -fn (t TokenKind) is_assign() bool { - return t in assign_tokens +pub fn (t Token) is_assign() bool { + return t.kind in assign_tokens } fn (t []TokenKind) contains(val TokenKind) bool { @@ -331,9 +331,9 @@ pub fn (tok Token) precedence() int { .logical_or { return 3 } - .plus_assign { - return 2 - } + // /.plus_assign { + // /return 2 + // /} else { return lowest_prec }