From 4f0d505c651a19c6f8b349cafa26a82aaffc8d9b Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 27 Feb 2020 18:02:40 +0100 Subject: [PATCH] v2: `if x := `; fix `for key, val in`; CastExpr --- vlib/v/ast/ast.v | 23 +++++++++++++++-------- vlib/v/fmt/fmt.v | 19 +++++++++++++++++-- vlib/v/parser/parser.v | 25 +++++++++++++++++++++---- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1e20f9d8e3..236fb895b3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,11 +11,11 @@ import ( pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | -CastExpr | EnumVal | Assoc | SizeOf | None | MapInit +CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | OrExpr -pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | +pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | +ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | LineComment | MultiLineComment | AssertStmt | UnsafeStmt pub type Type = StructType | ArrayType @@ -351,10 +351,11 @@ pub: pub struct ForInStmt { pub: - var string - cond Expr - stmts []Stmt - pos token.Position + key_var string + val_var string + cond Expr + stmts []Stmt + pos token.Position } pub struct ForCStmt { @@ -481,6 +482,12 @@ pub: expr Expr } +pub struct OrExpr { +pub: + var_name string + expr Expr +} + pub struct Assoc { pub: name string diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index fa48120ceb..1114a0282c 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -159,7 +159,11 @@ fn (f mut Fmt) stmt(node ast.Stmt) { f.writeln('}\n') } ast.ForInStmt { - f.write('for $it.var in ') + f.write('for $it.key_var') + if it.val_var != '' { + f.write(', $it.val_var') + } + f.write(' in ') f.expr(it.cond) f.writeln(' {') f.stmts(it.stmts) @@ -282,6 +286,11 @@ fn (f mut Fmt) expr(node ast.Expr) { ast.BoolLiteral { f.write(it.val.str()) } + ast.CastExpr { + f.write(f.table.type_to_str(it.typ) + '(') + f.expr(it.expr) + f.write(')') + } ast.CallExpr { f.write('${it.name}(') for i, expr in it.args { @@ -387,6 +396,10 @@ fn (f mut Fmt) expr(node ast.Expr) { ast.None { f.write('none') } + ast.OrExpr { + f.write(it.var_name + ' := ') + f.expr(it.expr) + } ast.PostfixExpr { f.expr(it.expr) f.write(it.op.str()) @@ -424,7 +437,9 @@ fn (f mut Fmt) expr(node ast.Expr) { f.write('}') } } - else {} + else { + println('fmt expr: unhandled node ') // + typeof(node)) + } } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 721f20f66b..bf3e823896 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1035,9 +1035,10 @@ fn (p mut Parser) for_statement() ast.Stmt { // `for i in vals`, `for i in start .. end` else if p.peek_tok.kind in [.key_in, .comma] { var_name := p.check_name() + mut val_name := '' if p.tok.kind == .comma { p.check(.comma) - val_name := p.check_name() + val_name = p.check_name() // p.table.register_var(table.Var{ // name: val_name // typ: table.int_type @@ -1092,7 +1093,8 @@ fn (p mut Parser) for_statement() ast.Stmt { stmts: stmts pos: p.tok.position() cond: cond - var: var_name + key_var: var_name + val_var: val_name } } // `for cond {` @@ -1115,10 +1117,22 @@ fn (p mut Parser) if_expr() ast.Expr { pos := p.tok.position() // `if x := opt() {` mut cond := ast.Expr{} + mut is_or := false if p.peek_tok.kind == .decl_assign { - p.next() + is_or = true + p.open_scope() + var_name := p.check_name() + // p.table.register_var( p.check(.decl_assign) - p.expr(0) + expr,typ := p.expr(0) + p.scope.register_var(ast.VarDecl{ + name: var_name + typ: typ + }) + cond = ast.OrExpr{ + var_name: var_name + expr: expr + } } else { cond,_ = p.expr(0) @@ -1138,6 +1152,9 @@ fn (p mut Parser) if_expr() ast.Expr { else_stmts = p.parse_block() } } + if is_or { + p.close_scope() + } // mut typ := table.void_type // mut left := ast.Expr{} // If the last statement is an expression, return its type