all: refactor UnionSumType to SumType (#6944)

pull/6946/head
Daniel Däschle 2020-11-25 12:09:40 +01:00 committed by GitHub
parent 96b73acad7
commit 7d6f97259f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 256 additions and 265 deletions

View File

@ -7,23 +7,23 @@ import v.token
import v.table import v.table
import v.errors import v.errors
pub __type TypeDecl = AliasTypeDecl | FnTypeDecl | UnionSumTypeDecl pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
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 |
FloatLiteral | Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | FloatLiteral | Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral |
Likely | LockExpr | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | Likely | LockExpr | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr |
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 | pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl | DeferStmt |
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlStmt |
SqlStmt | StructDecl | TypeDecl 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,7 +457,7 @@ pub mut:
} }
pub fn (i &Ident) var_info() IdentVar { pub fn (i &Ident) var_info() IdentVar {
match union mut i.info { match mut i.info {
IdentVar { IdentVar {
return i.info return i.info
} }
@ -558,18 +558,17 @@ pub mut:
pub struct MatchExpr { pub struct MatchExpr {
pub: pub:
tok_kind token.Kind tok_kind token.Kind
cond Expr cond Expr
branches []MatchBranch branches []MatchBranch
pos token.Position pos token.Position
is_mut bool // `match mut ast_node {` is_mut bool // `match mut ast_node {`
is_union_match bool // TODO: remove
pub mut: pub mut:
is_expr bool // returns a value is_expr bool // returns a value
return_type table.Type return_type table.Type
cond_type table.Type // type of `x` in `match x {` cond_type table.Type // type of `x` in `match x {`
expected_type table.Type // for debugging only expected_type table.Type // for debugging only
is_sum_type bool is_sum_type bool
} }
pub struct MatchBranch { pub struct MatchBranch {
@ -747,7 +746,7 @@ pub:
} }
// New implementation of sum types // New implementation of sum types
pub struct UnionSumTypeDecl { pub struct SumTypeDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
@ -1047,7 +1046,7 @@ pub mut:
[inline] [inline]
pub fn (expr Expr) is_blank_ident() bool { pub fn (expr Expr) is_blank_ident() bool {
match union expr { match expr {
Ident { return expr.kind == .blank_ident } Ident { return expr.kind == .blank_ident }
else { return false } else { return false }
} }
@ -1055,7 +1054,7 @@ pub fn (expr Expr) is_blank_ident() bool {
pub fn (expr Expr) position() token.Position { pub fn (expr Expr) position() token.Position {
// all uncommented have to be implemented // all uncommented have to be implemented
match union expr { match expr {
// KEKW2 // KEKW2
AnonFn { AnonFn {
return expr.decl.pos return expr.decl.pos
@ -1091,7 +1090,7 @@ pub fn (expr Expr) position() token.Position {
} }
pub fn (expr Expr) is_lvalue() bool { pub fn (expr Expr) is_lvalue() bool {
match union expr { match expr {
Ident { return true } Ident { return true }
CTempVar { return true } CTempVar { return true }
IndexExpr { return expr.left.is_lvalue() } IndexExpr { return expr.left.is_lvalue() }
@ -1102,7 +1101,7 @@ pub fn (expr Expr) is_lvalue() bool {
} }
pub fn (expr Expr) is_expr() bool { pub fn (expr Expr) is_expr() bool {
match union expr { match expr {
IfExpr { return expr.is_expr } IfExpr { return expr.is_expr }
MatchExpr { return expr.is_expr } MatchExpr { return expr.is_expr }
else {} else {}
@ -1112,7 +1111,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 union stmt { match stmt {
AssignStmt { AssignStmt {
return return
} }
@ -1137,11 +1136,11 @@ pub:
} }
pub fn (stmt Stmt) position() token.Position { pub fn (stmt Stmt) position() token.Position {
match union stmt { match 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 union stmt { TypeDecl { match stmt {
AliasTypeDecl, FnTypeDecl, UnionSumTypeDecl { return stmt.pos } AliasTypeDecl, FnTypeDecl, SumTypeDecl { return stmt.pos }
} } } }
// Please, do NOT use else{} here. // Please, do NOT use else{} here.
// This match is exhaustive *on purpose*, to help force // This match is exhaustive *on purpose*, to help force

View File

@ -73,7 +73,7 @@ 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 union obj { match obj {
Var { return &obj } Var { return &obj }
else {} else {}
} }
@ -83,7 +83,7 @@ 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 union obj { match obj {
ConstField { return &obj } ConstField { return &obj }
else {} else {}
} }
@ -101,7 +101,7 @@ 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
mut obj := s.objects[name] mut obj := s.objects[name]
match union mut obj { match mut obj {
Var { Var {
if obj.typ == typ { if obj.typ == typ {
return return
@ -182,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 union obj { match 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 {}

View File

@ -129,7 +129,7 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
if !needs_braces { if !needs_braces {
mut sub_expr := lit.exprs[i] mut sub_expr := lit.exprs[i]
for { for {
match union mut sub_expr { match mut sub_expr {
Ident { Ident {
if sub_expr.name[0] == `@` { if sub_expr.name[0] == `@` {
needs_braces = true needs_braces = true
@ -176,7 +176,7 @@ pub fn (lit &StringInterLiteral) get_fspec_braces(i int) (string, bool) {
// string representation of expr // string representation of expr
pub fn (x Expr) str() string { pub fn (x Expr) str() string {
match union x { match x {
CTempVar { CTempVar {
return x.orig.str() return x.orig.str()
} }
@ -302,7 +302,7 @@ pub fn (node &BranchStmt) str() string {
} }
pub fn (node Stmt) str() string { pub fn (node Stmt) str() string {
match union node { match node {
AssignStmt { AssignStmt {
mut out := '' mut out := ''
for i, left in node.left { for i, left in node.left {

View File

@ -325,7 +325,7 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
} }
if ftyp in [table.string_type, table.bool_type] || if ftyp in [table.string_type, table.bool_type] ||
sym.kind in sym.kind in
[.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .union_sum_type] || ftyp.has_flag(.optional) || [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type] || ftyp.has_flag(.optional) ||
sym.has_method('str') { sym.has_method('str') {
return `s` return `s`
} else { } else {

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) { pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
for _, obj in sc.objects { for _, obj in sc.objects {
match union obj { match 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 union stmt { match 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)
@ -237,7 +237,7 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
if stmt.is_pub { if stmt.is_pub {
c.warn('type alias `$stmt.name` $no_pub_in_main_warning', stmt.pos) c.warn('type alias `$stmt.name` $no_pub_in_main_warning', stmt.pos)
} }
} else if stmt is ast.UnionSumTypeDecl { } else if stmt is ast.SumTypeDecl {
if stmt.is_pub { if stmt.is_pub {
c.warn('sum type `$stmt.name` $no_pub_in_main_warning', stmt.pos) c.warn('sum type `$stmt.name` $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 union node { match 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' {
@ -311,7 +311,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
} }
} }
} }
ast.UnionSumTypeDecl { ast.SumTypeDecl {
c.check_valid_pascal_case(node.name, 'sum type', node.pos) c.check_valid_pascal_case(node.name, 'sum type', node.pos)
for typ in node.sub_types { for typ in node.sub_types {
mut sym := c.table.get_type_symbol(typ) mut sym := c.table.get_type_symbol(typ)
@ -445,7 +445,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
c.error('unknown type', struct_init.pos) c.error('unknown type', struct_init.pos)
} }
type_sym := c.table.get_type_symbol(struct_init.typ) type_sym := c.table.get_type_symbol(struct_init.typ)
if type_sym.kind == .union_sum_type && struct_init.fields.len == 1 { if type_sym.kind == .sum_type && struct_init.fields.len == 1 {
sexpr := struct_init.fields[0].expr.str() sexpr := struct_init.fields[0].expr.str()
c.error('cast to sum type using `${type_sym.source_name}($sexpr)` not `$type_sym.source_name{$sexpr}`', c.error('cast to sum type using `${type_sym.source_name}($sexpr)` not `$type_sym.source_name{$sexpr}`',
struct_init.pos) struct_init.pos)
@ -726,7 +726,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
} }
} }
if infix_expr.op in [.div, .mod] { if infix_expr.op in [.div, .mod] {
match union mut infix_expr.right { match mut infix_expr.right {
ast.FloatLiteral { ast.FloatLiteral {
if infix_expr.right.val.f64() == 0.0 { if infix_expr.right.val.f64() == 0.0 {
oper := if infix_expr.op == .div { 'division' } else { 'modulo' } oper := if infix_expr.op == .div { 'division' } else { 'modulo' }
@ -793,10 +793,10 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
c.error('$infix_expr.op.str(): type `$typ_sym.source_name` does not exist', c.error('$infix_expr.op.str(): type `$typ_sym.source_name` does not exist',
type_expr.pos) type_expr.pos)
} }
if left.kind !in [.interface_, .union_sum_type] { if left.kind !in [.interface_, .sum_type] {
c.error('`$infix_expr.op.str()` can only be used with interfaces and sum types', c.error('`$infix_expr.op.str()` can only be used with interfaces and sum types',
infix_expr.pos) infix_expr.pos)
} else if mut left.info is table.UnionSumType { } else if mut left.info is table.SumType {
if type_expr.typ !in left.info.variants { if type_expr.typ !in left.info.variants {
c.error('`$left.source_name` has no variant `$right.source_name`', c.error('`$left.source_name` has no variant `$right.source_name`',
infix_expr.pos) infix_expr.pos)
@ -856,9 +856,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
infix_expr.pos) infix_expr.pos)
} }
// sum types can't have any infix operation except of "is", is is checked before and doesn't reach this // sum types can't have any infix operation except of "is", is is checked before and doesn't reach this
if c.table.type_kind(left_type) == .union_sum_type { if c.table.type_kind(left_type) == .sum_type {
c.error('cannot use operator `$infix_expr.op` with `$left.name`', infix_expr.pos) c.error('cannot use operator `$infix_expr.op` with `$left.name`', infix_expr.pos)
} else if c.table.type_kind(right_type) == .union_sum_type { } else if c.table.type_kind(right_type) == .sum_type {
c.error('cannot use operator `$infix_expr.op` with `$right.name`', infix_expr.pos) c.error('cannot use operator `$infix_expr.op` with `$right.name`', infix_expr.pos)
} }
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
@ -890,7 +890,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
mut to_lock := '' // name of variable that needs lock mut to_lock := '' // name of variable that needs lock
mut pos := token.Position{} // and its position mut pos := token.Position{} // and its position
mut explicit_lock_needed := false mut explicit_lock_needed := false
match union mut expr { match mut expr {
ast.CastExpr { ast.CastExpr {
// TODO // TODO
return '', pos return '', pos
@ -1047,7 +1047,7 @@ pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type {
fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_expr ast.CallExpr) { fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_expr ast.CallExpr) {
elem_sym := c.table.get_type_symbol(elem_typ) elem_sym := c.table.get_type_symbol(elem_typ)
arg_expr := call_expr.args[0].expr arg_expr := call_expr.args[0].expr
match union arg_expr { match arg_expr {
ast.AnonFn { ast.AnonFn {
if arg_expr.decl.params.len > 1 { if arg_expr.decl.params.len > 1 {
c.error('function needs exactly 1 argument', call_expr.pos) c.error('function needs exactly 1 argument', call_expr.pos)
@ -1098,7 +1098,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
c.error('optional type cannot be called directly', call_expr.left.position()) c.error('optional type cannot be called directly', call_expr.left.position())
return table.void_type return table.void_type
} }
if left_type_sym.kind == .union_sum_type && method_name == 'type_name' { if left_type_sym.kind == .sum_type && method_name == 'type_name' {
return table.string_type return table.string_type
} }
// TODO: remove this for actual methods, use only for compiler magic // TODO: remove this for actual methods, use only for compiler magic
@ -1138,7 +1138,7 @@ 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 union mut arg_sym.info { match mut arg_sym.info {
table.FnType { ret_type = arg_sym.info.func.return_type } table.FnType { ret_type = arg_sym.info.func.return_type }
else { ret_type = arg_type } else { ret_type = arg_type }
} }
@ -1677,7 +1677,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 union last_stmt { match 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)
@ -1712,7 +1712,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex
} }
} }
} else { } else {
match union last_stmt { match last_stmt {
ast.ExprStmt { ast.ExprStmt {
if last_stmt.typ == table.void_type { if last_stmt.typ == table.void_type {
return return
@ -1735,7 +1735,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex
} }
fn is_expr_panic_or_exit(expr ast.Expr) bool { fn is_expr_panic_or_exit(expr ast.Expr) bool {
match union expr { match expr {
ast.CallExpr { return expr.name in ['panic', 'exit'] } ast.CallExpr { return expr.name in ['panic', 'exit'] }
else { return false } else { return false }
} }
@ -1746,7 +1746,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
c.prevent_sum_type_unwrapping_once = false c.prevent_sum_type_unwrapping_once = false
// T.name, typeof(expr).name // T.name, typeof(expr).name
mut name_type := 0 mut name_type := 0
match union mut selector_expr.expr { match mut selector_expr.expr {
ast.Ident { ast.Ident {
if selector_expr.expr.name == 'T' { if selector_expr.expr.name == 'T' {
name_type = table.Type(c.table.find_type_idx('T')).set_flag(.generic) name_type = table.Type(c.table.find_type_idx('T')).set_flag(.generic)
@ -1788,7 +1788,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
c.error('field `${sym.source_name}.$field_name` is not public', selector_expr.pos) c.error('field `${sym.source_name}.$field_name` is not public', selector_expr.pos)
} }
field_sym := c.table.get_type_symbol(field.typ) field_sym := c.table.get_type_symbol(field.typ)
if field_sym.kind == .union_sum_type { if field_sym.kind == .sum_type {
if !prevent_sum_type_unwrapping_once { if !prevent_sum_type_unwrapping_once {
scope := c.file.scope.innermost(selector_expr.pos.pos) scope := c.file.scope.innermost(selector_expr.pos.pos)
if scope_field := scope.find_struct_field(utyp, field_name) { if scope_field := scope.find_struct_field(utyp, field_name) {
@ -1947,7 +1947,7 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
} }
} }
if field.has_expr { if field.has_expr {
match union field.expr { match field.expr {
ast.IntegerLiteral { ast.IntegerLiteral {
val := field.expr.val.i64() val := field.expr.val.i64()
if val < int_min || val > int_max { if val < int_min || val > int_max {
@ -2107,7 +2107,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
// left_type = c.expr(left) // left_type = c.expr(left)
} }
assign_stmt.left_types << left_type assign_stmt.left_types << left_type
match union mut left { match mut left {
ast.Ident { ast.Ident {
if left.kind == .blank_ident { if left.kind == .blank_ident {
left_type = right_type left_type = right_type
@ -2132,7 +2132,7 @@ 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 union mut left.obj { match mut left.obj {
ast.Var { left.obj.typ = left_type } ast.Var { left.obj.typ = left_type }
ast.GlobalField { left.obj.typ = left_type } ast.GlobalField { left.obj.typ = left_type }
else {} else {}
@ -2282,7 +2282,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
if array_init.has_default { if array_init.has_default {
c.expr(array_init.default_expr) c.expr(array_init.default_expr)
} }
if sym.kind == .union_sum_type { if sym.kind == .sum_type {
if array_init.has_len && !array_init.has_default { if array_init.has_len && !array_init.has_default {
c.error('cannot initalize sum type array without default value', array_init.elem_type_pos) c.error('cannot initalize sum type array without default value', array_init.elem_type_pos)
} }
@ -2367,7 +2367,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
// [50]byte // [50]byte
mut fixed_size := 1 mut fixed_size := 1
init_expr := array_init.exprs[0] init_expr := array_init.exprs[0]
match union init_expr { match init_expr {
ast.IntegerLiteral { ast.IntegerLiteral {
fixed_size = init_expr.val.int() fixed_size = init_expr.val.int()
} }
@ -2409,7 +2409,7 @@ fn const_int_value(cfield ast.ConstField) ?int {
} }
fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral { fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral {
match union cfield.expr { match cfield.expr {
ast.IntegerLiteral { return cfield.expr } ast.IntegerLiteral { return cfield.expr }
else {} else {}
} }
@ -2435,7 +2435,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 union mut node { match 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)
@ -2769,7 +2769,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
c.error('checker: too many expr levels: $c.expr_level ', node.position()) c.error('checker: too many expr levels: $c.expr_level ', node.position())
return table.void_type return table.void_type
} }
match union mut node { match mut node {
ast.CTempVar { ast.CTempVar {
return node.typ return node.typ
} }
@ -2787,7 +2787,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
node.expr_type = c.expr(node.expr) node.expr_type = c.expr(node.expr)
expr_type_sym := c.table.get_type_symbol(node.expr_type) expr_type_sym := c.table.get_type_symbol(node.expr_type)
type_sym := c.table.get_type_symbol(node.typ) type_sym := c.table.get_type_symbol(node.typ)
if expr_type_sym.kind == .union_sum_type { if expr_type_sym.kind == .sum_type {
if type_sym.kind == .placeholder { if type_sym.kind == .placeholder {
// Unknown type used in the right part of `as` // Unknown type used in the right part of `as`
c.error('unknown type `$type_sym.source_name`', node.pos) c.error('unknown type `$type_sym.source_name`', node.pos)
@ -2799,12 +2799,12 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
} }
} else { } else {
mut s := 'cannot cast non-sum type `$expr_type_sym.source_name` using `as`' mut s := 'cannot cast non-sum type `$expr_type_sym.source_name` using `as`'
if type_sym.kind == .union_sum_type { if type_sym.kind == .sum_type {
s += ' - use e.g. `${type_sym.source_name}(some_expr)` instead.' s += ' - use e.g. `${type_sym.source_name}(some_expr)` instead.'
} }
c.error(s, node.pos) c.error(s, node.pos)
} }
if expr_type_sym.kind == .union_sum_type { if expr_type_sym.kind == .sum_type {
return node.typ return node.typ
} }
return node.typ.to_ptr() return node.typ.to_ptr()
@ -3054,7 +3054,7 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
c.error('can not cast type `byte` to string, use `${node.expr.str()}.str()` instead.', c.error('can not cast type `byte` to string, use `${node.expr.str()}.str()` instead.',
node.pos) node.pos)
} }
if to_type_sym.kind == .union_sum_type { if to_type_sym.kind == .sum_type {
if node.expr_type in [table.any_int_type, table.any_flt_type] { if node.expr_type in [table.any_int_type, table.any_flt_type] {
node.expr_type = c.promote_num(node.expr_type, if node.expr_type == table.any_int_type { table.int_type } else { table.f64_type }) node.expr_type = c.promote_num(node.expr_type, if node.expr_type == table.any_int_type { table.int_type } else { table.f64_type })
} }
@ -3209,7 +3209,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
} }
start_scope := c.file.scope.innermost(ident.pos.pos) start_scope := c.file.scope.innermost(ident.pos.pos)
if obj := start_scope.find(ident.name) { if obj := start_scope.find(ident.name) {
match union mut obj { match mut obj {
ast.GlobalField { ast.GlobalField {
ident.kind = .global ident.kind = .global
ident.info = ast.IdentVar{ ident.info = ast.IdentVar{
@ -3276,7 +3276,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
name = '${ident.mod}.$ident.name' name = '${ident.mod}.$ident.name'
} }
if obj := c.file.global_scope.find(name) { if obj := c.file.global_scope.find(name) {
match union mut obj { match mut obj {
ast.ConstField { ast.ConstField {
mut typ := obj.typ mut typ := obj.typ
if typ == 0 { if typ == 0 {
@ -3365,7 +3365,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
c.error('compiler bug: match 0 cond type', node.pos) c.error('compiler bug: match 0 cond type', node.pos)
} }
cond_type_sym := c.table.get_type_symbol(cond_type) cond_type_sym := c.table.get_type_symbol(cond_type)
if cond_type_sym.kind !in [.interface_, .union_sum_type] { if cond_type_sym.kind !in [.interface_, .sum_type] {
node.is_sum_type = false node.is_sum_type = false
} }
c.match_exprs(mut node, cond_type_sym) c.match_exprs(mut node, cond_type_sym)
@ -3390,7 +3390,7 @@ 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 {
mut stmt := branch.stmts[branch.stmts.len - 1] mut stmt := branch.stmts[branch.stmts.len - 1]
match union mut stmt { match 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
@ -3479,7 +3479,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
} }
continue continue
} }
match union expr { match expr {
ast.Type { ast.Type {
key = c.table.type_to_str(expr.typ) key = c.table.type_to_str(expr.typ)
expr_types << expr expr_types << expr
@ -3505,7 +3505,7 @@ 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 mut cond_type_sym.info is table.UnionSumType { } else if mut cond_type_sym.info is table.SumType {
if expr_type !in cond_type_sym.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)
@ -3520,7 +3520,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
} }
// when match is sum type matching, then register smart cast for every branch // when match is sum type matching, then register smart cast for every branch
if expr_types.len > 0 { if expr_types.len > 0 {
if cond_type_sym.kind == .union_sum_type { if cond_type_sym.kind == .sum_type {
mut expr_type := table.Type(0) mut expr_type := table.Type(0)
if expr_types.len > 1 { if expr_types.len > 1 {
mut agg_name := strings.new_builder(20) mut agg_name := strings.new_builder(20)
@ -3608,8 +3608,8 @@ 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 union mut type_sym.info { match mut type_sym.info {
table.UnionSumType { table.SumType {
for v in type_sym.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 {
@ -3673,7 +3673,7 @@ 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 union branch.stmt { match branch.stmt {
ast.ExprStmt { ast.ExprStmt {
if branch.is_timeout { if branch.is_timeout {
if !branch.stmt.typ.is_int() { if !branch.stmt.typ.is_int() {
@ -3694,7 +3694,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) table.Type {
} }
ast.AssignStmt { ast.AssignStmt {
expr := branch.stmt.right[0] expr := branch.stmt.right[0]
match union expr { match expr {
ast.PrefixExpr { ast.PrefixExpr {
if expr.right !is ast.Ident && if expr.right !is ast.Ident &&
expr.right !is ast.SelectorExpr && expr.right !is ast.IndexExpr { expr.right !is ast.SelectorExpr && expr.right !is ast.IndexExpr {
@ -3812,7 +3812,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
is_variable := if mut infix.left is ast.Ident { infix.left.kind == .variable } else { true } is_variable := if mut infix.left is ast.Ident { infix.left.kind == .variable } else { true }
// Register shadow variable or `as` variable with actual type // Register shadow variable or `as` variable with actual type
if is_variable { if is_variable {
if left_sym.kind in [.interface_, .union_sum_type] { if left_sym.kind in [.interface_, .sum_type] {
mut is_mut := false mut is_mut := false
mut scope := c.file.scope.innermost(branch.body_pos.pos) mut scope := c.file.scope.innermost(branch.body_pos.pos)
if mut infix.left is ast.Ident { if mut infix.left is ast.Ident {
@ -3821,7 +3821,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
is_mut = v.is_mut is_mut = v.is_mut
sum_type_casts << v.sum_type_casts sum_type_casts << v.sum_type_casts
} }
if left_sym.kind == .union_sum_type { if left_sym.kind == .sum_type {
// smartcast either if the value is immutable or if the mut argument is explicitly given // smartcast either if the value is immutable or if the mut argument is explicitly given
if !is_mut || branch.is_mut_name { if !is_mut || branch.is_mut_name {
sum_type_casts << right_expr.typ sum_type_casts << right_expr.typ
@ -3861,7 +3861,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
// smartcast either if the value is immutable or if the mut argument is explicitly given // smartcast either if the value is immutable or if the mut argument is explicitly given
if ((!is_root_mut && !is_mut) || if ((!is_root_mut && !is_mut) ||
branch.is_mut_name) && branch.is_mut_name) &&
left_sym.kind == .union_sum_type { left_sym.kind == .sum_type {
sum_type_casts << right_expr.typ sum_type_casts << right_expr.typ
scope.register_struct_field(ast.ScopeStructField{ scope.register_struct_field(ast.ScopeStructField{
struct_type: infix.left.expr_type struct_type: infix.left.expr_type
@ -3990,7 +3990,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
// saying whether that branch's contents should be skipped (targets a different os for example) // saying whether that branch's contents should be skipped (targets a different os for example)
fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool { fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool {
// TODO: better error messages here // TODO: better error messages here
match union cond { match cond {
ast.ParExpr { ast.ParExpr {
return c.comp_if_branch(cond.expr, pos) return c.comp_if_branch(cond.expr, pos)
} }
@ -4506,7 +4506,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
if sym.kind == .interface_ { if sym.kind == .interface_ {
c.error('interfaces cannot be used as method receiver', node.receiver_pos) c.error('interfaces cannot be used as method receiver', node.receiver_pos)
} }
if sym.kind == .union_sum_type && node.name == 'type_name' { if sym.kind == .sum_type && node.name == 'type_name' {
c.error('method overrides built-in sum type method', node.pos) c.error('method overrides built-in sum type method', node.pos)
} }
// if sym.has_method(node.name) { // if sym.has_method(node.name) {

View File

@ -1,9 +1,9 @@
__type Expr = IfExpr | CallExpr | MatchExpr type Expr = IfExpr | CallExpr | MatchExpr
struct MatchExpr {} struct MatchExpr {}
struct IfExpr {} struct IfExpr {}
struct CallExpr {} struct CallExpr {}
__type Stmt = Expr | AnotherThing type Stmt = Expr | AnotherThing
struct AnotherThing {} struct AnotherThing {}
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
__type Abc = int | string type Abc = int | string
fn main() { fn main() {
x := Abc(0) x := Abc(0)

View File

@ -1,4 +1,4 @@
__type Abc = int | string type Abc = int | string
struct Bar { struct Bar {
mut: mut:

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 { if node.name.len == 0 && node.comment.len == 0 && node.content.len == 0 {
return error('empty stmt') return error('empty stmt')
} }
match union stmt { match stmt {
ast.ConstDecl { ast.ConstDecl {
node.kind = .const_group node.kind = .const_group
node.parent_name = 'Constants' 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 { pub fn (mut d Doc) stmt_signature(stmt ast.Stmt) string {
match union stmt { match stmt {
ast.Module { ast.Module {
return 'module $stmt.name' return 'module $stmt.name'
} }
@ -93,10 +93,10 @@ 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 union stmt { match 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 union stmt { ast.TypeDecl { match stmt {
ast.FnTypeDecl, ast.AliasTypeDecl, ast.UnionSumTypeDecl { return stmt.name } ast.FnTypeDecl, ast.AliasTypeDecl, ast.SumTypeDecl { return stmt.name }
} } } }
ast.ConstDecl { return '' } // leave it blank ast.ConstDecl { return '' } // leave it blank
else { return '' } else { return '' }

View File

@ -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 union o { match 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 union o { match o {
int { return o.str() } int { return o.str() }
else { println('unknown object') } else { println('unknown object') }
} }

View File

@ -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 union node { match 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 {
@ -491,7 +491,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
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 union node { match node {
ast.AliasTypeDecl { ast.AliasTypeDecl {
if node.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
@ -544,11 +544,11 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
} }
comments << node.comments comments << node.comments
} }
ast.UnionSumTypeDecl { ast.SumTypeDecl {
if node.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
} }
f.write('__type $node.name = ') f.write('type $node.name = ')
mut sum_type_names := []string{} mut sum_type_names := []string{}
for t in node.sub_types { for t in node.sub_types {
sum_type_names << f.table.type_to_str(t) sum_type_names << f.table.type_to_str(t)
@ -741,7 +741,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
if f.is_debug { if f.is_debug {
eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()') eprintln('expr: ${node.position():-42} | node: ${typeof(node):-20} | $node.str()')
} }
match union mut node { match mut node {
ast.CTempVar { ast.CTempVar {
eprintln('ast.CTempVar of $node.orig.str() should be generated/used only in cgen') eprintln('ast.CTempVar of $node.orig.str() should be generated/used only in cgen')
} }
@ -1342,7 +1342,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
} }
f.expr_bufs << f.out.str() f.expr_bufs << f.out.str()
mut penalty := 3 mut penalty := 3
match union mut node.left { match mut node.left {
ast.InfixExpr { ast.InfixExpr {
if int(token.precedences[node.left.op]) > int(token.precedences[node.op]) { if int(token.precedences[node.left.op]) > int(token.precedences[node.op]) {
penalty-- penalty--
@ -1353,7 +1353,7 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) {
} }
else {} else {}
} }
match union node.right { match node.right {
ast.InfixExpr { penalty-- } ast.InfixExpr { penalty-- }
ast.ParExpr { penalty = 1 } ast.ParExpr { penalty = 1 }
else {} else {}
@ -1528,9 +1528,6 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) {
pub fn (mut f Fmt) match_expr(it ast.MatchExpr) { pub fn (mut f Fmt) match_expr(it ast.MatchExpr) {
f.write('match ') f.write('match ')
if it.is_union_match {
f.write('union ')
}
if it.is_mut { if it.is_mut {
f.write('mut ') f.write('mut ')
} }
@ -1652,7 +1649,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 union stmt { match 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 }
@ -1661,7 +1658,7 @@ fn stmt_is_single_line(stmt ast.Stmt) bool {
} }
fn expr_is_single_line(expr ast.Expr) bool { fn expr_is_single_line(expr ast.Expr) bool {
match union expr { match expr {
ast.IfExpr { return false } ast.IfExpr { return false }
ast.Comment { return false } ast.Comment { return false }
else {} else {}

View File

@ -4,7 +4,7 @@ struct IfExpr {
struct MatchExpr { struct MatchExpr {
} }
__type Expr = IfExpr | MatchExpr type Expr = IfExpr | MatchExpr
fn sum_types(a []Expr) { fn sum_types(a []Expr) {
} }

View File

@ -15,7 +15,7 @@ fn handle_users(users []User) {
fn (u &User) foo(u2 &User) { fn (u &User) foo(u2 &User) {
} }
__type Expr = IfExpr | IntegerLiteral type Expr = IfExpr | IntegerLiteral
fn exprs(e []Expr) { fn exprs(e []Expr) {
println(e.len) println(e.len)

View File

@ -6,7 +6,7 @@ mut:
struct S2 { struct S2 {
} }
__type Sum = S1 | S2 type Sum = S1 | S2
fn f(sum Sum) { fn f(sum Sum) {
if mut sum is S1 { if mut sum is S1 {

View File

@ -1,11 +1,11 @@
// Sumtype // Sumtype
__type FooBar = Bar | Foo type FooBar = Bar | Foo
pub __type PublicBar = Bar | Foo | FooBar pub type PublicBar = Bar | Foo | FooBar
__type Uint = byte | u16 | u32 | u64 type Uint = byte | u16 | u32 | u64 // This should stay on the same line
__type Float = f32 | f64 type Float = f32 | f64
// Alias type // Alias type
type MyInt = int type MyInt = int

View File

@ -6,7 +6,7 @@
type Uint = u16 | u64 type Uint = u16 | u64
| u32 | u32
| byte | byte // This should stay on the same line
type type
Float = Float =
f32 | f32 |

View File

@ -47,7 +47,7 @@ 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 union mut sym.info { match 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)
@ -73,7 +73,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
table.MultiReturn { table.MultiReturn {
g.gen_str_for_multi_return(sym.info, styp, str_fn_name) g.gen_str_for_multi_return(sym.info, styp, str_fn_name)
} }
table.UnionSumType { table.SumType {
g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name) g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name)
} }
else { else {
@ -438,7 +438,7 @@ fn struct_auto_str_func(sym table.TypeSymbol, field_type table.Type, fn_name str
return '${fn_name}($obj)' return '${fn_name}($obj)'
} }
return 'indent_${fn_name}($obj, indent_count + 1)' return 'indent_${fn_name}($obj, indent_count + 1)'
} else if sym.kind in [.array, .array_fixed, .map, .union_sum_type] { } else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
if has_custom_str { if has_custom_str {
return '${fn_name}(it->${c_name(field_name)})' return '${fn_name}(it->${c_name(field_name)})'
} }
@ -482,7 +482,7 @@ fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string
g.auto_str_funcs.writeln('}') g.auto_str_funcs.writeln('}')
} }
fn (mut g Gen) gen_str_for_union_sum_type(info table.UnionSumType, styp string, str_fn_name string) { fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_fn_name string) {
mut gen_fn_names := map[string]string{} mut gen_fn_names := map[string]string{}
for typ in info.variants { for typ in info.variants {
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)

View File

@ -371,8 +371,8 @@ pub fn (mut g Gen) write_typeof_functions() {
g.writeln('') g.writeln('')
g.writeln('// >> typeof() support for sum types') g.writeln('// >> typeof() support for sum types')
for typ in g.table.types { for typ in g.table.types {
if typ.kind == .union_sum_type { if typ.kind == .sum_type {
sum_info := typ.info as table.UnionSumType sum_info := typ.info as table.SumType
tidx := g.table.find_type_idx(typ.name) tidx := g.table.find_type_idx(typ.name)
g.writeln('char * v_typeof_unionsumtype_${tidx}(int sidx) { /* $typ.name */ ') g.writeln('char * v_typeof_unionsumtype_${tidx}(int sidx) { /* $typ.name */ ')
g.writeln(' switch(sidx) {') g.writeln(' switch(sidx) {')
@ -785,7 +785,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
} }
// println('cgen.stmt()') // println('cgen.stmt()')
// g.writeln('//// stmt start') // g.writeln('//// stmt start')
match union node { match 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)
@ -1266,18 +1266,19 @@ fn (mut g Gen) union_expr_with_cast(expr ast.Expr, got_type table.Type, expected
got_styp := g.typ(got_type) got_styp := g.typ(got_type)
got_idx := got_type.idx() got_idx := got_type.idx()
got_sym := g.table.get_type_symbol(got_type) got_sym := g.table.get_type_symbol(got_type)
// TODO: do we need 1-3?
if expected_is_ptr && got_is_ptr { if expected_is_ptr && got_is_ptr {
exp_der_styp := g.typ(expected_deref_type) exp_der_styp := g.typ(expected_deref_type)
g.write('/* union sum type cast 1 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = ') g.write('/* sum type cast 1 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = ')
g.expr(expr) g.expr(expr)
g.write(', .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))') g.write(', .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))')
} else if expected_is_ptr { } else if expected_is_ptr {
exp_der_styp := g.typ(expected_deref_type) exp_der_styp := g.typ(expected_deref_type)
g.write('/* union sum type cast 2 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = memdup(&($got_styp[]){') g.write('/* sum type cast 2 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = memdup(&($got_styp[]){')
g.expr(expr) g.expr(expr)
g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))') g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))')
} else if got_is_ptr { } else if got_is_ptr {
g.write('/* union sum type cast 3 */ ($exp_styp){._$got_idx = ') g.write('/* sum type cast 3 */ ($exp_styp){._$got_idx = ')
g.expr(expr) g.expr(expr)
g.write(', .typ = $got_type /* $got_sym.name */}') g.write(', .typ = $got_type /* $got_sym.name */}')
} else { } else {
@ -1299,7 +1300,7 @@ fn (mut g Gen) union_expr_with_cast(expr ast.Expr, got_type table.Type, expected
g.prevent_sum_type_unwrapping_once = true g.prevent_sum_type_unwrapping_once = true
g.expr(expr) g.expr(expr)
} else { } else {
g.write('/* union sum type cast 4 */ ($exp_styp){._$got_type = memdup(&($got_styp[]){') g.write('/* sum type cast 4 */ ($exp_styp){._$got_type = memdup(&($got_styp[]){')
g.expr(expr) g.expr(expr)
g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}') g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}')
} }
@ -1328,7 +1329,7 @@ fn (mut g Gen) union_expr_with_cast(expr ast.Expr, got_type table.Type, expected
// use instead of expr() when you need to cast to sum type (can add other casts also) // use instead of expr() when you need to cast to sum type (can add other casts also)
fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type table.Type, expected_type table.Type) { fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type table.Type, expected_type table.Type) {
sym := g.table.get_type_symbol(expected_type) sym := g.table.get_type_symbol(expected_type)
if sym.kind == .union_sum_type { if sym.kind == .sum_type {
g.union_expr_with_cast(expr, got_type, expected_type) g.union_expr_with_cast(expr, got_type, expected_type)
return return
} }
@ -1454,7 +1455,7 @@ fn (mut g Gen) gen_assert_metainfo(a ast.AssertStmt) string {
g.writeln('\t${metaname}.line_nr = $line_nr;') g.writeln('\t${metaname}.line_nr = $line_nr;')
g.writeln('\t${metaname}.fn_name = ${ctoslit(fn_name)};') g.writeln('\t${metaname}.fn_name = ${ctoslit(fn_name)};')
g.writeln('\t${metaname}.src = ${cnewlines(ctoslit(src))};') g.writeln('\t${metaname}.src = ${cnewlines(ctoslit(src))};')
match union mut a.expr { match mut a.expr {
ast.InfixExpr { ast.InfixExpr {
g.writeln('\t${metaname}.op = ${ctoslit(a.expr.op.str())};') g.writeln('\t${metaname}.op = ${ctoslit(a.expr.op.str())};')
g.writeln('\t${metaname}.llabel = ${cnewlines(ctoslit(a.expr.left.str()))};') g.writeln('\t${metaname}.llabel = ${cnewlines(ctoslit(a.expr.left.str()))};')
@ -1477,7 +1478,7 @@ fn (mut g Gen) gen_assert_metainfo(a ast.AssertStmt) string {
fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) { fn (mut g Gen) gen_assert_single_expr(e ast.Expr, t table.Type) {
unknown_value := '*unknown value*' unknown_value := '*unknown value*'
match union e { match e {
ast.CastExpr, ast.IndexExpr, ast.MatchExpr { ast.CastExpr, ast.IndexExpr, ast.MatchExpr {
g.write(ctoslit(unknown_value)) g.write(ctoslit(unknown_value))
} }
@ -1529,7 +1530,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
op := if assign_stmt.op == .decl_assign { token.Kind.assign } else { assign_stmt.op } op := if assign_stmt.op == .decl_assign { token.Kind.assign } else { assign_stmt.op }
is_decl := assign_stmt.op == .decl_assign is_decl := assign_stmt.op == .decl_assign
right_expr := assign_stmt.right[0] right_expr := assign_stmt.right[0]
match union right_expr { match right_expr {
ast.CallExpr { return_type = right_expr.return_type } ast.CallExpr { return_type = right_expr.return_type }
ast.MatchExpr { return_type = right_expr.return_type } ast.MatchExpr { return_type = right_expr.return_type }
ast.IfExpr { return_type = right_expr.typ } ast.IfExpr { return_type = right_expr.typ }
@ -1639,7 +1640,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
// TODO: non idents on left (exprs) // TODO: non idents on left (exprs)
if assign_stmt.has_cross_var { if assign_stmt.has_cross_var {
for i, left in assign_stmt.left { for i, left in assign_stmt.left {
match union left { match left {
ast.Ident { ast.Ident {
left_typ := assign_stmt.left_types[i] left_typ := assign_stmt.left_types[i]
left_sym := g.table.get_type_symbol(left_typ) left_sym := g.table.get_type_symbol(left_typ)
@ -1746,7 +1747,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
styp := g.typ(var_type) styp := g.typ(var_type)
mut is_fixed_array_init := false mut is_fixed_array_init := false
mut has_val := false mut has_val := false
match union val { match val {
ast.ArrayInit { ast.ArrayInit {
is_fixed_array_init = val.is_fixed is_fixed_array_init = val.is_fixed
has_val = val.has_val has_val = val.has_val
@ -1947,7 +1948,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) { fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
val_ := val val_ := val
match union val { match val {
ast.Ident { ast.Ident {
mut has_var := false mut has_var := false
for lx in left { for lx in left {
@ -2082,7 +2083,7 @@ 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 union obj { match 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 {
@ -2194,7 +2195,7 @@ fn (mut g Gen) gen_anon_fn_decl(it ast.AnonFn) {
fn (mut g Gen) expr(node ast.Expr) { fn (mut g Gen) expr(node ast.Expr) {
// println('cgen expr() line_nr=$node.pos.line_nr') // println('cgen expr() line_nr=$node.pos.line_nr')
// NB: please keep the type names in the match here in alphabetical order: // NB: please keep the type names in the match here in alphabetical order:
match union node { match node {
ast.AnonFn { ast.AnonFn {
// TODO: dont fiddle with buffers // TODO: dont fiddle with buffers
g.gen_anon_fn_decl(node) g.gen_anon_fn_decl(node)
@ -2277,7 +2278,7 @@ fn (mut g Gen) expr(node ast.Expr) {
g.expr(node.arg) g.expr(node.arg)
} }
g.write(')') g.write(')')
} else if sym.kind == .union_sum_type { } else if sym.kind == .sum_type {
g.expr_with_cast(node.expr, node.expr_type, node.typ) g.expr_with_cast(node.expr, node.expr_type, node.typ)
} else if sym.kind == .struct_ && !node.typ.is_ptr() && !(sym.info as table.Struct).is_typedef { } else if sym.kind == .struct_ && !node.typ.is_ptr() && !(sym.info as table.Struct).is_typedef {
styp := g.typ(node.typ) styp := g.typ(node.typ)
@ -2544,7 +2545,7 @@ fn (mut g Gen) expr(node ast.Expr) {
mut sum_type_deref_field := '' mut sum_type_deref_field := ''
if field := g.table.struct_find_field(sym, node.field_name) { if field := g.table.struct_find_field(sym, node.field_name) {
field_sym := g.table.get_type_symbol(field.typ) field_sym := g.table.get_type_symbol(field.typ)
if field_sym.kind == .union_sum_type { if field_sym.kind == .sum_type {
if !prevent_sum_type_unwrapping_once { if !prevent_sum_type_unwrapping_once {
// check first if field is sum type because scope searching is expensive // check first if field is sum type because scope searching is expensive
scope := g.file.scope.innermost(node.pos.pos) scope := g.file.scope.innermost(node.pos.pos)
@ -2633,7 +2634,7 @@ fn (mut g Gen) type_name(type_ table.Type) {
fn (mut g Gen) typeof_expr(node ast.TypeOf) { fn (mut g Gen) typeof_expr(node ast.TypeOf) {
sym := g.table.get_type_symbol(node.expr_type) sym := g.table.get_type_symbol(node.expr_type)
if sym.kind == .union_sum_type { if sym.kind == .sum_type {
// When encountering a .sum_type, typeof() should be done at runtime, // When encountering a .sum_type, typeof() should be done at runtime,
// because the subtype of the expression may change: // because the subtype of the expression may change:
sum_type_idx := node.expr_type.idx() sum_type_idx := node.expr_type.idx()
@ -2665,7 +2666,7 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
} }
fn (mut g Gen) enum_expr(node ast.Expr) { fn (mut g Gen) enum_expr(node ast.Expr) {
match union node { match node {
ast.EnumVal { g.write(node.val) } ast.EnumVal { g.write(node.val) }
else { g.expr(node) } else { g.expr(node) }
} }
@ -3075,7 +3076,7 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str
} }
g.write(cond_var) g.write(cond_var)
// branch_sym := g.table.get_type_symbol(branch.typ) // branch_sym := g.table.get_type_symbol(branch.typ)
if sym.kind == .union_sum_type { if sym.kind == .sum_type {
dot_or_ptr := if node.cond_type.is_ptr() { '->' } else { '.' } dot_or_ptr := if node.cond_type.is_ptr() { '->' } else { '.' }
g.write(dot_or_ptr) g.write(dot_or_ptr)
g.write('typ == ') g.write('typ == ')
@ -3210,7 +3211,7 @@ 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 union branch.stmt { match branch.stmt {
ast.ExprStmt { ast.ExprStmt {
// send expression // send expression
expr := branch.stmt.expr as ast.InfixExpr expr := branch.stmt.expr as ast.InfixExpr
@ -3406,8 +3407,8 @@ 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 {
info := g.match_sumtype_syms[i].info info := g.match_sumtype_syms[i].info
match union info { match info {
table.UnionSumType { table.SumType {
for typ in info.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
@ -3522,7 +3523,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
g.writeln('\tint errcode = ${cvar_name}.ecode;') g.writeln('\tint errcode = ${cvar_name}.ecode;')
} }
} else { } else {
match union branch.cond { match branch.cond {
ast.IfGuardExpr { ast.IfGuardExpr {
var_name := guard_vars[i] var_name := guard_vars[i]
g.write('if ($var_name = ') g.write('if ($var_name = ')
@ -3574,7 +3575,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
} }
fn (mut g Gen) index_expr(node ast.IndexExpr) { fn (mut g Gen) index_expr(node ast.IndexExpr) {
match union node.index { match node.index {
ast.RangeExpr { ast.RangeExpr {
sym := g.table.get_type_symbol(node.left_type) sym := g.table.get_type_symbol(node.left_type)
if sym.kind == .string { if sym.kind == .string {
@ -3835,7 +3836,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
[inline] [inline]
fn (g &Gen) expr_is_multi_return_call(expr ast.Expr) bool { fn (g &Gen) expr_is_multi_return_call(expr ast.Expr) bool {
match union expr { match expr {
ast.CallExpr { return g.table.get_type_symbol(expr.return_type).kind == .multi_return } ast.CallExpr { return g.table.get_type_symbol(expr.return_type).kind == .multi_return }
else { return false } else { return false }
} }
@ -4060,7 +4061,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
} }
} else { } else {
*/ */
match union field.expr { match field.expr {
ast.CharLiteral, ast.FloatLiteral, ast.IntegerLiteral { ast.CharLiteral, ast.FloatLiteral, ast.IntegerLiteral {
g.const_decl_simple_define(name, val) g.const_decl_simple_define(name, val)
} }
@ -4546,7 +4547,7 @@ 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 union mut typ.info { match mut typ.info {
table.Struct { table.Struct {
if typ.info.generic_types.len > 0 { if typ.info.generic_types.len > 0 {
continue continue
@ -4595,7 +4596,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
table.Alias { table.Alias {
// table.Alias { TODO // table.Alias { TODO
} }
table.UnionSumType { table.SumType {
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 = ')
@ -4646,7 +4647,7 @@ 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 union mut t.info { match mut t.info {
table.ArrayFixed { table.ArrayFixed {
dep := g.table.get_type_symbol(t.info.elem_type).name dep := g.table.get_type_symbol(t.info.elem_type).name
if dep in type_names { if dep in type_names {
@ -4707,7 +4708,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
g.expr(expr) g.expr(expr)
return true return true
} else if sym.kind == .enum_ { } else if sym.kind == .enum_ {
is_var := match union expr { is_var := match expr {
ast.SelectorExpr, ast.Ident { true } ast.SelectorExpr, ast.Ident { true }
else { false } else { false }
} }
@ -4722,7 +4723,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
g.write('")') g.write('")')
} }
} else if sym_has_str_method || sym.kind in } else if sym_has_str_method || sym.kind in
[.array, .array_fixed, .map, .struct_, .multi_return, .union_sum_type] { [.array, .array_fixed, .map, .struct_, .multi_return, .sum_type] {
is_p := typ.is_ptr() is_p := typ.is_ptr()
val_type := if is_p { typ.deref() } else { typ } val_type := if is_p { typ.deref() } else { typ }
str_fn_name := g.gen_str_for_type(val_type) str_fn_name := g.gen_str_for_type(val_type)
@ -4806,7 +4807,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
g.writeln('.data)[$i];') g.writeln('.data)[$i];')
g.write('\t$ret_elem_type ti = ') g.write('\t$ret_elem_type ti = ')
expr := node.args[0].expr expr := node.args[0].expr
match union expr { match expr {
ast.AnonFn { ast.AnonFn {
g.gen_anon_fn_decl(expr) g.gen_anon_fn_decl(expr)
g.write('${expr.decl.name}(it)') g.write('${expr.decl.name}(it)')
@ -4961,7 +4962,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) {
g.writeln('.data)[i];') g.writeln('.data)[i];')
g.write('if (') g.write('if (')
expr := node.args[0].expr expr := node.args[0].expr
match union expr { match expr {
ast.AnonFn { ast.AnonFn {
g.gen_anon_fn_decl(expr) g.gen_anon_fn_decl(expr)
g.write('${expr.decl.name}(it)') g.write('${expr.decl.name}(it)')
@ -5157,7 +5158,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.
} }
fn (mut g Gen) type_of_call_expr(node ast.Expr) string { fn (mut g Gen) type_of_call_expr(node ast.Expr) string {
match union node { match node {
ast.CallExpr { return g.typ(node.return_type) } ast.CallExpr { return g.typ(node.return_type) }
else { return typeof(node) } else { return typeof(node) }
} }
@ -5390,7 +5391,7 @@ fn (mut g Gen) type_default(typ_ table.Type) string {
else {} else {}
} }
return match sym.kind { return match sym.kind {
.interface_, .union_sum_type, .array_fixed, .multi_return { '{0}' } .interface_, .sum_type, .array_fixed, .multi_return { '{0}' }
.alias { g.type_default((sym.info as table.Alias).parent_type) } .alias { g.type_default((sym.info as table.Alias).parent_type) }
else { '0' } else { '0' }
} }
@ -5545,7 +5546,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) {
// g.insert_before(' // g.insert_before('
styp := g.typ(node.typ) styp := g.typ(node.typ)
expr_type_sym := g.table.get_type_symbol(node.expr_type) expr_type_sym := g.table.get_type_symbol(node.expr_type)
if expr_type_sym.kind == .union_sum_type { if expr_type_sym.kind == .sum_type {
dot := if node.expr_type.is_ptr() { '->' } else { '.' } dot := if node.expr_type.is_ptr() { '->' } else { '.' }
g.write('/* as */ *($styp*)__as_cast((') g.write('/* as */ *($styp*)__as_cast((')
g.expr(node.expr) g.expr(node.expr)
@ -5577,7 +5578,7 @@ fn (mut g Gen) is_expr(node ast.InfixExpr) {
sub_sym := g.table.get_type_symbol(sub_type.typ) sub_sym := g.table.get_type_symbol(sub_type.typ)
g.write('_${c_name(sym.name)}_${c_name(sub_sym.name)}_index') g.write('_${c_name(sym.name)}_${c_name(sub_sym.name)}_index')
return return
} else if sym.kind == .union_sum_type { } else if sym.kind == .sum_type {
g.write('typ $eq ') g.write('typ $eq ')
} }
g.expr(node.right) g.expr(node.right)
@ -5644,7 +5645,7 @@ fn (g &Gen) type_to_fmt(typ table.Type) string {
return '%g\\000' // g removes trailing zeros unlike %f return '%g\\000' // g removes trailing zeros unlike %f
} else if sym.kind == .u64 { } else if sym.kind == .u64 {
return '%lld\\000' return '%lld\\000'
} else if sym.kind == .union_sum_type { } else if sym.kind == .sum_type {
return '%.*s\\000' return '%.*s\\000'
} }
return '%d\\000' return '%d\\000'

View File

@ -174,7 +174,7 @@ fn (mut g Gen) comp_if(node ast.IfExpr) {
} }
fn (mut g Gen) comp_if_expr(cond ast.Expr) { fn (mut g Gen) comp_if_expr(cond ast.Expr) {
match union cond { match cond {
ast.ParExpr { ast.ParExpr {
g.write('(') g.write('(')
g.comp_if_expr(cond.expr) g.comp_if_expr(cond.expr)

View File

@ -366,7 +366,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
else {} else {}
} }
} }
if left_sym.kind == .union_sum_type && node.name == 'type_name' { if left_sym.kind == .sum_type && node.name == 'type_name' {
g.write('tos3( /* $left_sym.name */ v_typeof_unionsumtype_${node.receiver_type}( (') g.write('tos3( /* $left_sym.name */ v_typeof_unionsumtype_${node.receiver_type}( (')
g.expr(node.left) g.expr(node.left)
g.write(').typ ))') g.write(').typ ))')
@ -569,7 +569,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
g.writeln('); ${print_method}($tmp); string_free(&$tmp); //MEM2 $styp') g.writeln('); ${print_method}($tmp); string_free(&$tmp); //MEM2 $styp')
} else { } else {
expr := node.args[0].expr expr := node.args[0].expr
is_var := match union expr { is_var := match expr {
ast.SelectorExpr { true } ast.SelectorExpr { true }
ast.Ident { true } ast.Ident { true }
else { false } else { false }
@ -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 union mut x { match mut x {
ast.Var { x.is_used = false } ast.Var { x.is_used = false }
else {} else {}
} }
@ -740,7 +740,7 @@ 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 union mut obj { match mut obj {
ast.Var { ast.Var {
// if var.typ == 0 { // if var.typ == 0 {
// // TODO why 0? // // TODO why 0?
@ -887,7 +887,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
} }
arg_typ_sym := g.table.get_type_symbol(arg.typ) arg_typ_sym := g.table.get_type_symbol(arg.typ)
expected_deref_type := if expected_type.is_ptr() { expected_type.deref() } else { expected_type } expected_deref_type := if expected_type.is_ptr() { expected_type.deref() } else { expected_type }
is_sum_type := g.table.get_type_symbol(expected_deref_type).kind == .union_sum_type is_sum_type := g.table.get_type_symbol(expected_deref_type).kind == .sum_type
if !((arg_typ_sym.kind == .function) || is_sum_type) { if !((arg_typ_sym.kind == .function) || is_sum_type) {
g.write('(voidptr)&/*qq*/') g.write('(voidptr)&/*qq*/')
} }

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) { pub fn (mut g JsGen) find_class_methods(stmts []ast.Stmt) {
for stmt in stmts { for stmt in stmts {
match union stmt { match 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.
@ -257,7 +257,7 @@ pub fn (mut g JsGen) typ(t table.Type) string {
joined := types.join(', ') joined := types.join(', ')
styp = '[$joined]' styp = '[$joined]'
} }
.union_sum_type { .sum_type {
// TODO: Implement sumtypes // TODO: Implement sumtypes
styp = 'union_sym_type' styp = 'union_sym_type'
} }
@ -433,7 +433,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 union node { match node {
ast.AssertStmt { ast.AssertStmt {
g.gen_assert_stmt(node) g.gen_assert_stmt(node)
} }
@ -519,7 +519,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
} }
fn (mut g JsGen) expr(node ast.Expr) { fn (mut g JsGen) expr(node ast.Expr) {
match union node { match node {
ast.CTempVar { ast.CTempVar {
g.write('/* ast.CTempVar: node.name */') g.write('/* ast.CTempVar: node.name */')
} }
@ -1004,7 +1004,7 @@ fn (mut g JsGen) gen_for_stmt(it ast.ForStmt) {
fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) { fn (mut g JsGen) gen_go_stmt(node ast.GoStmt) {
// x := node.call_expr as ast.CallEpxr // TODO // x := node.call_expr as ast.CallEpxr // TODO
match union node.call_expr { match node.call_expr {
ast.CallExpr { ast.CallExpr {
mut name := node.call_expr.name mut name := node.call_expr.name
if node.call_expr.is_method { if node.call_expr.is_method {
@ -1193,7 +1193,7 @@ fn (mut g JsGen) gen_call_expr(it ast.CallExpr) {
g.write(it.name) g.write(it.name)
g.write('(') g.write('(')
expr := node.args[0].expr expr := node.args[0].expr
match union expr { match expr {
ast.AnonFn { ast.AnonFn {
g.gen_fn_decl(expr.decl) g.gen_fn_decl(expr.decl)
g.write(')') g.write(')')
@ -1538,7 +1538,7 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) { fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) {
sym := g.table.get_type_symbol(it.expr_type) sym := g.table.get_type_symbol(it.expr_type)
if sym.kind == .union_sum_type { if sym.kind == .sum_type {
// TODO: JS sumtypes not implemented yet // TODO: JS sumtypes not implemented yet
} else if sym.kind == .array_fixed { } else if sym.kind == .array_fixed {
fixed_info := sym.info as table.ArrayFixed fixed_info := sym.info as table.ArrayFixed

View File

@ -256,7 +256,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr) {
// //
// TODO `where id = some_column + 1` needs literal generation of `some_column` as a string, // TODO `where id = some_column + 1` needs literal generation of `some_column` as a string,
// not a V variable. Need to distinguish column names from V variables. // not a V variable. Need to distinguish column names from V variables.
match union expr { match expr {
ast.InfixExpr { ast.InfixExpr {
g.sql_side = .left g.sql_side = .left
g.expr_to_sql(expr.left) g.expr_to_sql(expr.left)

View File

@ -479,7 +479,7 @@ pub fn (mut g Gen) save_main_fn_addr() {
} }
pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, newline bool) { pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, newline bool) {
match union expr { match expr {
ast.StringLiteral { ast.StringLiteral {
if newline { if newline {
g.gen_print(expr.val + '\n') g.gen_print(expr.val + '\n')
@ -575,7 +575,7 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
// g.mov(.eax, 0) // g.mov(.eax, 0)
for i in 0 .. node.args.len { for i in 0 .. node.args.len {
expr := node.args[i].expr expr := node.args[i].expr
match union expr { match expr {
ast.IntegerLiteral { ast.IntegerLiteral {
// `foo(2)` => `mov edi,0x2` // `foo(2)` => `mov edi,0x2`
g.mov(fn_arg_registers[i], expr.val.int()) g.mov(fn_arg_registers[i], expr.val.int())
@ -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 union node { match node {
ast.AssignStmt { ast.AssignStmt {
g.assign_stmt(node) g.assign_stmt(node)
} }
@ -648,7 +648,7 @@ fn C.strtol() int
fn (mut g Gen) expr(node ast.Expr) { fn (mut g Gen) expr(node ast.Expr) {
// println('cgen expr()') // println('cgen expr()')
match union node { match node {
ast.ArrayInit {} ast.ArrayInit {}
ast.BoolLiteral {} ast.BoolLiteral {}
ast.CallExpr { ast.CallExpr {
@ -719,7 +719,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
name := left.str() name := left.str()
// if left is ast.Ident { // if left is ast.Ident {
// ident := left as ast.Ident // ident := left as ast.Ident
match union right { match right {
ast.IntegerLiteral { ast.IntegerLiteral {
g.allocate_var(name, 4, right.val.int()) g.allocate_var(name, 4, right.val.int())
} }
@ -755,7 +755,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
if node.left is ast.InfixExpr { if node.left is ast.InfixExpr {
verror('only simple expressions are supported right now (not more than 2 operands)') verror('only simple expressions are supported right now (not more than 2 operands)')
} }
match union mut node.left { match mut node.left {
ast.Ident { g.mov_var_to_reg(.eax, g.get_var_offset(node.left.name)) } ast.Ident { g.mov_var_to_reg(.eax, g.get_var_offset(node.left.name)) }
else {} else {}
} }
@ -774,7 +774,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
branch := node.branches[0] branch := node.branches[0]
infix_expr := branch.cond as ast.InfixExpr infix_expr := branch.cond as ast.InfixExpr
mut jne_addr := 0 // location of `jne *00 00 00 00*` mut jne_addr := 0 // location of `jne *00 00 00 00*`
match union mut infix_expr.left { match mut infix_expr.left {
ast.Ident { ast.Ident {
lit := infix_expr.right as ast.IntegerLiteral lit := infix_expr.right as ast.IntegerLiteral
g.cmp_var(infix_expr.left.name, lit.val.int()) g.cmp_var(infix_expr.left.name, lit.val.int())
@ -797,7 +797,7 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
// g.mov(.eax, 0x77777777) // g.mov(.eax, 0x77777777)
mut jump_addr := 0 // location of `jne *00 00 00 00*` mut jump_addr := 0 // location of `jne *00 00 00 00*`
start := g.pos() start := g.pos()
match union mut infix_expr.left { match mut infix_expr.left {
ast.Ident { ast.Ident {
lit := infix_expr.right as ast.IntegerLiteral lit := infix_expr.right as ast.IntegerLiteral
g.cmp_var(infix_expr.left.name, lit.val.int()) g.cmp_var(infix_expr.left.name, lit.val.int())

View File

@ -12,7 +12,7 @@ fn (mut p Parser) assign_stmt() ast.Stmt {
} }
fn (mut p Parser) check_undefined_variables(exprs []ast.Expr, val ast.Expr) { fn (mut p Parser) check_undefined_variables(exprs []ast.Expr, val ast.Expr) {
match union val { match val {
ast.Ident { ast.Ident {
for expr in exprs { for expr in exprs {
if expr is ast.Ident { if expr is ast.Ident {
@ -46,7 +46,7 @@ fn (mut p Parser) check_undefined_variables(exprs []ast.Expr, val ast.Expr) {
fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool { fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool {
val_ := val val_ := val
match union val_ { match val_ {
ast.Ident { ast.Ident {
for expr in exprs { for expr in exprs {
if expr is ast.Ident { if expr is ast.Ident {
@ -113,7 +113,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
} }
mut is_static := false mut is_static := false
for i, lx in left { for i, lx in left {
match union mut lx { match mut lx {
ast.Ident { ast.Ident {
if op == .decl_assign { if op == .decl_assign {
if p.scope.known_var(lx.name) { if p.scope.known_var(lx.name) {

View File

@ -567,7 +567,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) { fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) {
sym := p.table.get_type_symbol(typ) sym := p.table.get_type_symbol(typ)
if sym.kind !in [.array, .struct_, .map, .placeholder, .union_sum_type] && !typ.is_ptr() { if sym.kind !in [.array, .struct_, .map, .placeholder, .sum_type] && !typ.is_ptr() {
p.error_with_pos('mutable arguments are only allowed for arrays, maps, and structs\n' + p.error_with_pos('mutable arguments are only allowed for arrays, maps, and structs\n' +
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`', 'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
pos) pos)

View File

@ -170,11 +170,6 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
match_first_pos := p.tok.position() match_first_pos := p.tok.position()
p.inside_match = true p.inside_match = true
p.check(.key_match) p.check(.key_match)
mut is_union_match := false
if p.tok.kind == .key_union {
p.check(.key_union)
is_union_match = true
}
is_mut := p.tok.kind == .key_mut is_mut := p.tok.kind == .key_mut
mut is_sum_type := false mut is_sum_type := false
if is_mut { if is_mut {
@ -287,7 +282,6 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
is_sum_type: is_sum_type is_sum_type: is_sum_type
pos: pos pos: pos
is_mut: is_mut is_mut: is_mut
is_union_match: is_union_match
} }
} }
@ -361,12 +355,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 union mut stmt { match 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 mut stmt.expr { match 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',
@ -382,7 +376,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
} }
ast.AssignStmt { ast.AssignStmt {
expr := stmt.right[0] expr := stmt.right[0]
match union expr { match expr {
ast.PrefixExpr { ast.PrefixExpr {
if expr.op != .arrow { if expr.op != .arrow {
p.error_with_pos('select key: `<-` operator expected', p.error_with_pos('select key: `<-` operator expected',

View File

@ -608,7 +608,7 @@ 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 union mut stmt { match mut stmt {
ast.ForStmt { ast.ForStmt {
stmt.label = name stmt.label = name
return stmt return stmt
@ -1933,16 +1933,16 @@ fn (mut p Parser) union_sum_type_decl() ast.TypeDecl {
} }
prepend_mod_name := p.prepend_mod(name) prepend_mod_name := p.prepend_mod(name)
p.table.register_type_symbol(table.TypeSymbol{ p.table.register_type_symbol(table.TypeSymbol{
kind: .union_sum_type kind: .sum_type
name: prepend_mod_name name: prepend_mod_name
source_name: prepend_mod_name source_name: prepend_mod_name
mod: p.mod mod: p.mod
info: table.UnionSumType{ info: table.SumType{
variants: sum_variants variants: sum_variants
} }
is_public: is_pub is_public: is_pub
}) })
return ast.UnionSumTypeDecl{ return ast.SumTypeDecl{
name: name name: name
is_pub: is_pub is_pub: is_pub
sub_types: sum_variants sub_types: sum_variants
@ -1999,17 +1999,17 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
} }
prepend_mod_name := p.prepend_mod(name) prepend_mod_name := p.prepend_mod(name)
p.table.register_type_symbol(table.TypeSymbol{ p.table.register_type_symbol(table.TypeSymbol{
kind: .union_sum_type kind: .sum_type
name: prepend_mod_name name: prepend_mod_name
source_name: prepend_mod_name source_name: prepend_mod_name
mod: p.mod mod: p.mod
info: table.UnionSumType{ info: table.SumType{
variants: sum_variants variants: sum_variants
} }
is_public: is_pub is_public: is_pub
}) })
comments = p.eat_lineend_comments() comments = p.eat_lineend_comments()
return ast.UnionSumTypeDecl{ return ast.SumTypeDecl{
name: name name: name
is_pub: is_pub is_pub: is_pub
sub_types: sum_variants sub_types: sum_variants
@ -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 union mut obj { match mut obj {
ast.Var { ast.Var {
obj.is_used = true obj.is_used = true
return true return true

View File

@ -129,7 +129,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
mut table_name := '' mut table_name := ''
if kind != .delete { if kind != .delete {
expr := p.expr(0) expr := p.expr(0)
match union expr { match expr {
ast.Ident { ast.Ident {
if kind == .insert { if kind == .insert {
inserted_var_name = expr.name inserted_var_name = expr.name

View File

@ -203,7 +203,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
// default_expr = p.tok.lit // default_expr = p.tok.lit
// p.expr(0) // p.expr(0)
default_expr = p.expr(0) default_expr = p.expr(0)
match union mut default_expr { match mut default_expr {
ast.EnumVal { default_expr.typ = typ } ast.EnumVal { default_expr.typ = typ }
// TODO: implement all types?? // TODO: implement all types??
else {} else {}

View File

@ -722,8 +722,8 @@ pub fn (mut table Table) register_fn_gen_type(fn_name string, typ Type) {
// so until fixed at least show v (not C) error `x(variant) = y(SumType*)` // so until fixed at least show v (not C) error `x(variant) = y(SumType*)`
pub fn (table &Table) sumtype_has_variant(parent Type, variant Type) bool { pub fn (table &Table) sumtype_has_variant(parent Type, variant Type) bool {
parent_sym := table.get_type_symbol(parent) parent_sym := table.get_type_symbol(parent)
if parent_sym.kind == .union_sum_type { if parent_sym.kind == .sum_type {
parent_info := parent_sym.info as UnionSumType parent_info := parent_sym.info as SumType
for v in parent_info.variants { for v in parent_info.variants {
if v.idx() == variant.idx() { if v.idx() == variant.idx() {
return true return true

View File

@ -15,8 +15,8 @@ import strings
pub type Type = int pub type Type = int
pub __type TypeInfo = Aggregate | Alias | Array | ArrayFixed | Chan | Enum | FnType | pub type TypeInfo = Aggregate | Alias | Array | ArrayFixed | Chan | Enum | FnType | GenericStructInst |
GenericStructInst | Interface | Map | MultiReturn | Struct | UnionSumType Interface | Map | MultiReturn | Struct | SumType
pub enum Language { pub enum Language {
v v
@ -404,7 +404,7 @@ pub enum Kind {
struct_ struct_
generic_struct_inst generic_struct_inst
multi_return multi_return
union_sum_type sum_type
alias alias
enum_ enum_
function function
@ -420,7 +420,7 @@ pub fn (t &TypeSymbol) str() string {
[inline] [inline]
pub fn (t &TypeSymbol) enum_info() Enum { pub fn (t &TypeSymbol) enum_info() Enum {
match union mut t.info { match mut t.info {
Enum { return t.info } 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') }
} }
@ -428,7 +428,7 @@ pub fn (t &TypeSymbol) enum_info() Enum {
[inline] [inline]
pub fn (t &TypeSymbol) mr_info() MultiReturn { pub fn (t &TypeSymbol) mr_info() MultiReturn {
match union mut t.info { match mut t.info {
MultiReturn { return t.info } 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') }
} }
@ -436,7 +436,7 @@ pub fn (t &TypeSymbol) mr_info() MultiReturn {
[inline] [inline]
pub fn (t &TypeSymbol) array_info() Array { pub fn (t &TypeSymbol) array_info() Array {
match union mut t.info { match mut t.info {
Array { return t.info } 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') }
} }
@ -444,7 +444,7 @@ pub fn (t &TypeSymbol) array_info() Array {
[inline] [inline]
pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed { pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
match union mut t.info { match mut t.info {
ArrayFixed { return t.info } 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') }
} }
@ -452,7 +452,7 @@ pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
[inline] [inline]
pub fn (t &TypeSymbol) chan_info() Chan { pub fn (t &TypeSymbol) chan_info() Chan {
match union mut t.info { match mut t.info {
Chan { return t.info } 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') }
} }
@ -460,7 +460,7 @@ pub fn (t &TypeSymbol) chan_info() Chan {
[inline] [inline]
pub fn (t &TypeSymbol) map_info() Map { pub fn (t &TypeSymbol) map_info() Map {
match union mut t.info { match mut t.info {
Map { return t.info } 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') }
} }
@ -468,7 +468,7 @@ pub fn (t &TypeSymbol) map_info() Map {
[inline] [inline]
pub fn (t &TypeSymbol) struct_info() Struct { pub fn (t &TypeSymbol) struct_info() Struct {
match union mut t.info { match mut t.info {
Struct { return t.info } 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') }
} }
@ -718,7 +718,7 @@ pub fn (k Kind) str() string {
.map { 'map' } .map { 'map' }
.chan { 'chan' } .chan { 'chan' }
.multi_return { 'multi_return' } .multi_return { 'multi_return' }
.union_sum_type { 'union_sum_type' } .sum_type { 'sum_type' }
.alias { 'alias' } .alias { 'alias' }
.enum_ { 'enum' } .enum_ { 'enum' }
.any { 'any' } .any { 'any' }
@ -788,7 +788,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:
@ -841,7 +841,7 @@ pub mut:
value_type Type value_type Type
} }
pub struct UnionSumType { pub struct SumType {
pub: pub:
variants []Type variants []Type
} }

View File

@ -1,6 +1,6 @@
__type Expr = IfExpr | IntegerLiteral type Expr = IfExpr | IntegerLiteral
__type Stmt = FnDecl | StructDecl type Stmt = FnDecl | StructDecl
__type Node = Expr | Stmt type Node = Expr | Stmt
struct FnDecl { struct FnDecl {
pos int pos int
@ -26,7 +26,7 @@ fn handle(e Expr) string {
if e is IntegerLiteral { if e is IntegerLiteral {
assert typeof(e.val) == 'string' assert typeof(e.val) == 'string'
} }
match union e { match e {
IntegerLiteral { IntegerLiteral {
assert e.val == '12' assert e.val == '12'
// assert e.val == '12' // TODO // assert e.val == '12' // TODO
@ -54,7 +54,7 @@ fn test_assignment_and_push() {
val: '111' val: '111'
} }
arr1 << expr arr1 << expr
match union arr1[0] { match arr1[0] {
IntegerLiteral { IntegerLiteral {
arr1 << arr1[0] arr1 << arr1[0]
// should ref/dereference on assignent be made automatic? // should ref/dereference on assignent be made automatic?
@ -66,7 +66,7 @@ fn test_assignment_and_push() {
} }
// Test moving structs between master/sub arrays // Test moving structs between master/sub arrays
__type Master = Sub1 | Sub2 type Master = Sub1 | Sub2
struct Sub1 { struct Sub1 {
mut: mut:
@ -95,7 +95,7 @@ fn test_converting_down() {
} }
mut res := []Sub2{cap: out.len} mut res := []Sub2{cap: out.len}
for d in out { for d in out {
match union d { match d {
Sub2 { res << d } Sub2 { res << d }
else {} else {}
} }
@ -127,9 +127,9 @@ fn test_nested_sumtype_selector() {
fn test_nested_sumtype_match_selector() { fn test_nested_sumtype_match_selector() {
c := NodeWrapper{Node(Expr(IfExpr{pos: 1}))} c := NodeWrapper{Node(Expr(IfExpr{pos: 1}))}
match union c.node { match c.node {
Expr { Expr {
match union c.node { match c.node {
IfExpr { IfExpr {
assert c.node.pos == 1 assert c.node.pos == 1
} }
@ -161,9 +161,9 @@ fn test_nested_sumtype() {
fn test_nested_sumtype_match() { fn test_nested_sumtype_match() {
c := Node(Expr(IfExpr{pos: 1})) c := Node(Expr(IfExpr{pos: 1}))
match union c { match c {
Expr { Expr {
match union c { match c {
IfExpr { IfExpr {
assert c.pos == 1 assert c.pos == 1
} }
@ -178,11 +178,11 @@ fn test_nested_sumtype_match() {
} }
} }
__type Abc = int | string type Abc = int | string
fn test_string_cast_to_sumtype() { fn test_string_cast_to_sumtype() {
a := Abc('test') a := Abc('test')
match union a { match a {
int { int {
assert false assert false
} }
@ -195,7 +195,7 @@ fn test_string_cast_to_sumtype() {
fn test_int_cast_to_sumtype() { fn test_int_cast_to_sumtype() {
// literal // literal
a := Abc(111) a := Abc(111)
match union a { match a {
int { int {
assert true assert true
} }
@ -206,7 +206,7 @@ fn test_int_cast_to_sumtype() {
// var // var
i := 111 i := 111
b := Abc(i) b := Abc(i)
match union b { match b {
int { int {
assert true assert true
} }
@ -217,10 +217,10 @@ fn test_int_cast_to_sumtype() {
} }
// TODO: change definition once types other than int and f64 (int, f64, etc) are supported in sumtype // TODO: change definition once types other than int and f64 (int, f64, etc) are supported in sumtype
__type Number = int | f64 type Number = int | f64
fn is_gt_simple(val string, dst Number) bool { fn is_gt_simple(val string, dst Number) bool {
match union dst { match dst {
int { int {
return val.int() > dst return val.int() > dst
} }
@ -232,9 +232,9 @@ fn is_gt_simple(val string, dst Number) bool {
fn is_gt_nested(val string, dst Number) bool { fn is_gt_nested(val string, dst Number) bool {
dst2 := dst dst2 := dst
match union dst { match dst {
int { int {
match union dst2 { match dst2 {
int { int {
return val.int() > dst return val.int() > dst
} }
@ -245,7 +245,7 @@ fn is_gt_nested(val string, dst Number) bool {
} }
} }
f64 { f64 {
match union dst2 { match dst2 {
f64 { f64 {
return dst < val.f64() return dst < val.f64()
} }
@ -259,7 +259,7 @@ fn is_gt_nested(val string, dst Number) bool {
} }
fn concat(val string, dst Number) string { fn concat(val string, dst Number) string {
match union dst { match dst {
int { int {
mut res := val + '(int)' mut res := val + '(int)'
res += dst.str() res += dst.str()
@ -274,7 +274,7 @@ fn concat(val string, dst Number) string {
} }
fn get_sum(val string, dst Number) f64 { fn get_sum(val string, dst Number) f64 {
match union dst { match dst {
int { int {
mut res := val.int() mut res := val.int()
res += dst res += dst
@ -288,8 +288,8 @@ fn get_sum(val string, dst Number) f64 {
} }
} }
__type Bar = string | Test type Bar = string | Test
__type Xyz = int | string type Xyz = int | string
struct Test { struct Test {
x string x string
@ -337,11 +337,11 @@ fn test_assignment() {
} }
} }
__type Inner = int | string type Inner = int | string
struct InnerStruct { struct InnerStruct {
x Inner x Inner
} }
__type Outer = string | InnerStruct type Outer = string | InnerStruct
fn test_nested_if_is() { fn test_nested_if_is() {
b := Outer(InnerStruct{Inner(0)}) b := Outer(InnerStruct{Inner(0)})
@ -352,7 +352,7 @@ fn test_nested_if_is() {
} }
} }
__type Expr3 = CallExpr | CTempVarExpr type Expr3 = CallExpr | CTempVarExpr
struct Expr3Wrapper { struct Expr3Wrapper {
mut: mut:
expr Expr3 expr Expr3
@ -408,7 +408,7 @@ mut:
name string name string
} }
__type Food = Milk | Eggs type Food = Milk | Eggs
struct FoodWrapper { struct FoodWrapper {
mut: mut:
@ -417,7 +417,7 @@ mut:
fn test_match_aggregate() { fn test_match_aggregate() {
f := Food(Milk{'test'}) f := Food(Milk{'test'})
match union f { match f {
Milk, Eggs { Milk, Eggs {
assert f.name == 'test' assert f.name == 'test'
} }
@ -426,7 +426,7 @@ fn test_match_aggregate() {
fn test_match_mut() { fn test_match_mut() {
mut f := Food(Milk{'test'}) mut f := Food(Milk{'test'})
match union mut f { match mut f {
Eggs { Eggs {
f.name = 'eggs' f.name = 'eggs'
assert f.name == 'eggs' assert f.name == 'eggs'
@ -440,7 +440,7 @@ fn test_match_mut() {
fn test_match_not_mut() { fn test_match_not_mut() {
mut f := Food(Milk{'test'}) mut f := Food(Milk{'test'})
match union f { match f {
Eggs { Eggs {
// only works without smartcast // only works without smartcast
assert f is Eggs assert f is Eggs
@ -470,7 +470,7 @@ fn test_if_not_mut() {
fn test_match_mut_selector() { fn test_match_mut_selector() {
mut f := FoodWrapper{Food(Milk{'test'})} mut f := FoodWrapper{Food(Milk{'test'})}
match union mut f.food { match mut f.food {
Eggs { Eggs {
f.food.name = 'eggs' f.food.name = 'eggs'
assert f.food.name == 'eggs' assert f.food.name == 'eggs'

View File

@ -121,7 +121,7 @@ pub enum Kind {
key_struct key_struct
key_true key_true
key_type key_type
key___type // __type key___type // type
key_typeof key_typeof
key_orelse key_orelse
key_union key_union

View File

@ -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 {}
@ -287,7 +287,7 @@ fn (mut p Parser) decode_string() ?Any {
continue continue
} }
else { return error('invalid backslash escape.') } else { return error('invalid backslash escape.') }
} }
if int(peek) == 85 { if int(peek) == 85 {
return error('unicode endpoints must be in lowercase `u`.') return error('unicode endpoints must be in lowercase `u`.')

View File

@ -7,9 +7,9 @@ import strings
fn write_value(v Any, i int, len int, mut wr strings.Builder) { fn write_value(v Any, i int, len int, mut wr strings.Builder) {
str := v.str() str := v.str()
if v is string { if v is string {
wr.write('"$str"') wr.write('"$str"')
} else { } else {
wr.write(str) wr.write(str)
} }
if i >= len-1 { return } if i >= len-1 { return }
@ -51,7 +51,7 @@ 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 union f { match f {
string { return f } string { return f }
int { return f.str() } int { return f.str() }
i64 { return f.str() } i64 { return f.str() }

View File

@ -79,7 +79,7 @@ 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 union f { match 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() }
@ -91,7 +91,7 @@ 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 union f { match 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() }
@ -103,7 +103,7 @@ 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 union f { match 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() }
@ -114,7 +114,7 @@ pub fn (f Any) f32() f32 {
// Use `Any` as a float. // Use `Any` as a float.
pub fn (f Any) f64() f64 { pub fn (f Any) f64() f64 {
match union f { match f {
int { return f } int { return f }
i64 { return f } i64 { return f }
f64 { return f } f64 { return f }
@ -138,7 +138,7 @@ 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 union f { match f {
bool { return f } bool { return f }
string { return f.bool() } string { return f.bool() }
else { return false } else { return false }