v2: more parser fixes

pull/3759/head
Alexander Medvednikov 2020-02-17 14:15:42 +01:00
parent 457035c7ec
commit 1dd6491a2f
7 changed files with 131 additions and 77 deletions

View File

@ -3207,6 +3207,8 @@ fn todo_remove() {
fn (p mut Parser) check_if_parser_is_stuck(parsing_cycle u64, parsing_start_ticks i64){ 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 { if p.prev_stuck_token_idx == p.token_idx {
// many many cycles have passed with no progress :-( ... // many many cycles have passed with no progress :-( ...
eprintln('Parsing is [probably] stuck. Cycle: ${parsing_cycle:12ld} .') 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{ if time.ticks() > parsing_start_ticks + 30*1000{
p.error(' p.error('
V took more than 30 seconds to compile this file. 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 p.prev_stuck_token_idx = p.token_idx
*/
} }

View File

@ -65,9 +65,10 @@ pub fn new_v(pref &pref.Preferences) &V {
mut vgen_buf := strings.new_builder(1000) mut vgen_buf := strings.new_builder(1000)
vgen_buf.writeln('module vgen\nimport strings') vgen_buf.writeln('module vgen\nimport strings')
compiled_dir:=if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) }
return &V{ 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) table: new_table(pref.obfuscate)
out_name_c: out_name_c out_name_c: out_name_c
cgen: new_cgen(out_name_c) cgen: new_cgen(out_name_c)

View File

@ -15,7 +15,7 @@ CastExpr | EnumVal
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt
// | IncDecStmt k // | IncDecStmt k
// Stand-alone expression in a statement list. // Stand-alone expression in a statement list.
pub struct ExprStmt { pub struct ExprStmt {
@ -406,6 +406,16 @@ pub:
val Expr val Expr
} }
pub struct GotoLabel{
pub:
name string
}
pub struct GotoStmt {
pub:
name string
}
pub struct ArrayInit { pub struct ArrayInit {
pub: pub:
pos token.Position pos token.Position

View File

@ -28,7 +28,6 @@ pub fn new_checker(table &table.Table) Checker {
pub fn (c mut Checker) check(ast_file ast.File) { pub fn (c mut Checker) check(ast_file ast.File) {
c.file_name = ast_file.path c.file_name = ast_file.path
c.scope = &ast_file.scope c.scope = &ast_file.scope
for stmt in ast_file.stmts { for stmt in ast_file.stmts {
c.stmt(stmt) 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) c.error('too many fields', struct_init.pos)
} }
for i, expr in struct_init.exprs { for i, expr in struct_init.exprs {
//struct_field info. // struct_field info.
field_name := struct_init.fields[i] field_name := struct_init.fields[i]
mut field := info.fields[i] mut field := info.fields[i]
mut found_field := false 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 { pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
mut elem_type := table.void_type mut elem_type := table.void_type
// a = [] // a = []
if array_init.exprs.len == 0 { if array_init.exprs.len == 0 {}
}
for i, expr in array_init.exprs { for i, expr in array_init.exprs {
c.expr(expr) c.expr(expr)
typ := 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) 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 is_fixed := false
fixed_size := 1 fixed_size := 1
idx := if is_fixed { 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) }
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_type := table.new_type(idx)
array_init.typ = array_type array_init.typ = array_type
return array_init.typ return array_init.typ
@ -260,10 +250,10 @@ fn (c mut Checker) stmt(node ast.Stmt) {
mut field := it.fields[i] mut field := it.fields[i]
typ := c.expr(expr) typ := c.expr(expr)
mut xconst := c.table.consts[field.name] mut xconst := c.table.consts[field.name]
//if xconst.typ == 0 { // if xconst.typ == 0 {
xconst.typ = typ xconst.typ = typ
c.table.consts[field.name] = xconst c.table.consts[field.name] = xconst
//} // }
field.typ = typ field.typ = typ
it.fields[i] = field it.fields[i] = field
} }
@ -271,10 +261,10 @@ fn (c mut Checker) stmt(node ast.Stmt) {
ast.VarDecl { ast.VarDecl {
typ := c.expr(it.expr) typ := c.expr(it.expr)
// typ_sym := c.table.get_type_symbol(typ) // typ_sym := c.table.get_type_symbol(typ)
//println('var $it.name - $typ - $it.typ - $typ_sym.name') // println('var $it.name - $typ - $it.typ - $typ_sym.name')
//if it.typ == 0 { // if it.typ == 0 {
// it.typ = typ // it.typ = typ
//} // }
it.typ = typ it.typ = typ
} }
ast.ForStmt { ast.ForStmt {
@ -312,7 +302,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
ast.IntegerLiteral { ast.IntegerLiteral {
return table.int_type return table.int_type
} }
ast.FloatLiteral{ ast.FloatLiteral {
return table.f64_type return table.f64_type
} }
ast.PostfixExpr { ast.PostfixExpr {
@ -323,6 +313,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
c.expr(it.left) c.expr(it.left)
} }
*/ */
ast.StringLiteral { ast.StringLiteral {
return table.string_type 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 { 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 { if ident.kind == .variable {
//println('===========================') // println('===========================')
//c.scope.print_vars(0) // c.scope.print_vars(0)
//println('===========================') // println('===========================')
info := ident.info as ast.IdentVar info := ident.info as ast.IdentVar
if info.typ != 0 { if info.typ != 0 {
return info.typ 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 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 found = false
c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos) c.error('not found: $ident.name - POS: $ident.pos.pos', ident.pos)
panic('') panic('')
@ -452,15 +448,16 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
if block.stmts.len > 0 { if block.stmts.len > 0 {
match block.stmts[block.stmts.len - 1] { match block.stmts[block.stmts.len - 1] {
ast.ExprStmt { ast.ExprStmt {
a := 0
// TODO: ask alex about this // TODO: ask alex about this
//typ := c.expr(it.expr) // typ := c.expr(it.expr)
//type_sym := c.table.get_type_symbol(typ) // type_sym := c.table.get_type_symbol(typ)
//p.warn('match expr ret $type_sym.name') // p.warn('match expr ret $type_sym.name')
//node.typ = typ // node.typ = typ
//return typ // return typ
} }
else {} else {}
} }
} }
} }
node.typ = t 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 { if node.stmts.len > 0 {
match node.stmts[node.stmts.len - 1] { match node.stmts[node.stmts.len - 1] {
ast.ExprStmt { ast.ExprStmt {
//type_sym := p.table.get_type_symbol(it.typ) // type_sym := p.table.get_type_symbol(it.typ)
//p.warn('if expr ret $type_sym.name') // p.warn('if expr ret $type_sym.name')
//typ = it.typ // typ = it.typ
//return it.typ // return it.typ
t := c.expr(it.expr) t := c.expr(it.expr)
node.typ = t node.typ = t
return t return t
@ -497,10 +494,10 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type {
// left = // left =
} }
else {} else {}
} }
} }
return typ return typ
//return table.void_type // return table.void_type
} }
pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.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 { pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type {
/* /*
mut typ := left_type mut typ := left_type
left_type_sym := p.table.get_type_symbol(left_type) left_type_sym := p.table.get_type_symbol(left_type)
if left_type_sym.kind == .array { 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 typ = info.elem_type
} }
*/ */
mut typ := c.expr(node.left) mut typ := c.expr(node.left)
mut is_range := false // TODO is_range := node.index is ast.RangeExpr mut is_range := false // TODO is_range := node.index is ast.RangeExpr
match node.index { match node.index {

View File

@ -44,7 +44,8 @@ enum Size {
pub fn gen(files []ast.File, out_name string) { pub fn gen(files []ast.File, out_name string) {
mut g := Gen{ mut g := Gen{
sect_header_name_pos: 0 sect_header_name_pos: 0
buf: [] // buf: []
out_name: out_name out_name: out_name
} }
g.generate_elf_header() g.generate_elf_header()

View File

@ -1 +1,24 @@
module parser 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{}
}

View File

@ -280,15 +280,30 @@ pub fn (p mut Parser) stmt() ast.Stmt {
stmts: stmts stmts: stmts
} }
} }
.key_goto {
p.next()
name := p.check_name()
return ast.GotoStmt{
name: name
}
}
else { else {
// `x := ...` // `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, .comma] {
if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign] { if p.tok.kind == .name && p.peek_tok.kind in [.decl_assign] {
return p.var_decl() 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() 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,typ := p.expr(0)
expr,_ := p.expr(0) expr,_ := p.expr(0)
return ast.ExprStmt{ 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 { pub fn (p mut Parser) assign_expr(left ast.Expr) ast.AssignExpr {
op := p.tok.kind op := p.tok.kind
p.next() p.next()
@ -632,20 +631,33 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
p.check(.rpar) p.check(.rpar)
typ = table.int_type typ = table.int_type
} }
// Map or `{ x | foo:bar, a:10 }` // Map `{"age": 20}` or `{ x | foo:bar, a:10 }`
.lcbr { .lcbr {
p.warn('kek')
p.next() p.next()
p.check_name() if p.tok.kind == .str {
p.check(.pipe) for p.tok.kind != .rcbr && p.tok.kind != .eof {
for { p.check(.str)
p.check_name() p.check(.colon)
p.check(.colon) p.expr(0)
p.expr(0) if p.tok.kind == .comma {
if p.tok.kind == .comma { p.next()
p.check(.comma) }
} }
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) 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()') // println('infix op=$op.str()')
precedence := p.tok.precedence() precedence := p.tok.precedence()
p.next() 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() { if op.is_relational() {
typ = table.bool_type typ = table.bool_type
} }
@ -1105,9 +1119,11 @@ fn (p mut Parser) array_init() ast.Expr {
// mut is_fixed := false // mut is_fixed := false
// mut fixed_size := 0 // mut fixed_size := 0
if p.tok.kind == .rsbr { if p.tok.kind == .rsbr {
// []typ => `[]` and `typ` must be on the same line
line_nr := p.tok.line_nr
p.check(.rsbr) p.check(.rsbr)
// []string // []string
if p.tok.kind == .name { if p.tok.kind == .name && p.tok.line_nr == line_nr {
val_type = p.parse_type() val_type = p.parse_type()
} }
// [] // []
@ -1192,6 +1208,10 @@ fn (p mut Parser) parse_import() ast.Import {
if p.tok.kind == .dot { if p.tok.kind == .dot {
p.next() p.next()
mod_name += '.' + p.check_name() mod_name += '.' + p.check_name()
if p.tok.kind == .dot {
p.next()
mod_name += '.' + p.check_name()
}
} }
mut mod_alias := mod_name mut mod_alias := mod_name
if p.tok.kind == .key_as { if p.tok.kind == .key_as {