From ccf4f61521e71ee358a690779a4547a89d74b69a Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 28 Feb 2020 15:36:41 +0100 Subject: [PATCH] ast: ParExpr, OrExpr, IfGuardExpr; ForInStmt fix; remove all cap vars --- .github/FUNDING.yml | 1 + vlib/compiler/aparser.v | 34 +++++++++++++++++----------------- vlib/v/ast/ast.v | 36 ++++++++++++++++++++++++------------ vlib/v/fmt/fmt.v | 15 ++++++++++++--- vlib/v/parser/parser.v | 34 ++++++++++++++++++++++------------ 5 files changed, 76 insertions(+), 44 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 47bcee121..c74b9d3f7 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ # These are supported funding model platforms patreon: vlang +github: [medvednikov] diff --git a/vlib/compiler/aparser.v b/vlib/compiler/aparser.v index 90486d093..7b4bbb29e 100644 --- a/vlib/compiler/aparser.v +++ b/vlib/compiler/aparser.v @@ -2014,21 +2014,21 @@ fn (p mut Parser) var_expr(v Var) string { mut typ := v.typ // Function pointer? if p.base_type(typ).starts_with('fn ') && p.tok == .lpar { - T := p.table.find_type(p.base_type(typ)) + tt := p.table.find_type(p.base_type(typ)) p.gen('(') - p.fn_call_args(mut T.func, []) + p.fn_call_args(mut tt.func, []) p.gen(')') - typ = T.func.typ + typ = tt.func.typ } // users[0].name if p.tok == .lsbr { typ = p.index_expr(typ, fn_ph) if p.base_type(typ).starts_with('fn ') && p.tok == .lpar { - T := p.table.find_type(p.base_type(typ)) + tt := p.table.find_type(p.base_type(typ)) p.gen('(') - p.fn_call_args(mut T.func, []) + p.fn_call_args(mut tt.func, []) p.gen(')') - typ = T.func.typ + typ = tt.func.typ } } // a.b.c().d chain @@ -2364,10 +2364,10 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string { // [2.. if p.tok != .dotdot { index_pos := p.cgen.cur_line.len - T := p.table.find_type(p.expression()) + tt := p.table.find_type(p.expression()) // Allows only i8-64 and byte-64 to be used when accessing an array - if T.parent != 'int' && T.parent != 'u32' { - p.check_types(T.name, 'int') + if tt.parent != 'int' && tt.parent != 'u32' { + p.check_types(tt.name, 'int') } if p.cgen.cur_line[index_pos..].replace(' ', '').int() < 0 { p.error('cannot access negative array index') @@ -2402,10 +2402,10 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string { } } else { - T := p.table.find_type(p.expression()) + tt := p.table.find_type(p.expression()) // TODO: Get the key type of the map instead of only string. - if is_map && T.parent != 'string' { - p.check_types(T.name, 'string') + if is_map && tt.parent != 'string' { + p.check_types(tt.name, 'string') } } p.check(.rsbr) @@ -3065,14 +3065,14 @@ fn (p mut Parser) js_decode() string { cjson_tmp := p.get_tmp() mut decl := '$typ $tmp; ' // Init the struct - T := p.table.find_type(typ) - for field in T.fields { + tt := p.table.find_type(typ) + for field in tt.fields { def_val := type_default(field.typ) if def_val != '' { decl += '${tmp}.$field.name = OPTION_CAST($field.typ) $def_val;\n' } } - p.gen_json_for_type(T) + p.gen_json_for_type(tt) decl += 'cJSON* $cjson_tmp = json__json_parse($expr);' p.cgen.insert_before(decl) // p.gen('jsdecode_$typ(json_parse($expr), &$tmp);') @@ -3085,8 +3085,8 @@ fn (p mut Parser) js_decode() string { else if op == 'encode' { p.check(.lpar) typ,expr := p.tmp_expr() - T := p.table.find_type(typ) - p.gen_json_for_type(T) + tt := p.table.find_type(typ) + p.gen_json_for_type(tt) p.check(.rpar) p.gen('json__json_print(json__jsencode_${typ}($expr))') return 'string' diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index a4744a0fa..a3fd1d565 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,7 +11,7 @@ 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 | OrExpr | ParExpr +CastExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | @@ -159,11 +159,12 @@ mut: pub struct MethodCallExpr { pub: // tok token.Token - pos token.Position - expr Expr - name string - args []Expr - muts []bool + pos token.Position + expr Expr + name string + args []Expr + muts []bool + or_block OrExpr } pub struct Return { @@ -355,11 +356,13 @@ pub: pub struct ForInStmt { pub: - key_var string - val_var string - cond Expr - stmts []Stmt - pos token.Position + key_var string + val_var string + cond Expr + is_range bool + high Expr // `10` in `for i in 0..10 {` + stmts []Stmt + pos token.Position } pub struct ForCStmt { @@ -492,12 +495,21 @@ pub: expr Expr } -pub struct OrExpr { +// `if [x := opt()] {` +pub struct IfGuardExpr { pub: var_name string expr Expr } +// `or { ... }` +pub struct OrExpr { +pub: + stmts []Stmt + // 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 0c95c2c46..1c3b52ed2 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -168,6 +168,10 @@ fn (f mut Fmt) stmt(node ast.Stmt) { } f.write(' in ') f.expr(it.cond) + if it.is_range { + f.write(' .. ') + f.expr(it.high) + } f.writeln(' {') f.stmts(it.stmts) f.writeln('}') @@ -421,19 +425,24 @@ fn (f mut Fmt) expr(node ast.Expr) { } } f.write(')') + if it.or_block.stmts.len > 0 { + f.writeln(' or {') + f.stmts(it.or_block.stmts) + f.write('}') + } } ast.None { f.write('none') } - ast.OrExpr { + ast.IfGuardExpr { f.write(it.var_name + ' := ') f.expr(it.expr) } - ast.ParExpr{ + ast.ParExpr { f.write('(') f.expr(it.expr) f.write(')') - } + } ast.PostfixExpr { f.expr(it.expr) f.write(it.op.str()) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4269e391c..078b43e93 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -57,7 +57,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { pref: &pref.Preferences{} scope: scope // scope: &ast.Scope{start_pos: 0, parent: 0} - + } p.init_parse_fns() p.read_first_token() @@ -329,7 +329,7 @@ pub fn (p mut Parser) stmt() ast.Stmt { return ast.ExprStmt{ expr: expr // typ: typ - + } } } @@ -621,7 +621,7 @@ pub fn (p mut Parser) name_expr() ast.Expr { p.expr_mod = '' return ast.EnumVal{ enum_name: enum_name // lp.prepend_mod(enum_name) - + val: val pos: p.tok.position() } @@ -887,9 +887,10 @@ fn (p mut Parser) dot_expr(left ast.Expr, left_type table.Type) ast.Expr { if p.tok.kind == .lpar { p.next() args,muts := p.call_args() + mut or_stmts := []ast.Stmt if p.tok.kind == .key_orelse { p.next() - p.parse_block() + or_stmts = p.parse_block() } mcall_expr := ast.MethodCallExpr{ expr: left @@ -897,6 +898,9 @@ fn (p mut Parser) dot_expr(left ast.Expr, left_type table.Type) ast.Expr { args: args muts: muts pos: p.tok.position() + or_block: ast.OrExpr{ + stmts: or_stmts + } } mut node := ast.Expr{} node = mcall_expr @@ -1064,9 +1068,13 @@ fn (p mut Parser) for_statement() ast.Stmt { } // 0 .. 10 // start := p.tok.lit.int() + // TODO use RangeExpr + mut high_expr := ast.Expr{} + mut is_range := false if p.tok.kind == .dotdot { + is_range = true p.check(.dotdot) - p.expr(0) + high_expr,_ = p.expr(0) } // p.table.register_var(table.Var{ // name: var_name @@ -1085,6 +1093,8 @@ fn (p mut Parser) for_statement() ast.Stmt { cond: cond key_var: var_name val_var: val_name + high: high_expr + is_range: is_range } } // `for cond {` @@ -1119,7 +1129,7 @@ fn (p mut Parser) if_expr() ast.Expr { name: var_name typ: typ }) - cond = ast.OrExpr{ + cond = ast.IfGuardExpr{ var_name: var_name expr: expr } @@ -1168,11 +1178,11 @@ fn (p mut Parser) if_expr() ast.Expr { stmts: stmts else_stmts: else_stmts // typ: typ - + pos: pos has_else: has_else // left: left - + } return node } @@ -1588,12 +1598,12 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt { return ast.VarDecl{ name: ident.name // name2: name2 - + expr: expr // p.expr(token.lowest_prec) - + is_mut: info0.is_mut // typ: typ - + pos: p.tok.position() } // return p.var_decl(ident[0], exprs[0]) @@ -1731,7 +1741,7 @@ fn (p mut Parser) match_expr() ast.Expr { blocks: blocks match_exprs: match_exprs // typ: typ - + cond: cond } return node -- 2.30.2