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