From 1dd6491a2f62ec4bfecae8ed1f130e45c7eda248 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 17 Feb 2020 14:15:42 +0100 Subject: [PATCH] v2: more parser fixes --- vlib/compiler/aparser.v | 5 ++- vlib/compiler/main.v | 3 +- vlib/v/ast/ast.v | 12 +++++- vlib/v/checker/checker.v | 82 +++++++++++++++++++--------------------- vlib/v/gen/x64/gen.v | 3 +- vlib/v/parser/comptime.v | 23 +++++++++++ vlib/v/parser/parser.v | 80 ++++++++++++++++++++++++--------------- 7 files changed, 131 insertions(+), 77 deletions(-) diff --git a/vlib/compiler/aparser.v b/vlib/compiler/aparser.v index bc675591ec..3fa3747b90 100644 --- a/vlib/compiler/aparser.v +++ b/vlib/compiler/aparser.v @@ -3207,6 +3207,8 @@ fn todo_remove() { fn (p mut Parser) check_if_parser_is_stuck(parsing_cycle u64, parsing_start_ticks i64){ + // QTODO + /* if p.prev_stuck_token_idx == p.token_idx { // many many cycles have passed with no progress :-( ... eprintln('Parsing is [probably] stuck. Cycle: ${parsing_cycle:12ld} .') @@ -3218,9 +3220,10 @@ fn (p mut Parser) check_if_parser_is_stuck(parsing_cycle u64, parsing_start_tick if time.ticks() > parsing_start_ticks + 30*1000{ p.error(' V took more than 30 seconds to compile this file. -Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose . +Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose ') } } p.prev_stuck_token_idx = p.token_idx + */ } diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index 33fc5745e8..d866b90dc2 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -65,9 +65,10 @@ pub fn new_v(pref &pref.Preferences) &V { mut vgen_buf := strings.new_builder(1000) vgen_buf.writeln('module vgen\nimport strings') + compiled_dir:=if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) } return &V{ - compiled_dir: if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) } + compiled_dir:compiled_dir// if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) } table: new_table(pref.obfuscate) out_name_c: out_name_c cgen: new_cgen(out_name_c) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 9efbc75b83..c88b76ea15 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -15,7 +15,7 @@ CastExpr | EnumVal pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt // | IncDecStmt k // Stand-alone expression in a statement list. pub struct ExprStmt { @@ -406,6 +406,16 @@ pub: val Expr } +pub struct GotoLabel{ +pub: +name string +} + +pub struct GotoStmt { +pub: +name string +} + pub struct ArrayInit { pub: pos token.Position diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 88f9722bdd..036fdba760 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -28,7 +28,6 @@ pub fn new_checker(table &table.Table) Checker { pub fn (c mut Checker) check(ast_file ast.File) { c.file_name = ast_file.path c.scope = &ast_file.scope - for stmt in ast_file.stmts { c.stmt(stmt) } @@ -56,7 +55,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type c.error('too many fields', struct_init.pos) } for i, expr in struct_init.exprs { - //struct_field info. + // struct_field info. field_name := struct_init.fields[i] mut field := info.fields[i] mut found_field := false @@ -209,12 +208,8 @@ pub fn (c &Checker) assign_stmt(assign_stmt ast.AssignStmt) {} pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { mut elem_type := table.void_type - // a = [] - if array_init.exprs.len == 0 { - - } - + if array_init.exprs.len == 0 {} for i, expr in array_init.exprs { c.expr(expr) typ := c.expr(expr) @@ -228,15 +223,10 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { c.error('expected array element with type `$elem_type_sym.name`', array_init.pos) } } - //idx := if is_fixed { p.table.find_or_register_array_fixed(val_type, fixed_size, 1) } else { p.table.find_or_register_array(val_type, 1) } + // idx := if is_fixed { p.table.find_or_register_array_fixed(val_type, fixed_size, 1) } else { p.table.find_or_register_array(val_type, 1) } is_fixed := false fixed_size := 1 - idx := if is_fixed { - c.table.find_or_register_array_fixed(elem_type, fixed_size, 1) - } - else { - c.table.find_or_register_array(elem_type, 1) - } + idx := if is_fixed { c.table.find_or_register_array_fixed(elem_type, fixed_size, 1) } else { c.table.find_or_register_array(elem_type, 1) } array_type := table.new_type(idx) array_init.typ = array_type return array_init.typ @@ -260,10 +250,10 @@ fn (c mut Checker) stmt(node ast.Stmt) { mut field := it.fields[i] typ := c.expr(expr) mut xconst := c.table.consts[field.name] - //if xconst.typ == 0 { - xconst.typ = typ - c.table.consts[field.name] = xconst - //} + // if xconst.typ == 0 { + xconst.typ = typ + c.table.consts[field.name] = xconst + // } field.typ = typ it.fields[i] = field } @@ -271,10 +261,10 @@ fn (c mut Checker) stmt(node ast.Stmt) { ast.VarDecl { typ := c.expr(it.expr) // typ_sym := c.table.get_type_symbol(typ) - //println('var $it.name - $typ - $it.typ - $typ_sym.name') - //if it.typ == 0 { - // it.typ = typ - //} + // println('var $it.name - $typ - $it.typ - $typ_sym.name') + // if it.typ == 0 { + // it.typ = typ + // } it.typ = typ } ast.ForStmt { @@ -312,7 +302,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { ast.IntegerLiteral { return table.int_type } - ast.FloatLiteral{ + ast.FloatLiteral { return table.f64_type } ast.PostfixExpr { @@ -323,6 +313,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { c.expr(it.left) } */ + ast.StringLiteral { return table.string_type } @@ -371,18 +362,23 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { } pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { - //println('IDENT: $it.name - $it.pos.pos') + // println('IDENT: $it.name - $it.pos.pos') if ident.kind == .variable { - //println('===========================') - //c.scope.print_vars(0) - //println('===========================') + // println('===========================') + // c.scope.print_vars(0) + // println('===========================') info := ident.info as ast.IdentVar if info.typ != 0 { return info.typ } - start_scope := c.scope.innermost(ident.pos.pos) or { c.scope } + start_scope := c.scope.innermost(ident.pos.pos) or { + c.scope + } mut found := true - mut var_scope, mut var := start_scope.find_scope_and_var(ident.name) or { + mut var_scope := &ast.Scope(0) + mut var := ast.VarDecl{} + // mut var_scope, mut var := start_scope.find_scope_and_var(ident.name) or { + var_scope,var = start_scope.find_scope_and_var(ident.name) or { found = false c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos) panic('') @@ -452,15 +448,16 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type { if block.stmts.len > 0 { match block.stmts[block.stmts.len - 1] { ast.ExprStmt { + a := 0 // TODO: ask alex about this - //typ := c.expr(it.expr) - //type_sym := c.table.get_type_symbol(typ) - //p.warn('match expr ret $type_sym.name') - //node.typ = typ - //return typ + // typ := c.expr(it.expr) + // type_sym := c.table.get_type_symbol(typ) + // p.warn('match expr ret $type_sym.name') + // node.typ = typ + // return typ } else {} - } + } } } node.typ = t @@ -486,10 +483,10 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type { if node.stmts.len > 0 { match node.stmts[node.stmts.len - 1] { ast.ExprStmt { - //type_sym := p.table.get_type_symbol(it.typ) - //p.warn('if expr ret $type_sym.name') - //typ = it.typ - //return it.typ + // type_sym := p.table.get_type_symbol(it.typ) + // p.warn('if expr ret $type_sym.name') + // typ = it.typ + // return it.typ t := c.expr(it.expr) node.typ = t return t @@ -497,10 +494,10 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type { // left = } else {} - } + } } return typ - //return table.void_type + // return table.void_type } pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type { @@ -522,7 +519,7 @@ pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type { } pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { -/* + /* mut typ := left_type left_type_sym := p.table.get_type_symbol(left_type) if left_type_sym.kind == .array { @@ -530,7 +527,6 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { typ = info.elem_type } */ - mut typ := c.expr(node.left) mut is_range := false // TODO is_range := node.index is ast.RangeExpr match node.index { diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 811dadc248..6dbd8bf6e7 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -44,7 +44,8 @@ enum Size { pub fn gen(files []ast.File, out_name string) { mut g := Gen{ sect_header_name_pos: 0 - buf: [] + // buf: [] + out_name: out_name } g.generate_elf_header() diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index 234e51e2bb..81b26f28be 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -1 +1,24 @@ module parser + +import ( + v.ast +) + +pub fn (p mut Parser) comp_if() ast.CompIf { + p.next() + p.check(.key_if) + if p.tok.kind == .not { + p.next() + } + p.check_name() + if p.tok.kind == .question { + p.next() + } + p.parse_block() + if p.tok.kind == .dollar && p.peek_tok.kind == .key_else { + p.next() + p.check(.key_else) + p.parse_block() + } + return ast.CompIf{} +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ae398db957..5d2c77f6e8 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -280,15 +280,30 @@ pub fn (p mut Parser) stmt() ast.Stmt { stmts: stmts } } + .key_goto { + p.next() + name := p.check_name() + return ast.GotoStmt{ + name: name + } + } else { // `x := ...` // if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign, .comma] { if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign] { return p.var_decl() } - if p.tok.kind == .name && p.peek_tok.kind in [.comma] { + else if p.tok.kind == .name && p.peek_tok.kind in [.comma] { return p.assign_stmt() } + // `label:` + else if p.tok.kind == .name && p.peek_tok.kind == .colon { + name := p.check_name() + p.check(.colon) + return ast.GotoLabel{ + name: name + } + } // expr,typ := p.expr(0) expr,_ := p.expr(0) return ast.ExprStmt{ @@ -300,22 +315,6 @@ pub fn (p mut Parser) stmt() ast.Stmt { } } -pub fn (p mut Parser) comp_if() ast.CompIf { - p.next() - p.check(.key_if) - if p.tok.kind == .not { - p.next() - } - p.check_name() - p.parse_block() - if p.tok.kind == .dollar && p.peek_tok.kind == .key_else { - p.next() - p.check(.key_else) - p.parse_block() - } - return ast.CompIf{} -} - pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr { op := p.tok.kind p.next() @@ -632,20 +631,33 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { p.check(.rpar) typ = table.int_type } - // Map or `{ x | foo:bar, a:10 }` + // Map `{"age": 20}` or `{ x | foo:bar, a:10 }` .lcbr { + p.warn('kek') p.next() - p.check_name() - p.check(.pipe) - for { - p.check_name() - p.check(.colon) - p.expr(0) - if p.tok.kind == .comma { - p.check(.comma) + if p.tok.kind == .str { + for p.tok.kind != .rcbr && p.tok.kind != .eof { + p.check(.str) + p.check(.colon) + p.expr(0) + if p.tok.kind == .comma { + p.next() + } } - if p.tok.kind == .rcbr { - break + } + else { + p.check_name() + p.check(.pipe) + for { + p.check_name() + p.check(.colon) + p.expr(0) + if p.tok.kind == .comma { + p.check(.comma) + } + if p.tok.kind == .rcbr { + break + } } } p.check(.rcbr) @@ -822,7 +834,9 @@ fn (p mut Parser) infix_expr(left ast.Expr) (ast.Expr,table.Type) { // println('infix op=$op.str()') precedence := p.tok.precedence() p.next() - right,mut typ := p.expr(precedence) + mut typ := table.Type{} + mut right := ast.Expr{} + right,typ = p.expr(precedence) if op.is_relational() { typ = table.bool_type } @@ -1105,9 +1119,11 @@ fn (p mut Parser) array_init() ast.Expr { // mut is_fixed := false // mut fixed_size := 0 if p.tok.kind == .rsbr { + // []typ => `[]` and `typ` must be on the same line + line_nr := p.tok.line_nr p.check(.rsbr) // []string - if p.tok.kind == .name { + if p.tok.kind == .name && p.tok.line_nr == line_nr { val_type = p.parse_type() } // [] @@ -1192,6 +1208,10 @@ fn (p mut Parser) parse_import() ast.Import { if p.tok.kind == .dot { p.next() mod_name += '.' + p.check_name() + if p.tok.kind == .dot { + p.next() + mod_name += '.' + p.check_name() + } } mut mod_alias := mod_name if p.tok.kind == .key_as {