1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

V: fix const bugs and pass const_test.v (#4206)

* fix const bug in v2

* v2: fix const decl

* small comment fix
This commit is contained in:
hazohelet 2020-04-03 02:39:17 +09:00 committed by GitHub
parent 6309e699e5
commit 0e6fe0a4f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 9 deletions

View File

@ -110,6 +110,7 @@ mut:
pub struct ConstDecl { pub struct ConstDecl {
pub: pub:
pos token.Position
fields []Field fields []Field
exprs []Expr exprs []Expr
is_pub bool is_pub bool

View File

@ -150,6 +150,10 @@ pub fn (c mut Checker) infix_expr(infix_expr mut ast.InfixExpr) table.Type {
if right.kind in [.array, .map] && infix_expr.op == .key_in { if right.kind in [.array, .map] && infix_expr.op == .key_in {
return table.bool_type return table.bool_type
} }
// fot type-unresolved consts
if left_type == table.void_type || right_type == table.void_type {
return table.void_type
}
c.error('infix expr: cannot use `$right.name` (right) as `$left.name`', infix_expr.pos) c.error('infix expr: cannot use `$right.name` (right) as `$left.name`', infix_expr.pos)
} }
if infix_expr.op.is_relational() { if infix_expr.op.is_relational() {
@ -346,7 +350,6 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
if arg_typ_sym.kind == .string && typ_sym.has_method('str') { if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
continue continue
} }
// TODO const bug
if typ_sym.kind == .void && arg_typ_sym.kind == .string { if typ_sym.kind == .void && arg_typ_sym.kind == .string {
continue continue
} }
@ -570,17 +573,56 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.stmts(it.stmts) c.stmts(it.stmts)
} }
ast.ConstDecl { ast.ConstDecl {
mut unresolved_num:= 0 // number of type-unresolved consts
mut ordered_exprs := []ast.Expr
mut ordered_fields := []ast.Field
for i, expr in it.exprs { for i, expr in it.exprs {
mut field := it.fields[i] mut field := it.fields[i]
typ := c.expr(expr) typ := c.expr(expr)
// TODO: once consts are fixed update here if typ == table.void_type {
c.table.register_const(table.Var{ unresolved_num++
name: field.name }
typ: typ else { // succeed in resolving type
}) c.table.register_const(table.Var{
field.typ = typ name: field.name
it.fields[i] = field typ: typ
})
field.typ = typ
it.fields[i] = field
ordered_exprs << expr
ordered_fields << field
if unresolved_num == 0 {
continue
}
for j, _expr in it.exprs[0..i]{
mut _field := it.fields[j]
_typ := c.expr(_expr)
if _field.typ == 0 && _typ != table.void_type {
// succeed in resolving type
c.table.register_const(table.Var{
name: _field.name
typ: _typ
})
unresolved_num--
_field.typ = _typ
it.fields[j] = _field
ordered_exprs << _expr
ordered_fields << _field
}
}
}
} }
if unresolved_num != 0 {
c.error("$unresolved_num ill-defined consts are in use", it.pos)
}
for i, field in ordered_fields { // set the fields and exprs as ordered
it.fields[i] = field
it.exprs[i] = ordered_exprs[i]
}
/*
it.exprs = ordered_exprs
it.fields = ordered_fields
*/
} }
ast.ExprStmt { ast.ExprStmt {
c.expr(it.expr) c.expr(it.expr)

View File

@ -1440,6 +1440,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
if is_pub { if is_pub {
p.next() p.next()
} }
pos := p.tok.position()
p.check(.key_const) p.check(.key_const)
p.check(.lpar) p.check(.lpar)
mut fields := []ast.Field mut fields := []ast.Field
@ -1463,6 +1464,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
} }
p.check(.rpar) p.check(.rpar)
return ast.ConstDecl{ return ast.ConstDecl{
pos : pos
fields: fields fields: fields
exprs: exprs exprs: exprs
is_pub: is_pub is_pub: is_pub

View File

@ -1,6 +1,6 @@
pub const ( pub const (
// c = a // TODO
a = b a = b
c = a + b
b = 1 b = 1
d = (e / 2) + 7 d = (e / 2) + 7
e = 9 e = 9