all: use the new types with old syntax (#6922)

pull/6937/head
Daniel Däschle 2020-11-24 13:58:29 +01:00 committed by GitHub
parent 8be9bdacd1
commit aa6303f0b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 303 additions and 300 deletions

View File

@ -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.

View File

@ -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 {}

View File

@ -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 {

View File

@ -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]

View File

@ -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 {

View File

@ -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'

View File

@ -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

View File

@ -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') }
}

View File

@ -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 }

View File

@ -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()

View File

@ -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()

View File

@ -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 {}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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 {

View File

@ -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:

View File

@ -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 {}

View File

@ -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 ''
}

View File

@ -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 }
}
}