mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v2: more parser fixes
This commit is contained in:
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){
|
||||
// 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
|
||||
*/
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
// 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 {
|
||||
// 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,12 +448,13 @@ 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 {}
|
||||
}
|
||||
@ -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
|
||||
@ -500,7 +497,7 @@ pub fn (c mut Checker) if_expr(node mut ast.IfExpr) table.Type {
|
||||
}
|
||||
}
|
||||
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 {
|
||||
|
@ -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()
|
||||
|
@ -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{}
|
||||
}
|
||||
|
@ -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,9 +631,21 @@ 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()
|
||||
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(.pipe)
|
||||
for {
|
||||
@ -648,6 +659,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
p.check(.rcbr)
|
||||
}
|
||||
else {
|
||||
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user