v2: fix `mod.Enum.val` and `x = .val`
parent
59d6a675dd
commit
c51f464446
|
@ -35,6 +35,13 @@ pub fn (c mut Checker) check(ast_file ast.File) {
|
||||||
for stmt in ast_file.stmts {
|
for stmt in ast_file.stmts {
|
||||||
c.stmt(stmt)
|
c.stmt(stmt)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
println('all types:')
|
||||||
|
for t in c.table.types {
|
||||||
|
println(t.name + ' - ' + t.kind.str())
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if c.nr_errors > 0 {
|
if c.nr_errors > 0 {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
@ -105,7 +112,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
|
||||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||||
field_type_sym := c.table.get_type_symbol(field.typ)
|
field_type_sym := c.table.get_type_symbol(field.typ)
|
||||||
if !c.table.check(expr_type, field.typ) {
|
if !c.table.check(expr_type, field.typ) {
|
||||||
c.error('cannot assign $expr_type_sym.name as $field_type_sym.name for field $field.name', struct_init.pos)
|
c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`', struct_init.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +139,7 @@ pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type {
|
||||||
}
|
}
|
||||||
// if !c.table.check(&infix_expr.right_type, &infix_expr.right_type) {
|
// if !c.table.check(&infix_expr.right_type, &infix_expr.right_type) {
|
||||||
// c.error('infix expr: cannot use `$infix_expr.right_type.name` as `$infix_expr.left_type.name`', infix_expr.pos)
|
// c.error('infix expr: cannot use `$infix_expr.right_type.name` as `$infix_expr.left_type.name`', infix_expr.pos)
|
||||||
|
// ltyp := typeof(infix_expr.left)
|
||||||
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() {
|
||||||
|
@ -142,6 +150,9 @@ pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type {
|
||||||
|
|
||||||
fn (c mut Checker) check_assign_expr(assign_expr ast.AssignExpr) {
|
fn (c mut Checker) check_assign_expr(assign_expr ast.AssignExpr) {
|
||||||
left_type := c.expr(assign_expr.left)
|
left_type := c.expr(assign_expr.left)
|
||||||
|
c.expected_type = left_type
|
||||||
|
// t := c.table.get_type_symbol(left_type)
|
||||||
|
// println('setting exp type to $c.expected_type $t.name')
|
||||||
right_type := c.expr(assign_expr.val)
|
right_type := c.expr(assign_expr.val)
|
||||||
if !c.table.check(right_type, left_type) {
|
if !c.table.check(right_type, left_type) {
|
||||||
left_type_sym := c.table.get_type_symbol(left_type)
|
left_type_sym := c.table.get_type_symbol(left_type)
|
||||||
|
@ -272,7 +283,11 @@ pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c &Checker) assign_stmt(assign_stmt ast.AssignStmt) {}
|
/*
|
||||||
|
pub fn (c mut 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
|
||||||
|
@ -305,6 +320,7 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (c mut Checker) stmt(node ast.Stmt) {
|
fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
|
// c.expected_type = table.void_type
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
for stmt in it.stmts {
|
for stmt in it.stmts {
|
||||||
|
@ -314,9 +330,12 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
ast.Return {
|
ast.Return {
|
||||||
c.return_stmt(it)
|
c.return_stmt(it)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
c.assign_stmt(it)
|
c.assign_stmt(it)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
ast.ConstDecl {
|
ast.ConstDecl {
|
||||||
for i, expr in it.exprs {
|
for i, expr in it.exprs {
|
||||||
mut field := it.fields[i]
|
mut field := it.fields[i]
|
||||||
|
@ -653,10 +672,13 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type {
|
||||||
// If a short form is used, `expected_type` needs to be an enum
|
// If a short form is used, `expected_type` needs to be an enum
|
||||||
// with this value.
|
// with this value.
|
||||||
pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
|
pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
|
||||||
typ_idx := if node.enum_name == '' { c.expected_type } else { c.table.find_type_idx(node.enum_name) }
|
// println('checker: enum: $node.enum_name')
|
||||||
|
typ_idx := if node.enum_name == '' { c.expected_type } else { //
|
||||||
|
c.table.find_type_idx(node.enum_name) }
|
||||||
typ := c.table.get_type_symbol(table.Type(typ_idx))
|
typ := c.table.get_type_symbol(table.Type(typ_idx))
|
||||||
// println('checker: enum val $c.expected_type $typ.name')
|
|
||||||
info := typ.info as table.Enum
|
info := typ.info as table.Enum
|
||||||
|
// rintln('checker: x = $info.x enum val $c.expected_type $typ.name')
|
||||||
|
// println(info.vals)
|
||||||
if !(node.val in info.vals) {
|
if !(node.val in info.vals) {
|
||||||
c.error('enum `$typ.name` does not have a value `$node.val`', node.pos)
|
c.error('enum `$typ.name` does not have a value `$node.val`', node.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,9 @@ pub fn (p mut Parser) parse_any_type(is_ptr bool) table.Type {
|
||||||
// prefix with full module
|
// prefix with full module
|
||||||
name = '${p.imports[name]}.$p.tok.lit'
|
name = '${p.imports[name]}.$p.tok.lit'
|
||||||
}
|
}
|
||||||
|
else if p.expr_mod != '' {
|
||||||
|
name = p.expr_mod + '.' + name
|
||||||
|
}
|
||||||
// `Foo` in module `mod` means `mod.Foo`
|
// `Foo` in module `mod` means `mod.Foo`
|
||||||
else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) {
|
else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) {
|
||||||
name = p.mod + '.' + name
|
name = p.mod + '.' + name
|
||||||
|
|
|
@ -42,6 +42,7 @@ mut:
|
||||||
pref &pref.Preferences // Preferences shared from V struct
|
pref &pref.Preferences // Preferences shared from V struct
|
||||||
builtin_mod bool
|
builtin_mod bool
|
||||||
mod string
|
mod string
|
||||||
|
expr_mod string
|
||||||
expected_type table.Type
|
expected_type table.Type
|
||||||
scope &ast.Scope
|
scope &ast.Scope
|
||||||
imports map[string]string
|
imports map[string]string
|
||||||
|
@ -551,6 +552,13 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
mut node := ast.Expr{}
|
mut node := ast.Expr{}
|
||||||
is_c := p.tok.lit == 'C'
|
is_c := p.tok.lit == 'C'
|
||||||
mut mod := ''
|
mut mod := ''
|
||||||
|
// p.warn('resetting')
|
||||||
|
p.expr_mod = ''
|
||||||
|
// `map[string]int` initialization
|
||||||
|
if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr {
|
||||||
|
map_type := p.parse_map_type()
|
||||||
|
return node
|
||||||
|
}
|
||||||
if p.peek_tok.kind == .dot && (is_c || p.known_import(p.tok.lit)) {
|
if p.peek_tok.kind == .dot && (is_c || p.known_import(p.tok.lit)) {
|
||||||
if !is_c {
|
if !is_c {
|
||||||
// prepend the full import
|
// prepend the full import
|
||||||
|
@ -558,11 +566,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
}
|
p.expr_mod = mod
|
||||||
// `map[string]int` initialization
|
|
||||||
if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr {
|
|
||||||
map_type := p.parse_map_type()
|
|
||||||
return node
|
|
||||||
}
|
}
|
||||||
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
|
// p.warn('name expr $p.tok.lit $p.peek_tok.str()')
|
||||||
// fn call or type cast
|
// fn call or type cast
|
||||||
|
@ -586,6 +590,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
typ: to_typ
|
typ: to_typ
|
||||||
expr: expr
|
expr: expr
|
||||||
}
|
}
|
||||||
|
p.expr_mod = ''
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
// fn call
|
// fn call
|
||||||
|
@ -606,13 +611,24 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
return p.struct_init()
|
return p.struct_init()
|
||||||
}
|
}
|
||||||
else if p.peek_tok.kind == .dot && p.tok.lit[0].is_capital() {
|
else if p.peek_tok.kind == .dot && p.tok.lit[0].is_capital() {
|
||||||
enum_name := p.check_name()
|
// `Color.green`
|
||||||
|
mut enum_name := p.check_name()
|
||||||
|
if mod != '' {
|
||||||
|
enum_name = mod + '.' + enum_name
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enum_name = p.prepend_mod(enum_name)
|
||||||
|
}
|
||||||
|
// p.warn('Color.green $enum_name ' + p.prepend_mod(enum_name) + 'mod=$mod')
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
val := p.check_name()
|
val := p.check_name()
|
||||||
// println('enum val $enum_name . $val')
|
// println('enum val $enum_name . $val')
|
||||||
|
p.expr_mod = ''
|
||||||
return ast.EnumVal{
|
return ast.EnumVal{
|
||||||
enum_name: enum_name
|
enum_name: enum_name // lp.prepend_mod(enum_name)
|
||||||
|
|
||||||
val: val
|
val: val
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -620,6 +636,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
||||||
ident = p.parse_ident(is_c)
|
ident = p.parse_ident(is_c)
|
||||||
node = ident
|
node = ident
|
||||||
}
|
}
|
||||||
|
p.expr_mod = ''
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,6 +973,7 @@ fn (p mut Parser) enum_val() ast.EnumVal {
|
||||||
|
|
||||||
return ast.EnumVal{
|
return ast.EnumVal{
|
||||||
val: val
|
val: val
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,6 +1470,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||||
if ret == -1 {
|
if ret == -1 {
|
||||||
p.error('cannot register type `$name`, another type with this name exists')
|
p.error('cannot register type `$name`, another type with this name exists')
|
||||||
}
|
}
|
||||||
|
p.expr_mod = ''
|
||||||
return ast.StructDecl{
|
return ast.StructDecl{
|
||||||
name: name
|
name: name
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
|
@ -1708,7 +1727,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
p.table.register_type_symbol(table.TypeSymbol{
|
p.table.register_type_symbol(table.TypeSymbol{
|
||||||
kind: .enum_
|
kind: .enum_
|
||||||
name: name
|
name: p.prepend_mod(name)
|
||||||
info: table.Enum{
|
info: table.Enum{
|
||||||
vals: vals
|
vals: vals
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ pub fn (t &Table) get_type_symbol(typ Type) &TypeSymbol {
|
||||||
return &t.types[idx]
|
return &t.types[idx]
|
||||||
}
|
}
|
||||||
// this should never happen
|
// this should never happen
|
||||||
panic('get_type_symbol: invalid type $typ - ${idx}. This should neer happen')
|
panic('get_type_symbol: invalid type (typ=$typ idx=${idx}). This should neer happen')
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will override or register builtin type
|
// this will override or register builtin type
|
||||||
|
|
Loading…
Reference in New Issue