all: use the new types with old syntax (#6922)
parent
8be9bdacd1
commit
aa6303f0b2
|
@ -7,7 +7,7 @@ import v.token
|
|||
import v.table
|
||||
import v.errors
|
||||
|
||||
pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl | UnionSumTypeDecl
|
||||
pub __type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl | UnionSumTypeDecl
|
||||
|
||||
pub __type Expr = AnonFn | ArrayInit | AsCast | Assoc | AtExpr | BoolLiteral | CTempVar |
|
||||
CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal |
|
||||
|
@ -16,14 +16,14 @@ pub __type Expr = AnonFn | ArrayInit | AsCast | Assoc | AtExpr | BoolLiteral | C
|
|||
RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral |
|
||||
StructInit | Type | TypeOf | UnsafeExpr
|
||||
|
||||
pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl | DeferStmt |
|
||||
EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
|
||||
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlStmt |
|
||||
StructDecl | TypeDecl
|
||||
pub __type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl |
|
||||
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl |
|
||||
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return |
|
||||
SqlStmt | StructDecl | TypeDecl
|
||||
|
||||
// NB: when you add a new Expr or Stmt type with a .pos field, remember to update
|
||||
// the .position() token.Position methods too.
|
||||
pub type ScopeObject = ConstField | GlobalField | Var
|
||||
pub __type ScopeObject = ConstField | GlobalField | Var
|
||||
|
||||
pub struct Type {
|
||||
pub:
|
||||
|
@ -430,7 +430,7 @@ pub mut:
|
|||
share table.ShareType
|
||||
}
|
||||
|
||||
pub type IdentInfo = IdentFn | IdentVar
|
||||
pub __type IdentInfo = IdentFn | IdentVar
|
||||
|
||||
pub enum IdentKind {
|
||||
unresolved
|
||||
|
@ -457,9 +457,9 @@ pub mut:
|
|||
}
|
||||
|
||||
pub fn (i &Ident) var_info() IdentVar {
|
||||
match i.info as info {
|
||||
match union mut i.info {
|
||||
IdentVar {
|
||||
return *info
|
||||
return i.info
|
||||
}
|
||||
else {
|
||||
// return IdentVar{}
|
||||
|
@ -1123,7 +1123,7 @@ pub fn (expr Expr) is_expr() bool {
|
|||
|
||||
// check if stmt can be an expression in C
|
||||
pub fn (stmt Stmt) check_c_expr() ? {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
AssignStmt {
|
||||
return
|
||||
}
|
||||
|
@ -1148,10 +1148,10 @@ pub:
|
|||
}
|
||||
|
||||
pub fn (stmt Stmt) position() token.Position {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
AssertStmt, AssignStmt, Block, BranchStmt, CompFor, ConstDecl, DeferStmt, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, GotoLabel, GotoStmt, Import, Return, StructDecl, GlobalDecl, HashStmt, InterfaceDecl, Module, SqlStmt { return stmt.pos }
|
||||
GoStmt { return stmt.call_expr.position() }
|
||||
TypeDecl { match stmt {
|
||||
TypeDecl { match union stmt {
|
||||
AliasTypeDecl, FnTypeDecl, SumTypeDecl, UnionSumTypeDecl { return stmt.pos }
|
||||
} }
|
||||
// Please, do NOT use else{} here.
|
||||
|
|
|
@ -73,8 +73,8 @@ pub fn (s &Scope) is_known(name string) bool {
|
|||
|
||||
pub fn (s &Scope) find_var(name string) ?&Var {
|
||||
if obj := s.find(name) {
|
||||
match obj {
|
||||
Var { return obj }
|
||||
match union obj {
|
||||
Var { return &obj }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
@ -83,8 +83,8 @@ pub fn (s &Scope) find_var(name string) ?&Var {
|
|||
|
||||
pub fn (s &Scope) find_const(name string) ?&ConstField {
|
||||
if obj := s.find(name) {
|
||||
match obj {
|
||||
ConstField { return obj }
|
||||
match union obj {
|
||||
ConstField { return &obj }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
@ -100,12 +100,13 @@ pub fn (s &Scope) known_var(name string) bool {
|
|||
|
||||
pub fn (mut s Scope) update_var_type(name string, typ table.Type) {
|
||||
s.end_pos = s.end_pos // TODO mut bug
|
||||
match mut s.objects[name] {
|
||||
mut obj := s.objects[name]
|
||||
match union mut obj {
|
||||
Var {
|
||||
if it.typ == typ {
|
||||
if obj.typ == typ {
|
||||
return
|
||||
}
|
||||
it.typ = typ
|
||||
obj.typ = typ
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ pub fn (sc &Scope) show(depth int, max_depth int) string {
|
|||
}
|
||||
out += '$indent# $sc.start_pos - $sc.end_pos\n'
|
||||
for _, obj in sc.objects {
|
||||
match obj {
|
||||
match union obj {
|
||||
ConstField { out += '$indent * const: $obj.name - $obj.typ\n' }
|
||||
Var { out += '$indent * var: $obj.name - $obj.typ\n' }
|
||||
else {}
|
||||
|
|
|
@ -302,7 +302,7 @@ pub fn (node &BranchStmt) str() string {
|
|||
}
|
||||
|
||||
pub fn (node Stmt) str() string {
|
||||
match node {
|
||||
match union node {
|
||||
AssignStmt {
|
||||
mut out := ''
|
||||
for i, left in node.left {
|
||||
|
|
|
@ -9,7 +9,7 @@ pub fn (b &Builder) generic_struct_insts_to_concrete() {
|
|||
if typ.kind == .generic_struct_inst {
|
||||
info := typ.info as table.GenericStructInst
|
||||
parent := b.table.types[info.parent_idx]
|
||||
mut parent_info := *(parent.info as table.Struct)
|
||||
mut parent_info := parent.info as table.Struct
|
||||
mut fields := parent_info.fields.clone()
|
||||
for i, _ in fields {
|
||||
mut field := fields[i]
|
||||
|
|
|
@ -95,7 +95,7 @@ pub fn (mut c Checker) check(ast_file &ast.File) {
|
|||
|
||||
pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
|
||||
for _, obj in sc.objects {
|
||||
match obj {
|
||||
match union obj {
|
||||
ast.Var {
|
||||
if !c.pref.is_repl {
|
||||
if !obj.is_used && obj.name[0] != `_` {
|
||||
|
@ -178,7 +178,7 @@ const (
|
|||
fn (mut c Checker) check_file_in_main(file ast.File) bool {
|
||||
mut has_main_fn := false
|
||||
for stmt in file.stmts {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.ConstDecl {
|
||||
if stmt.is_pub {
|
||||
c.warn('const $no_pub_in_main_warning', stmt.pos)
|
||||
|
@ -278,7 +278,7 @@ fn (mut c Checker) check_valid_pascal_case(name string, identifier string, pos t
|
|||
}
|
||||
|
||||
pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
||||
match node {
|
||||
match union node {
|
||||
ast.AliasTypeDecl {
|
||||
// TODO Replace `c.file.mod.name != 'time'` by `it.language != .v` once available
|
||||
if c.file.mod.name != 'time' && c.file.mod.name != 'builtin' {
|
||||
|
@ -347,89 +347,92 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
|
|||
if decl.language == .v && !c.is_builtin_mod {
|
||||
c.check_valid_pascal_case(decl.name, 'struct name', decl.pos)
|
||||
}
|
||||
struct_sym := c.table.find_type(decl.name) or {
|
||||
mut struct_sym := c.table.find_type(decl.name) or {
|
||||
table.TypeSymbol{}
|
||||
}
|
||||
mut struct_info := struct_sym.info as table.Struct
|
||||
for i, field in decl.fields {
|
||||
if decl.language == .v && !field.is_embed {
|
||||
c.check_valid_snake_case(field.name, 'field name', field.pos)
|
||||
}
|
||||
sym := c.table.get_type_symbol(field.typ)
|
||||
if field.is_embed {
|
||||
if sym.info is table.Struct as sym_info {
|
||||
for embed_field in sym_info.fields {
|
||||
already_exists := struct_info.fields.filter(it.name == embed_field.name).len > 0
|
||||
if !already_exists {
|
||||
struct_info.fields << {
|
||||
embed_field |
|
||||
embed_alias_for: field.name
|
||||
if mut struct_sym.info is table.Struct {
|
||||
for i, field in decl.fields {
|
||||
if decl.language == .v && !field.is_embed {
|
||||
c.check_valid_snake_case(field.name, 'field name', field.pos)
|
||||
}
|
||||
sym := c.table.get_type_symbol(field.typ)
|
||||
if field.is_embed {
|
||||
if mut sym.info is table.Struct {
|
||||
for embed_field in sym.info.fields {
|
||||
already_exists := struct_sym.info.fields.filter(it.name == embed_field.name).len >
|
||||
0
|
||||
if !already_exists {
|
||||
struct_sym.info.fields << {
|
||||
embed_field |
|
||||
embed_alias_for: field.name
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.error('`$sym.name` is not a struct', field.pos)
|
||||
}
|
||||
} else {
|
||||
c.error('`$sym.name` is not a struct', field.pos)
|
||||
}
|
||||
}
|
||||
for j in 0 .. i {
|
||||
if field.name == decl.fields[j].name {
|
||||
c.error('field name `$field.name` duplicate', field.pos)
|
||||
for j in 0 .. i {
|
||||
if field.name == decl.fields[j].name {
|
||||
c.error('field name `$field.name` duplicate', field.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
if sym.kind == .placeholder && decl.language != .c && !sym.name.starts_with('C.') {
|
||||
c.error(util.new_suggestion(sym.source_name, c.table.known_type_names()).say('unknown type `$sym.source_name`'),
|
||||
field.type_pos)
|
||||
}
|
||||
if sym.kind == .array {
|
||||
array_info := sym.array_info()
|
||||
elem_sym := c.table.get_type_symbol(array_info.elem_type)
|
||||
if elem_sym.kind == .placeholder {
|
||||
c.error(util.new_suggestion(elem_sym.source_name, c.table.known_type_names()).say('unknown type `$elem_sym.source_name`'),
|
||||
if sym.kind == .placeholder && decl.language != .c && !sym.name.starts_with('C.') {
|
||||
c.error(util.new_suggestion(sym.source_name, c.table.known_type_names()).say('unknown type `$sym.source_name`'),
|
||||
field.type_pos)
|
||||
}
|
||||
}
|
||||
if sym.kind == .struct_ {
|
||||
info := sym.info as table.Struct
|
||||
if info.is_ref_only && !field.typ.is_ptr() {
|
||||
c.error('`$sym.source_name` type can only be used as a reference: `&$sym.source_name`',
|
||||
field.type_pos)
|
||||
}
|
||||
}
|
||||
if sym.kind == .map {
|
||||
info := sym.map_info()
|
||||
key_sym := c.table.get_type_symbol(info.key_type)
|
||||
value_sym := c.table.get_type_symbol(info.value_type)
|
||||
if key_sym.kind == .placeholder {
|
||||
c.error('unknown type `$key_sym.source_name`', field.type_pos)
|
||||
}
|
||||
if value_sym.kind == .placeholder {
|
||||
c.error('unknown type `$value_sym.source_name`', field.type_pos)
|
||||
}
|
||||
}
|
||||
if field.has_default_expr {
|
||||
c.expected_type = field.typ
|
||||
field_expr_type := c.expr(field.default_expr)
|
||||
c.check_expected(field_expr_type, field.typ) or {
|
||||
c.error('incompatible initializer for field `$field.name`: $err', field.default_expr.position())
|
||||
}
|
||||
// Check for unnecessary inits like ` = 0` and ` = ''`
|
||||
if field.typ.is_ptr() {
|
||||
continue
|
||||
}
|
||||
if field.default_expr is ast.IntegerLiteral {
|
||||
if field.default_expr.val == '0' {
|
||||
c.warn('unnecessary default value of `0`: struct fields are zeroed by default',
|
||||
field.default_expr.pos)
|
||||
if sym.kind == .array {
|
||||
array_info := sym.array_info()
|
||||
elem_sym := c.table.get_type_symbol(array_info.elem_type)
|
||||
if elem_sym.kind == .placeholder {
|
||||
c.error(util.new_suggestion(elem_sym.source_name, c.table.known_type_names()).say('unknown type `$elem_sym.source_name`'),
|
||||
field.type_pos)
|
||||
}
|
||||
} else if field.default_expr is ast.StringLiteral {
|
||||
if field.default_expr.val == '' {
|
||||
c.warn("unnecessary default value of '': struct fields are zeroed by default",
|
||||
field.default_expr.pos)
|
||||
}
|
||||
if sym.kind == .struct_ {
|
||||
info := sym.info as table.Struct
|
||||
if info.is_ref_only && !field.typ.is_ptr() {
|
||||
c.error('`$sym.source_name` type can only be used as a reference: `&$sym.source_name`',
|
||||
field.type_pos)
|
||||
}
|
||||
} else if field.default_expr is ast.BoolLiteral {
|
||||
if field.default_expr.val == false {
|
||||
c.warn('unnecessary default value `false`: struct fields are zeroed by default',
|
||||
field.default_expr.pos)
|
||||
}
|
||||
if sym.kind == .map {
|
||||
info := sym.map_info()
|
||||
key_sym := c.table.get_type_symbol(info.key_type)
|
||||
value_sym := c.table.get_type_symbol(info.value_type)
|
||||
if key_sym.kind == .placeholder {
|
||||
c.error('unknown type `$key_sym.source_name`', field.type_pos)
|
||||
}
|
||||
if value_sym.kind == .placeholder {
|
||||
c.error('unknown type `$value_sym.source_name`', field.type_pos)
|
||||
}
|
||||
}
|
||||
if field.has_default_expr {
|
||||
c.expected_type = field.typ
|
||||
field_expr_type := c.expr(field.default_expr)
|
||||
c.check_expected(field_expr_type, field.typ) or {
|
||||
c.error('incompatible initializer for field `$field.name`: $err',
|
||||
field.default_expr.position())
|
||||
}
|
||||
// Check for unnecessary inits like ` = 0` and ` = ''`
|
||||
if field.typ.is_ptr() {
|
||||
continue
|
||||
}
|
||||
if field.default_expr is ast.IntegerLiteral {
|
||||
if field.default_expr.val == '0' {
|
||||
c.warn('unnecessary default value of `0`: struct fields are zeroed by default',
|
||||
field.default_expr.pos)
|
||||
}
|
||||
} else if field.default_expr is ast.StringLiteral {
|
||||
if field.default_expr.val == '' {
|
||||
c.warn("unnecessary default value of '': struct fields are zeroed by default",
|
||||
field.default_expr.pos)
|
||||
}
|
||||
} else if field.default_expr is ast.BoolLiteral {
|
||||
if field.default_expr.val == false {
|
||||
c.warn('unnecessary default value `false`: struct fields are zeroed by default',
|
||||
field.default_expr.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -938,9 +941,8 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
|||
return '', pos
|
||||
}
|
||||
mut typ_sym := c.table.get_type_symbol(c.unwrap_generic(expr.expr_type))
|
||||
if typ_sym.kind == .alias {
|
||||
alias_info := typ_sym.info as table.Alias
|
||||
typ_sym = c.table.get_type_symbol(alias_info.parent_type)
|
||||
if mut typ_sym.info is table.Alias {
|
||||
typ_sym = c.table.get_type_symbol(typ_sym.info.parent_type)
|
||||
}
|
||||
match typ_sym.kind {
|
||||
.struct_ {
|
||||
|
@ -1148,8 +1150,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
arg_sym := c.table.get_type_symbol(arg_type)
|
||||
// FIXME: match expr failed for now
|
||||
mut ret_type := 0
|
||||
match arg_sym.info as info {
|
||||
table.FnType { ret_type = info.func.return_type }
|
||||
match union mut arg_sym.info {
|
||||
table.FnType { ret_type = arg_sym.info.func.return_type }
|
||||
else { ret_type = arg_type }
|
||||
}
|
||||
call_expr.return_type = c.table.find_or_register_array(ret_type, 1, c.mod)
|
||||
|
@ -1616,7 +1618,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
|
||||
fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos token.Position) bool {
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
inter_sym := c.table.get_type_symbol(inter_typ)
|
||||
mut inter_sym := c.table.get_type_symbol(inter_typ)
|
||||
styp := c.table.type_to_str(typ)
|
||||
for imethod in inter_sym.methods {
|
||||
if method := typ_sym.find_method(imethod.name) {
|
||||
|
@ -1632,9 +1634,10 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok
|
|||
}
|
||||
c.error("`$styp` doesn't implement method `$imethod.name`", pos)
|
||||
}
|
||||
mut inter_info := inter_sym.info as table.Interface
|
||||
if typ !in inter_info.types && typ_sym.kind != .interface_ {
|
||||
inter_info.types << typ
|
||||
if mut inter_sym.info is table.Interface {
|
||||
if typ !in inter_sym.info.types && typ_sym.kind != .interface_ {
|
||||
inter_sym.info.types << typ
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -1686,7 +1689,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex
|
|||
}
|
||||
last_stmt := or_expr.stmts[stmts_len - 1]
|
||||
if ret_type != table.void_type {
|
||||
match last_stmt {
|
||||
match union last_stmt {
|
||||
ast.ExprStmt {
|
||||
last_stmt_typ := c.expr(last_stmt.expr)
|
||||
type_fits := c.check_types(last_stmt_typ, ret_type)
|
||||
|
@ -1721,7 +1724,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex
|
|||
}
|
||||
}
|
||||
} else {
|
||||
match last_stmt {
|
||||
match union last_stmt {
|
||||
ast.ExprStmt {
|
||||
if last_stmt.typ == table.void_type {
|
||||
return
|
||||
|
@ -2141,9 +2144,9 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
ident_var_info.typ = left_type
|
||||
left.info = ident_var_info
|
||||
if left_type != 0 {
|
||||
match mut left.obj as v {
|
||||
ast.Var { v.typ = left_type }
|
||||
ast.GlobalField { v.typ = left_type }
|
||||
match union mut left.obj {
|
||||
ast.Var { left.obj.typ = left_type }
|
||||
ast.GlobalField { left.obj.typ = left_type }
|
||||
else {}
|
||||
}
|
||||
/*
|
||||
|
@ -2444,7 +2447,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
eprintln('checking file: ${c.file.path:-30} | stmt pos: ${stmt_pos.str():-45} | stmt')
|
||||
}
|
||||
// c.expected_type = table.void_type
|
||||
match mut node {
|
||||
match union mut node {
|
||||
ast.AssertStmt {
|
||||
cur_exp_typ := c.expected_type
|
||||
assert_type := c.expr(node.expr)
|
||||
|
@ -3071,9 +3074,9 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
|
|||
c.error('cannot cast `$from_type_sym.source_name` to `$to_type_sym.source_name`',
|
||||
node.pos)
|
||||
}
|
||||
} else if to_type_sym.info is table.Alias as alias_info {
|
||||
if !c.check_types(node.expr_type, alias_info.parent_type) {
|
||||
parent_type_sym := c.table.get_type_symbol(alias_info.parent_type)
|
||||
} else if mut to_type_sym.info is table.Alias {
|
||||
if !c.check_types(node.expr_type, to_type_sym.info.parent_type) {
|
||||
parent_type_sym := c.table.get_type_symbol(to_type_sym.info.parent_type)
|
||||
c.error('cannot convert type `$from_type_sym.source_name` to `$to_type_sym.source_name` (alias to `$parent_type_sym.source_name`)',
|
||||
node.pos)
|
||||
}
|
||||
|
@ -3217,14 +3220,14 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
|||
c.error('`mut` not allowed with `=` (use `:=` to declare a variable)', ident.pos)
|
||||
}
|
||||
start_scope := c.file.scope.innermost(ident.pos.pos)
|
||||
if obj1 := start_scope.find(ident.name) {
|
||||
match mut obj1 as obj {
|
||||
if obj := start_scope.find(ident.name) {
|
||||
match union mut obj {
|
||||
ast.GlobalField {
|
||||
ident.kind = .global
|
||||
ident.info = ast.IdentVar{
|
||||
typ: obj.typ
|
||||
}
|
||||
ident.obj = obj1
|
||||
ident.obj = obj
|
||||
return obj.typ
|
||||
}
|
||||
ast.Var {
|
||||
|
@ -3269,7 +3272,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
|||
if !is_sum_type_cast {
|
||||
obj.typ = typ
|
||||
}
|
||||
ident.obj = obj1
|
||||
ident.obj = obj
|
||||
// unwrap optional (`println(x)`)
|
||||
if is_optional {
|
||||
return typ.clear_flag(.optional)
|
||||
|
@ -3284,8 +3287,8 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
|||
if !name.contains('.') && ident.mod != 'builtin' {
|
||||
name = '${ident.mod}.$ident.name'
|
||||
}
|
||||
if obj1 := c.file.global_scope.find(name) {
|
||||
match mut obj1 as obj {
|
||||
if obj := c.file.global_scope.find(name) {
|
||||
match union mut obj {
|
||||
ast.ConstField {
|
||||
mut typ := obj.typ
|
||||
if typ == 0 {
|
||||
|
@ -3297,7 +3300,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
|||
typ: typ
|
||||
}
|
||||
obj.typ = typ
|
||||
ident.obj = obj1
|
||||
ident.obj = obj
|
||||
return typ
|
||||
}
|
||||
else {}
|
||||
|
@ -3398,7 +3401,8 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
|
|||
}
|
||||
// If the last statement is an expression, return its type
|
||||
if branch.stmts.len > 0 {
|
||||
match mut branch.stmts[branch.stmts.len - 1] as stmt {
|
||||
mut stmt := branch.stmts[branch.stmts.len - 1]
|
||||
match union mut stmt {
|
||||
ast.ExprStmt {
|
||||
ret_type = c.expr(stmt.expr)
|
||||
stmt.typ = ret_type
|
||||
|
@ -3513,8 +3517,8 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
|||
// c.type_implements(expr_type, c.expected_type, expr.position())
|
||||
expr_pos := expr.position()
|
||||
c.type_implements(expr_type, c.expected_type, expr_pos)
|
||||
} else if cond_type_sym.info is table.UnionSumType as info {
|
||||
if expr_type !in info.variants {
|
||||
} else if mut cond_type_sym.info is table.UnionSumType {
|
||||
if expr_type !in cond_type_sym.info.variants {
|
||||
expr_str := c.table.type_to_str(expr_type)
|
||||
expect_str := c.table.type_to_str(c.expected_type)
|
||||
c.error('`$expect_str` has no variant `$expr_str`', expr.position())
|
||||
|
@ -3616,9 +3620,9 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
|||
// by listing all variants or values
|
||||
mut is_exhaustive := true
|
||||
mut unhandled := []string{}
|
||||
match type_sym.info as info {
|
||||
match union mut type_sym.info {
|
||||
table.SumType {
|
||||
for v in info.variants {
|
||||
for v in type_sym.info.variants {
|
||||
v_str := c.table.type_to_str(v)
|
||||
if v_str !in branch_exprs {
|
||||
is_exhaustive = false
|
||||
|
@ -3627,7 +3631,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
|||
}
|
||||
}
|
||||
table.UnionSumType {
|
||||
for v in info.variants {
|
||||
for v in type_sym.info.variants {
|
||||
v_str := c.table.type_to_str(v)
|
||||
if v_str !in branch_exprs {
|
||||
is_exhaustive = false
|
||||
|
@ -3637,7 +3641,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
|||
}
|
||||
//
|
||||
table.Enum {
|
||||
for v in info.vals {
|
||||
for v in type_sym.info.vals {
|
||||
if v !in branch_exprs {
|
||||
is_exhaustive = false
|
||||
unhandled << '`.$v`'
|
||||
|
@ -3690,27 +3694,27 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) table.Type {
|
|||
node.expected_type = c.expected_type
|
||||
for branch in node.branches {
|
||||
c.stmt(branch.stmt)
|
||||
match branch.stmt as stmt {
|
||||
match union branch.stmt {
|
||||
ast.ExprStmt {
|
||||
if branch.is_timeout {
|
||||
if !stmt.typ.is_int() {
|
||||
tsym := c.table.get_type_symbol(stmt.typ)
|
||||
if !branch.stmt.typ.is_int() {
|
||||
tsym := c.table.get_type_symbol(branch.stmt.typ)
|
||||
c.error('invalid type `$tsym.name` for timeout - expected integer type aka `time.Duration`',
|
||||
stmt.pos)
|
||||
branch.stmt.pos)
|
||||
}
|
||||
} else {
|
||||
if stmt.expr is ast.InfixExpr {
|
||||
if stmt.expr.left !is ast.Ident &&
|
||||
stmt.expr.left !is ast.SelectorExpr && stmt.expr.left !is ast.IndexExpr {
|
||||
c.error('channel in `select` key must be predefined', stmt.expr.left.position())
|
||||
if branch.stmt.expr is ast.InfixExpr {
|
||||
if branch.stmt.expr.left !is ast.Ident &&
|
||||
branch.stmt.expr.left !is ast.SelectorExpr && branch.stmt.expr.left !is ast.IndexExpr {
|
||||
c.error('channel in `select` key must be predefined', branch.stmt.expr.left.position())
|
||||
}
|
||||
} else {
|
||||
c.error('invalid expression for `select` key', stmt.expr.position())
|
||||
c.error('invalid expression for `select` key', branch.stmt.expr.position())
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.AssignStmt {
|
||||
expr := stmt.right[0]
|
||||
expr := branch.stmt.right[0]
|
||||
match union expr {
|
||||
ast.PrefixExpr {
|
||||
if expr.right !is ast.Ident &&
|
||||
|
@ -3723,7 +3727,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) table.Type {
|
|||
}
|
||||
}
|
||||
else {
|
||||
c.error('`<-` receive expression expected', stmt.right[0].position())
|
||||
c.error('`<-` receive expression expected', branch.stmt.right[0].position())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3742,8 +3746,8 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type {
|
|||
for i in 0 .. node.lockeds.len {
|
||||
c.ident(mut node.lockeds[i])
|
||||
id := node.lockeds[i]
|
||||
if id.obj is ast.Var as v {
|
||||
if v.typ.share() != .shared_t {
|
||||
if mut id.obj is ast.Var {
|
||||
if id.obj.typ.share() != .shared_t {
|
||||
c.error('`$id.name` must be declared `shared` to be locked', id.pos)
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -122,7 +122,7 @@ pub fn (mut d Doc) stmt(stmt ast.Stmt, filename string) ?DocNode {
|
|||
if node.name.len == 0 && node.comment.len == 0 && node.content.len == 0 {
|
||||
return error('empty stmt')
|
||||
}
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.ConstDecl {
|
||||
node.kind = .const_group
|
||||
node.parent_name = 'Constants'
|
||||
|
|
|
@ -77,7 +77,7 @@ fn (mut d Doc) convert_pos(filename string, pos token.Position) DocPos {
|
|||
}
|
||||
|
||||
pub fn (mut d Doc) stmt_signature(stmt ast.Stmt) string {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.Module {
|
||||
return 'module $stmt.name'
|
||||
}
|
||||
|
@ -93,9 +93,9 @@ pub fn (mut d Doc) stmt_signature(stmt ast.Stmt) string {
|
|||
}
|
||||
|
||||
pub fn (d Doc) stmt_name(stmt ast.Stmt) string {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.FnDecl, ast.StructDecl, ast.EnumDecl, ast.InterfaceDecl { return stmt.name }
|
||||
ast.TypeDecl { match stmt {
|
||||
ast.TypeDecl { match union stmt {
|
||||
ast.SumTypeDecl, ast.FnTypeDecl, ast.AliasTypeDecl, ast.UnionSumTypeDecl { return stmt.name }
|
||||
} }
|
||||
ast.ConstDecl { return '' } // leave it blank
|
||||
|
|
|
@ -8,7 +8,7 @@ import v.checker
|
|||
import v.table
|
||||
import v.pref
|
||||
|
||||
pub type Object = int | string
|
||||
pub __type Object = int | string
|
||||
|
||||
pub struct Eval {
|
||||
mut:
|
||||
|
@ -33,14 +33,14 @@ pub fn (mut e Eval) eval(file ast.File, table &table.Table) string {
|
|||
}
|
||||
|
||||
fn print_object(o Object) {
|
||||
match o {
|
||||
match union o {
|
||||
int { println(o) }
|
||||
else { println('unknown object') }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (o Object) str() string {
|
||||
match o {
|
||||
match union o {
|
||||
int { return o.str() }
|
||||
else { println('unknown object') }
|
||||
}
|
||||
|
|
|
@ -245,7 +245,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
|||
if f.is_debug {
|
||||
eprintln('stmt: ${node.position():-42} | node: ${typeof(node):-20}')
|
||||
}
|
||||
match node {
|
||||
match union node {
|
||||
ast.AssignStmt {
|
||||
f.comments(node.comments, {})
|
||||
for i, left in node.left {
|
||||
|
@ -480,18 +480,18 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
|||
f.writeln('}')
|
||||
}
|
||||
ast.StructDecl {
|
||||
f.struct_decl(it)
|
||||
f.struct_decl(node)
|
||||
}
|
||||
ast.TypeDecl {
|
||||
// already handled in f.imports
|
||||
f.type_decl(it)
|
||||
f.type_decl(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
||||
mut comments := []ast.Comment{}
|
||||
match node {
|
||||
match union node {
|
||||
ast.AliasTypeDecl {
|
||||
if node.is_pub {
|
||||
f.write('pub ')
|
||||
|
@ -962,8 +962,8 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
|||
f.write('> ')
|
||||
}
|
||||
f.single_line_if = true
|
||||
match branch.stmt as stmt {
|
||||
ast.ExprStmt { f.expr(stmt.expr) }
|
||||
match branch.stmt {
|
||||
ast.ExprStmt { f.expr(branch.stmt.expr) }
|
||||
else { f.stmt(branch.stmt) }
|
||||
}
|
||||
f.single_line_if = false
|
||||
|
@ -1691,7 +1691,7 @@ fn (mut f Fmt) write_language_prefix(lang table.Language) {
|
|||
}
|
||||
|
||||
fn stmt_is_single_line(stmt ast.Stmt) bool {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.ExprStmt { return expr_is_single_line(stmt.expr) }
|
||||
ast.Return { return true }
|
||||
ast.AssignStmt { return true }
|
||||
|
|
|
@ -10,9 +10,9 @@ import v.util
|
|||
fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
||||
mut sym := g.table.get_type_symbol(g.unwrap_generic(typ))
|
||||
mut str_fn_name := styp_to_str_fn_name(styp)
|
||||
if sym.info is table.Alias as sym_info {
|
||||
if sym_info.is_import {
|
||||
sym = g.table.get_type_symbol((sym.info as table.Alias).parent_type)
|
||||
if mut sym.info is table.Alias {
|
||||
if sym.info.is_import {
|
||||
sym = g.table.get_type_symbol(sym.info.parent_type)
|
||||
str_fn_name = styp_to_str_fn_name(sym.name.replace('.', '__'))
|
||||
}
|
||||
}
|
||||
|
@ -47,37 +47,37 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
|||
eprintln('> gen_str_for_type_with_styp: |typ: ${typ:5}, ${sym.name:20}|has_str: ${sym_has_str_method:5}|expects_ptr: ${str_method_expects_ptr:5}|nr_args: ${str_nr_args:1}|fn_name: ${str_fn_name:20}')
|
||||
}
|
||||
g.str_types << already_generated_key
|
||||
match sym.info as sym_info {
|
||||
match union mut sym.info {
|
||||
table.Alias {
|
||||
if sym_info.is_import {
|
||||
if sym.info.is_import {
|
||||
g.gen_str_default(sym, styp, str_fn_name)
|
||||
} else {
|
||||
g.gen_str_for_alias(sym_info, styp, str_fn_name)
|
||||
g.gen_str_for_alias(sym.info, styp, str_fn_name)
|
||||
}
|
||||
}
|
||||
table.Array {
|
||||
g.gen_str_for_array(it, styp, str_fn_name)
|
||||
g.gen_str_for_array(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.ArrayFixed {
|
||||
g.gen_str_for_array_fixed(it, styp, str_fn_name)
|
||||
g.gen_str_for_array_fixed(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.Enum {
|
||||
g.gen_str_for_enum(it, styp, str_fn_name)
|
||||
g.gen_str_for_enum(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.Struct {
|
||||
g.gen_str_for_struct(it, styp, str_fn_name)
|
||||
g.gen_str_for_struct(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.Map {
|
||||
g.gen_str_for_map(it, styp, str_fn_name)
|
||||
g.gen_str_for_map(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.MultiReturn {
|
||||
g.gen_str_for_multi_return(it, styp, str_fn_name)
|
||||
g.gen_str_for_multi_return(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.SumType {
|
||||
g.gen_str_for_sum_type(it, styp, str_fn_name)
|
||||
g.gen_str_for_sum_type(sym.info, styp, str_fn_name)
|
||||
}
|
||||
table.UnionSumType {
|
||||
g.gen_str_for_union_sum_type(it, styp, str_fn_name)
|
||||
g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name)
|
||||
}
|
||||
else {
|
||||
verror("could not generate string method $str_fn_name for type \'$styp\'")
|
||||
|
@ -120,9 +120,9 @@ fn (mut g Gen) gen_str_for_alias(info table.Alias, styp string, str_fn_name stri
|
|||
fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name string) {
|
||||
mut typ := info.elem_type
|
||||
mut sym := g.table.get_type_symbol(info.elem_type)
|
||||
if sym.info is table.Alias as alias_info {
|
||||
typ = alias_info.parent_type
|
||||
sym = g.table.get_type_symbol(alias_info.parent_type)
|
||||
if mut sym.info is table.Alias {
|
||||
typ = sym.info.parent_type
|
||||
sym = g.table.get_type_symbol(typ)
|
||||
}
|
||||
field_styp := g.typ(typ)
|
||||
is_elem_ptr := typ.is_ptr()
|
||||
|
@ -188,9 +188,9 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name stri
|
|||
fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_fn_name string) {
|
||||
mut typ := info.elem_type
|
||||
mut sym := g.table.get_type_symbol(info.elem_type)
|
||||
if sym.info is table.Alias as alias_info {
|
||||
typ = alias_info.parent_type
|
||||
sym = g.table.get_type_symbol(alias_info.parent_type)
|
||||
if mut sym.info is table.Alias {
|
||||
typ = sym.info.parent_type
|
||||
sym = g.table.get_type_symbol(typ)
|
||||
}
|
||||
field_styp := g.typ(typ)
|
||||
is_elem_ptr := typ.is_ptr()
|
||||
|
|
|
@ -801,7 +801,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
}
|
||||
// println('cgen.stmt()')
|
||||
// g.writeln('//// stmt start')
|
||||
match node {
|
||||
match union node {
|
||||
ast.AssertStmt {
|
||||
g.write_v_source_line_info(node.pos)
|
||||
g.gen_assert_stmt(node)
|
||||
|
@ -843,7 +843,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
g.comp_for(node)
|
||||
}
|
||||
ast.DeferStmt {
|
||||
mut defer_stmt := *node
|
||||
mut defer_stmt := node
|
||||
defer_stmt.ifdef = g.defer_ifdef
|
||||
g.defer_stmts << defer_stmt
|
||||
}
|
||||
|
@ -914,7 +914,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
}
|
||||
}
|
||||
keep_fn_decl := g.fn_decl
|
||||
g.fn_decl = node
|
||||
g.fn_decl = &node
|
||||
if node.name == 'main.main' {
|
||||
g.has_main = true
|
||||
}
|
||||
|
@ -2098,25 +2098,24 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int
|
|||
return
|
||||
}
|
||||
for _, obj in scope.objects {
|
||||
match obj {
|
||||
match union obj {
|
||||
ast.Var {
|
||||
g.writeln('// var $obj.name pos=$obj.pos.pos')
|
||||
// if var.typ == 0 {
|
||||
// // TODO why 0?
|
||||
// continue
|
||||
// }
|
||||
v := *obj
|
||||
// if v.pos.pos > end_pos {
|
||||
if v.pos.pos > end_pos || (v.pos.pos < start_pos && v.pos.line_nr == line_nr) {
|
||||
if obj.pos.pos > end_pos || (obj.pos.pos < start_pos && obj.pos.line_nr == line_nr) {
|
||||
// Do not free vars that were declared after this scope
|
||||
continue
|
||||
}
|
||||
is_optional := v.typ.has_flag(.optional)
|
||||
is_optional := obj.typ.has_flag(.optional)
|
||||
if is_optional {
|
||||
// TODO: free optionals
|
||||
continue
|
||||
}
|
||||
g.autofree_variable(v)
|
||||
g.autofree_variable(obj)
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -2573,8 +2572,8 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
if i != 0 {
|
||||
sum_type_deref_field += ').'
|
||||
}
|
||||
if cast_sym.info is table.Aggregate as sym_info {
|
||||
sum_type_deref_field += '_${sym_info.types[g.aggregate_type_idx]}'
|
||||
if mut cast_sym.info is table.Aggregate {
|
||||
sum_type_deref_field += '_${cast_sym.info.types[g.aggregate_type_idx]}'
|
||||
} else {
|
||||
sum_type_deref_field += '_$typ'
|
||||
}
|
||||
|
@ -3253,10 +3252,10 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
exception_branch = j
|
||||
timeout_expr = (branch.stmt as ast.ExprStmt).expr
|
||||
} else {
|
||||
match branch.stmt as stmt {
|
||||
match union branch.stmt {
|
||||
ast.ExprStmt {
|
||||
// send expression
|
||||
expr := stmt.expr as ast.InfixExpr
|
||||
expr := branch.stmt.expr as ast.InfixExpr
|
||||
channels << expr.left
|
||||
if expr.right is ast.Ident ||
|
||||
expr.right is ast.IndexExpr || expr.right is ast.SelectorExpr || expr.right is ast.StructInit {
|
||||
|
@ -3275,15 +3274,16 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
is_push << true
|
||||
}
|
||||
ast.AssignStmt {
|
||||
rec_expr := stmt.right[0] as ast.PrefixExpr
|
||||
rec_expr := branch.stmt.right[0] as ast.PrefixExpr
|
||||
channels << rec_expr.right
|
||||
is_push << false
|
||||
// create tmp unless the object with *exactly* the type we need exists already
|
||||
if stmt.op == .decl_assign || stmt.right_types[0] != stmt.left_types[0] {
|
||||
if branch.stmt.op == .decl_assign ||
|
||||
branch.stmt.right_types[0] != branch.stmt.left_types[0] {
|
||||
tmp_obj := g.new_tmp_var()
|
||||
tmp_objs << tmp_obj
|
||||
el_stype := g.typ(stmt.right_types[0])
|
||||
elem_types << if stmt.op == .decl_assign {
|
||||
el_stype := g.typ(branch.stmt.right_types[0])
|
||||
elem_types << if branch.stmt.op == .decl_assign {
|
||||
el_stype + ' '
|
||||
} else {
|
||||
''
|
||||
|
@ -3293,7 +3293,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
tmp_objs << ''
|
||||
elem_types << ''
|
||||
}
|
||||
objs << stmt.left[0]
|
||||
objs << branch.stmt.left[0]
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -3418,8 +3418,8 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
if i == 0 {
|
||||
g.write(name)
|
||||
}
|
||||
if cast_sym.info is table.Aggregate as sym_info {
|
||||
g.write('._${sym_info.types[g.aggregate_type_idx]}')
|
||||
if mut cast_sym.info is table.Aggregate {
|
||||
g.write('._${cast_sym.info.types[g.aggregate_type_idx]}')
|
||||
} else {
|
||||
g.write('._$typ')
|
||||
}
|
||||
|
@ -3447,16 +3447,17 @@ fn (mut g Gen) should_write_asterisk_due_to_match_sumtype(expr ast.Expr) bool {
|
|||
fn (mut g Gen) match_sumtype_has_no_struct_and_contains(node ast.Ident) bool {
|
||||
for i, expr in g.match_sumtype_exprs {
|
||||
if expr is ast.Ident && node.name == (expr as ast.Ident).name {
|
||||
match g.match_sumtype_syms[i].info as sumtype {
|
||||
info := g.match_sumtype_syms[i].info
|
||||
match union info {
|
||||
table.SumType {
|
||||
for typ in sumtype.variants {
|
||||
for typ in info.variants {
|
||||
if g.table.get_type_symbol(typ).kind == .struct_ {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
table.UnionSumType {
|
||||
for typ in sumtype.variants {
|
||||
for typ in info.variants {
|
||||
if g.table.get_type_symbol(typ).kind == .struct_ {
|
||||
return false
|
||||
}
|
||||
|
@ -3500,9 +3501,11 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
|||
// easier to use a temp var, than do C tricks with commas, introduce special vars etc
|
||||
// (as it used to be done).
|
||||
// Always use this in -autofree, since ?: can have tmp expressions that have to be freed.
|
||||
first_branch := node.branches[0]
|
||||
needs_tmp_var := node.is_expr &&
|
||||
(g.pref.autofree || (g.pref.experimental &&
|
||||
(node.branches[0].stmts.len > 1 || node.branches[0].stmts[0] is ast.IfExpr)))
|
||||
(first_branch.stmts.len > 1 || (first_branch.stmts[0] is ast.ExprStmt &&
|
||||
(first_branch.stmts[0] as ast.ExprStmt).expr is ast.IfExpr))))
|
||||
/*
|
||||
needs_tmp_var := node.is_expr &&
|
||||
(g.pref.autofree || g.pref.experimental) &&
|
||||
|
@ -4224,8 +4227,8 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
mut initialized := false
|
||||
for i, field in struct_init.fields {
|
||||
inited_fields[field.name] = i
|
||||
if sym.info is table.Struct as struct_info {
|
||||
equal_fields := struct_info.fields.filter(it.name == field.name)
|
||||
if mut sym.info is table.Struct {
|
||||
equal_fields := sym.info.fields.filter(it.name == field.name)
|
||||
if equal_fields.len == 0 {
|
||||
continue
|
||||
}
|
||||
|
@ -4276,8 +4279,8 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
// g.zero_struct_fields(info, inited_fields)
|
||||
// nr_fields = info.fields.len
|
||||
for field in info.fields {
|
||||
if sym.info is table.Struct as struct_info {
|
||||
equal_fields := struct_info.fields.filter(it.name == field.name)
|
||||
if mut sym.info is table.Struct {
|
||||
equal_fields := sym.info.fields.filter(it.name == field.name)
|
||||
if equal_fields.len == 0 {
|
||||
continue
|
||||
}
|
||||
|
@ -4590,9 +4593,9 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
|
|||
}
|
||||
// sym := g.table.get_type_symbol(typ)
|
||||
mut name := util.no_dots(typ.name)
|
||||
match typ.info as info {
|
||||
match union mut typ.info {
|
||||
table.Struct {
|
||||
if info.generic_types.len > 0 {
|
||||
if typ.info.generic_types.len > 0 {
|
||||
continue
|
||||
}
|
||||
// TODO: yuck
|
||||
|
@ -4602,13 +4605,13 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
|
|||
}
|
||||
// TODO avoid buffer manip
|
||||
start_pos := g.type_definitions.len
|
||||
if info.is_union {
|
||||
if typ.info.is_union {
|
||||
g.type_definitions.writeln('union $name {')
|
||||
} else {
|
||||
g.type_definitions.writeln('struct $name {')
|
||||
}
|
||||
if info.fields.len > 0 {
|
||||
for field in info.fields.filter(it.embed_alias_for == '') {
|
||||
if typ.info.fields.len > 0 {
|
||||
for field in typ.info.fields.filter(it.embed_alias_for == '') {
|
||||
// Some of these structs may want to contain
|
||||
// optionals that may not be defined at this point
|
||||
// if this is the case then we are going to
|
||||
|
@ -4642,7 +4645,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
|
|||
table.SumType {
|
||||
g.type_definitions.writeln('')
|
||||
g.type_definitions.writeln('// Sum type $name = ')
|
||||
for sv in it.variants {
|
||||
for sv in typ.info.variants {
|
||||
g.type_definitions.writeln('// | ${sv:4d} = ${g.typ(sv):-20s}')
|
||||
}
|
||||
g.type_definitions.writeln('typedef struct {')
|
||||
|
@ -4655,12 +4658,12 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
|
|||
g.typedefs.writeln('typedef struct $name $name;')
|
||||
g.type_definitions.writeln('')
|
||||
g.type_definitions.writeln('// Union sum type $name = ')
|
||||
for variant in it.variants {
|
||||
for variant in typ.info.variants {
|
||||
g.type_definitions.writeln('// | ${variant:4d} = ${g.typ(variant.idx()):-20s}')
|
||||
}
|
||||
g.type_definitions.writeln('struct $name {')
|
||||
g.type_definitions.writeln(' union {')
|
||||
for variant in it.variants {
|
||||
for variant in typ.info.variants {
|
||||
g.type_definitions.writeln(' ${g.typ(variant.to_ptr())} _$variant.idx();')
|
||||
}
|
||||
g.type_definitions.writeln(' };')
|
||||
|
@ -4702,19 +4705,18 @@ fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol {
|
|||
}
|
||||
// create list of deps
|
||||
mut field_deps := []string{}
|
||||
match t.info {
|
||||
match union mut t.info {
|
||||
table.ArrayFixed {
|
||||
dep := g.table.get_type_symbol(it.elem_type).name
|
||||
dep := g.table.get_type_symbol(t.info.elem_type).name
|
||||
if dep in type_names {
|
||||
field_deps << dep
|
||||
}
|
||||
}
|
||||
table.Struct {
|
||||
info := t.info as table.Struct
|
||||
// if info.is_interface {
|
||||
// continue
|
||||
// }
|
||||
for field in info.fields {
|
||||
for field in t.info.fields {
|
||||
dep := g.table.get_type_symbol(field.typ).name
|
||||
// skip if not in types list or already in deps
|
||||
if dep !in type_names || dep in field_deps || field.typ.is_ptr() {
|
||||
|
@ -4747,11 +4749,11 @@ fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol {
|
|||
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
|
||||
mut typ := etype
|
||||
mut sym := g.table.get_type_symbol(typ)
|
||||
if sym.info is table.Alias as alias_info {
|
||||
parent_sym := g.table.get_type_symbol(alias_info.parent_type)
|
||||
if mut sym.info is table.Alias {
|
||||
parent_sym := g.table.get_type_symbol(sym.info.parent_type)
|
||||
if parent_sym.has_method('str') {
|
||||
typ = sym.info.parent_type
|
||||
sym = parent_sym
|
||||
typ = alias_info.parent_type
|
||||
}
|
||||
}
|
||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||
|
|
|
@ -549,9 +549,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
g.checker_bug('print arg.typ is 0', node.pos)
|
||||
}
|
||||
mut sym := g.table.get_type_symbol(typ)
|
||||
if sym.info is table.Alias as alias_info {
|
||||
typ = alias_info.parent_type
|
||||
sym = g.table.get_type_symbol(alias_info.parent_type)
|
||||
if mut sym.info is table.Alias {
|
||||
typ = sym.info.parent_type
|
||||
sym = g.table.get_type_symbol(typ)
|
||||
}
|
||||
// check if alias parent also not a string
|
||||
if typ != table.string_type {
|
||||
|
@ -685,7 +685,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
|
|||
// instead of `string t = ...`, and we need to mark this variable as unused,
|
||||
// so that it's freed after the call. (Used tmp arg vars are not freed to avoid double frees).
|
||||
if x := scope.find(t) {
|
||||
match mut x {
|
||||
match union mut x {
|
||||
ast.Var { x.is_used = false }
|
||||
else {}
|
||||
}
|
||||
|
@ -740,27 +740,26 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
|
|||
// g.write('/* postgen */')
|
||||
scope := g.file.scope.innermost(node_pos)
|
||||
for _, obj in scope.objects {
|
||||
match mut obj {
|
||||
match union mut obj {
|
||||
ast.Var {
|
||||
// if var.typ == 0 {
|
||||
// // TODO why 0?
|
||||
// continue
|
||||
// }
|
||||
v := *obj
|
||||
is_optional := v.typ.has_flag(.optional)
|
||||
is_optional := obj.typ.has_flag(.optional)
|
||||
if is_optional {
|
||||
// TODO: free optionals
|
||||
continue
|
||||
}
|
||||
if !v.is_autofree_tmp {
|
||||
if !obj.is_autofree_tmp {
|
||||
continue
|
||||
}
|
||||
if v.is_used {
|
||||
if obj.is_used {
|
||||
// this means this tmp expr var has already been freed
|
||||
continue
|
||||
}
|
||||
obj.is_used = true
|
||||
g.autofree_variable(v)
|
||||
g.autofree_variable(obj)
|
||||
// g.nr_vars_to_free--
|
||||
}
|
||||
else {}
|
||||
|
|
|
@ -164,7 +164,7 @@ pub fn (mut g JsGen) push_pub_var(s string) {
|
|||
|
||||
pub fn (mut g JsGen) find_class_methods(stmts []ast.Stmt) {
|
||||
for stmt in stmts {
|
||||
match stmt {
|
||||
match union stmt {
|
||||
ast.FnDecl {
|
||||
if stmt.is_method {
|
||||
// Found struct method, store it to be generated along with the class.
|
||||
|
@ -437,7 +437,7 @@ fn (mut g JsGen) stmts(stmts []ast.Stmt) {
|
|||
|
||||
fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||
g.stmt_start_pos = g.out.len
|
||||
match node {
|
||||
match union node {
|
||||
ast.AssertStmt {
|
||||
g.gen_assert_stmt(node)
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
|||
g.gen_const_decl(node)
|
||||
}
|
||||
ast.DeferStmt {
|
||||
g.defer_stmts << *node
|
||||
g.defer_stmts << node
|
||||
}
|
||||
ast.EnumDecl {
|
||||
g.gen_enum_decl(node)
|
||||
|
@ -466,7 +466,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
|||
g.gen_expr_stmt(node)
|
||||
}
|
||||
ast.FnDecl {
|
||||
g.fn_decl = node
|
||||
g.fn_decl = &node
|
||||
g.gen_fn_decl(node)
|
||||
}
|
||||
ast.ForCStmt {
|
||||
|
|
|
@ -603,7 +603,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
|||
}
|
||||
|
||||
fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
match node {
|
||||
match union node {
|
||||
ast.AssignStmt {
|
||||
g.assign_stmt(node)
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ fn (mut p Parser) vweb() ast.ComptimeCall {
|
|||
if obj is ast.Var {
|
||||
mut v := obj
|
||||
v.pos = stmt.body_pos
|
||||
tmpl_scope.register(v.name, *v)
|
||||
tmpl_scope.register(v.name, v)
|
||||
// set the controller action var to used
|
||||
// if its unused in the template it will warn
|
||||
v.is_used = true
|
||||
|
|
|
@ -443,12 +443,12 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
|
|||
}
|
||||
p.inside_match = false
|
||||
p.inside_select = false
|
||||
match stmt {
|
||||
match union mut stmt {
|
||||
ast.ExprStmt {
|
||||
if !stmt.is_expr {
|
||||
p.error_with_pos('select: invalid expression', stmt.pos)
|
||||
} else {
|
||||
match union stmt.expr {
|
||||
match union mut stmt.expr {
|
||||
ast.InfixExpr {
|
||||
if stmt.expr.op != .arrow {
|
||||
p.error_with_pos('select key: `<-` operator expected',
|
||||
|
|
|
@ -608,18 +608,18 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||
p.next()
|
||||
if p.tok.kind == .key_for {
|
||||
mut stmt := p.stmt(is_top_level)
|
||||
match mut stmt {
|
||||
match union mut stmt {
|
||||
ast.ForStmt {
|
||||
stmt.label = name
|
||||
return *stmt
|
||||
return stmt
|
||||
}
|
||||
ast.ForInStmt {
|
||||
stmt.label = name
|
||||
return *stmt
|
||||
return stmt
|
||||
}
|
||||
ast.ForCStmt {
|
||||
stmt.label = name
|
||||
return *stmt
|
||||
return stmt
|
||||
}
|
||||
else {
|
||||
assert false
|
||||
|
@ -2139,7 +2139,7 @@ fn (mut p Parser) rewind_scanner_to_current_token_in_new_mode() {
|
|||
|
||||
pub fn (mut p Parser) mark_var_as_used(varname string) bool {
|
||||
if obj := p.scope.find(varname) {
|
||||
match mut obj {
|
||||
match union mut obj {
|
||||
ast.Var {
|
||||
obj.is_used = true
|
||||
return true
|
||||
|
|
|
@ -263,12 +263,12 @@ pub fn (t &Table) struct_find_field(s &TypeSymbol, name string) ?Field {
|
|||
// println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx')
|
||||
mut ts := s
|
||||
for {
|
||||
if ts.info is Struct as struct_info {
|
||||
if field := struct_info.find_field(name) {
|
||||
if mut ts.info is Struct {
|
||||
if field := ts.info.find_field(name) {
|
||||
return field
|
||||
}
|
||||
} else if ts.info is Aggregate as agg_info {
|
||||
if field := agg_info.find_field(name) {
|
||||
} else if mut ts.info is Aggregate {
|
||||
if field := ts.info.find_field(name) {
|
||||
return field
|
||||
}
|
||||
field := t.register_aggregate_field(mut ts, name) or {
|
||||
|
|
|
@ -15,8 +15,8 @@ import strings
|
|||
|
||||
pub type Type = int
|
||||
|
||||
pub type TypeInfo = Aggregate | Alias | Array | ArrayFixed | Chan | Enum | FnType | GenericStructInst |
|
||||
Interface | Map | MultiReturn | Struct | SumType | UnionSumType
|
||||
pub __type TypeInfo = Aggregate | Alias | Array | ArrayFixed | Chan | Enum | FnType |
|
||||
GenericStructInst | Interface | Map | MultiReturn | Struct | SumType | UnionSumType
|
||||
|
||||
pub enum Language {
|
||||
v
|
||||
|
@ -421,56 +421,56 @@ pub fn (t &TypeSymbol) str() string {
|
|||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) enum_info() Enum {
|
||||
match t.info {
|
||||
Enum { return *it }
|
||||
match union mut t.info {
|
||||
Enum { return t.info }
|
||||
else { panic('TypeSymbol.enum_info(): no enum info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) mr_info() MultiReturn {
|
||||
match t.info {
|
||||
MultiReturn { return *it }
|
||||
match union mut t.info {
|
||||
MultiReturn { return t.info }
|
||||
else { panic('TypeSymbol.mr_info(): no multi return info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_info() Array {
|
||||
match t.info {
|
||||
Array { return *it }
|
||||
match union mut t.info {
|
||||
Array { return t.info }
|
||||
else { panic('TypeSymbol.array_info(): no array info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
|
||||
match t.info {
|
||||
ArrayFixed { return *it }
|
||||
match union mut t.info {
|
||||
ArrayFixed { return t.info }
|
||||
else { panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) chan_info() Chan {
|
||||
match t.info {
|
||||
Chan { return *it }
|
||||
match union mut t.info {
|
||||
Chan { return t.info }
|
||||
else { panic('TypeSymbol.chan_info(): no chan info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) map_info() Map {
|
||||
match t.info {
|
||||
Map { return *it }
|
||||
match union mut t.info {
|
||||
Map { return t.info }
|
||||
else { panic('TypeSymbol.map_info(): no map info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (t &TypeSymbol) struct_info() Struct {
|
||||
match t.info {
|
||||
Struct { return *it }
|
||||
match union mut t.info {
|
||||
Struct { return t.info }
|
||||
else { panic('TypeSymbol.struct_info(): no struct info for type: $t.name') }
|
||||
}
|
||||
}
|
||||
|
@ -790,7 +790,7 @@ pub:
|
|||
// NB: FExpr here is a actually an ast.Expr .
|
||||
// It should always be used by casting to ast.Expr, using ast.fe2ex()/ast.ex2fe()
|
||||
// That hack is needed to break an import cycle between v.ast and v.table .
|
||||
pub type FExpr = byteptr | voidptr
|
||||
pub __type FExpr = byteptr | voidptr
|
||||
|
||||
pub struct Field {
|
||||
pub:
|
||||
|
|
|
@ -11,7 +11,7 @@ import v.util
|
|||
import v.pref
|
||||
|
||||
// `Any` is a sum type that lists the possible types to be decoded and used.
|
||||
pub type Any = string | int | i64 | f32 | f64 | any_int | any_float | bool | Null | []Any | map[string]Any
|
||||
pub __type Any = string | int | i64 | f32 | f64 | any_int | any_float | bool | Null | []Any | map[string]Any
|
||||
// `Null` struct is a simple representation of the `null` value in JSON.
|
||||
pub struct Null {}
|
||||
|
||||
|
|
|
@ -51,21 +51,20 @@ pub fn (flds []Any) str() string {
|
|||
|
||||
// String representation of the `Any` type.
|
||||
pub fn (f Any) str() string {
|
||||
match f {
|
||||
string { return *f }
|
||||
int { return (*f).str() }
|
||||
i64 { return (*f).str() }
|
||||
f32 { return (*f).str() }
|
||||
f64 { return (*f).str() }
|
||||
any_int { return (*f).str() }
|
||||
any_float { return (*f).str() }
|
||||
bool { return (*f).str() }
|
||||
map[string]Any { return (*f).str() }
|
||||
match union f {
|
||||
string { return f }
|
||||
int { return f.str() }
|
||||
i64 { return f.str() }
|
||||
f32 { return f.str() }
|
||||
f64 { return f.str() }
|
||||
any_int { return f.str() }
|
||||
any_float { return f.str() }
|
||||
bool { return f.str() }
|
||||
map[string]Any { return f.str() }
|
||||
Null { return 'null' }
|
||||
else {
|
||||
if f is []Any {
|
||||
arr := f
|
||||
return (*arr).str()
|
||||
return f.str()
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
|
|
@ -66,11 +66,10 @@ pub fn null() Null {
|
|||
// Use `Any` as a map.
|
||||
pub fn (f Any) as_map() map[string]Any {
|
||||
if f is map[string]Any {
|
||||
return *f
|
||||
return f
|
||||
} else if f is []Any {
|
||||
mut mp := map[string]Any
|
||||
arr := f
|
||||
for i, fi in arr {
|
||||
for i, fi in f {
|
||||
mp['$i'] = fi
|
||||
}
|
||||
return mp
|
||||
|
@ -80,9 +79,9 @@ pub fn (f Any) as_map() map[string]Any {
|
|||
|
||||
// Use `Any` as an integer.
|
||||
pub fn (f Any) int() int {
|
||||
match f {
|
||||
int { return *f }
|
||||
i64 { return int(*f) }
|
||||
match union f {
|
||||
int { return f }
|
||||
i64 { return int(f) }
|
||||
f64 { return f.str().int() }
|
||||
f32 { return f.str().int() }
|
||||
bool { return int(f) }
|
||||
|
@ -92,9 +91,9 @@ pub fn (f Any) int() int {
|
|||
|
||||
// Use `Any` as a 64-bit integer.
|
||||
pub fn (f Any) i64() i64 {
|
||||
match f {
|
||||
int { return *f }
|
||||
i64 { return int(*f) }
|
||||
match union f {
|
||||
int { return f }
|
||||
i64 { return int(f) }
|
||||
f64 { return f.str().i64() }
|
||||
f32 { return f.str().i64() }
|
||||
bool { return int(f) }
|
||||
|
@ -104,33 +103,32 @@ pub fn (f Any) i64() i64 {
|
|||
|
||||
// Use `Any` as a 32-bit float.
|
||||
pub fn (f Any) f32() f32 {
|
||||
match f {
|
||||
int { return *f }
|
||||
i64 { return (*f).str().f32() }
|
||||
f64 { return (*f).str().f32() }
|
||||
f32 { return *f }
|
||||
match union f {
|
||||
int { return f }
|
||||
i64 { return f.str().f32() }
|
||||
f64 { return f.str().f32() }
|
||||
f32 { return f }
|
||||
else { return 0.0 }
|
||||
}
|
||||
}
|
||||
|
||||
// Use `Any` as a float.
|
||||
pub fn (f Any) f64() f64 {
|
||||
match f {
|
||||
int { return *f }
|
||||
i64 { return *f }
|
||||
f64 { return *f }
|
||||
f32 { return (*f).str().f64() }
|
||||
match union f {
|
||||
int { return f }
|
||||
i64 { return f }
|
||||
f64 { return f }
|
||||
f32 { return f.str().f64() }
|
||||
else { return 0.0 }
|
||||
}
|
||||
}
|
||||
// Use `Any` as an array.
|
||||
pub fn (f Any) arr() []Any {
|
||||
if f is []Any {
|
||||
return *f
|
||||
return f
|
||||
} else if f is map[string]Any {
|
||||
mut arr := []Any{}
|
||||
mp := *f
|
||||
for _, v in mp {
|
||||
for _, v in f {
|
||||
arr << v
|
||||
}
|
||||
return arr
|
||||
|
@ -140,9 +138,9 @@ pub fn (f Any) arr() []Any {
|
|||
|
||||
// Use `Any` as a bool
|
||||
pub fn (f Any) bool() bool {
|
||||
match f {
|
||||
bool { return *f }
|
||||
string { return (*f).bool() }
|
||||
match union f {
|
||||
bool { return f }
|
||||
string { return f.bool() }
|
||||
else { return false }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue