v2: more parser fixes
							parent
							
								
									457035c7ec
								
							
						
					
					
						commit
						1dd6491a2f
					
				| 
						 | 
					@ -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
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,12 +448,13 @@ 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 {}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -500,7 +497,7 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	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 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,9 +631,21 @@ 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()
 | 
				
			||||||
 | 
								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()
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
				p.check_name()
 | 
									p.check_name()
 | 
				
			||||||
				p.check(.pipe)
 | 
									p.check(.pipe)
 | 
				
			||||||
				for {
 | 
									for {
 | 
				
			||||||
| 
						 | 
					@ -648,6 +659,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
 | 
				
			||||||
						break
 | 
											break
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			p.check(.rcbr)
 | 
								p.check(.rcbr)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
| 
						 | 
					@ -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 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue