checker: do not allow nil sum types init
parent
dcab79146b
commit
6f318be96c
|
@ -0,0 +1,5 @@
|
|||
module builtin
|
||||
|
||||
struct string {
|
||||
len int
|
||||
}
|
|
@ -12,25 +12,25 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
|
|||
|
||||
pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr | BoolLiteral |
|
||||
CTempVar | CallExpr | CastExpr | ChanInit | CharLiteral | Comment | ComptimeCall |
|
||||
ComptimeSelector | ConcatExpr | DumpExpr | EnumVal | FloatLiteral | GoExpr | Ident |
|
||||
IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
|
||||
ComptimeSelector | ConcatExpr | DumpExpr | EmptyExpr | EnumVal | FloatLiteral | GoExpr |
|
||||
Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
|
||||
MapInit | MatchExpr | NodeError | None | OffsetOf | OrExpr | ParExpr | PostfixExpr |
|
||||
PrefixExpr | RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral |
|
||||
StringLiteral | StructInit | Type | TypeOf | UnsafeExpr
|
||||
|
||||
pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl |
|
||||
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl |
|
||||
GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | NodeError |
|
||||
Return | SqlStmt | StructDecl | TypeDecl
|
||||
DeferStmt | EmptyStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt |
|
||||
GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module |
|
||||
NodeError | Return | SqlStmt | StructDecl | TypeDecl
|
||||
|
||||
// NB: when you add a new Expr or Stmt type with a .pos field, remember to update
|
||||
// the .position() token.Position methods too.
|
||||
pub type ScopeObject = AsmRegister | ConstField | GlobalField | Var
|
||||
|
||||
// TOOD: replace table.Param
|
||||
// TODO: replace table.Param
|
||||
pub type Node = CallArg | ConstField | EnumField | Expr | Field | File | GlobalField |
|
||||
IfBranch | MatchBranch | ScopeObject | SelectBranch | Stmt | StructField | StructInitField |
|
||||
table.Param
|
||||
IfBranch | MatchBranch | NodeError | ScopeObject | SelectBranch | Stmt | StructField |
|
||||
StructInitField | table.Param
|
||||
|
||||
pub struct Type {
|
||||
pub:
|
||||
|
@ -38,6 +38,21 @@ pub:
|
|||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct EmptyExpr {}
|
||||
|
||||
pub fn empty_expr() Expr {
|
||||
return EmptyExpr{}
|
||||
}
|
||||
|
||||
pub struct EmptyStmt {
|
||||
pub:
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub fn empty_stmt() Stmt {
|
||||
return EmptyStmt{}
|
||||
}
|
||||
|
||||
// `{stmts}` or `unsafe {stmts}`
|
||||
pub struct Block {
|
||||
pub:
|
||||
|
@ -1431,6 +1446,10 @@ pub fn (expr Expr) position() token.Position {
|
|||
AnonFn {
|
||||
return expr.decl.pos
|
||||
}
|
||||
EmptyExpr {
|
||||
println('compiler bug, unhandled EmptyExpr position()')
|
||||
return token.Position{}
|
||||
}
|
||||
NodeError, ArrayDecompose, ArrayInit, AsCast, Assoc, AtExpr, BoolLiteral, CallExpr, CastExpr,
|
||||
ChanInit, CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr,
|
||||
FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit,
|
||||
|
@ -1540,6 +1559,9 @@ pub:
|
|||
|
||||
pub fn (node Node) position() token.Position {
|
||||
match node {
|
||||
NodeError {
|
||||
return token.Position{}
|
||||
}
|
||||
Stmt {
|
||||
mut pos := node.pos
|
||||
if node is Import {
|
||||
|
@ -1736,15 +1758,19 @@ pub fn (node Node) children() []Node {
|
|||
// a dependency cycle between v.ast and v.table, for the single
|
||||
// field table.Field.default_expr, which should be ast.Expr
|
||||
pub fn fe2ex(x table.FExpr) Expr {
|
||||
res := Expr{}
|
||||
unsafe { C.memcpy(&res, &x, sizeof(Expr)) }
|
||||
return res
|
||||
unsafe {
|
||||
res := Expr{}
|
||||
C.memcpy(&res, &x, sizeof(Expr))
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ex2fe(x Expr) table.FExpr {
|
||||
res := table.FExpr{}
|
||||
unsafe { C.memcpy(&res, &x, sizeof(table.FExpr)) }
|
||||
return res
|
||||
unsafe {
|
||||
res := table.FExpr{}
|
||||
C.memcpy(&res, &x, sizeof(table.FExpr))
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
// helper for dealing with `m[k1][k2][k3][k3] = value`
|
||||
|
|
|
@ -9,9 +9,9 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr {
|
|||
mut has_len := false
|
||||
mut has_cap := false
|
||||
mut has_default := false
|
||||
mut len_expr := Expr{}
|
||||
mut cap_expr := Expr{}
|
||||
mut default_expr := Expr{}
|
||||
mut len_expr := empty_expr()
|
||||
mut cap_expr := empty_expr()
|
||||
mut default_expr := empty_expr()
|
||||
mut exprs := []Expr{}
|
||||
for field in node.fields {
|
||||
match field.name {
|
||||
|
|
|
@ -469,6 +469,9 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
|||
utyp := c.unwrap_generic(struct_init.typ)
|
||||
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
||||
type_sym := c.table.get_type_symbol(utyp)
|
||||
if !c.inside_unsafe && type_sym.kind == .sum_type {
|
||||
c.warn('direct sum type init (`x := SumType{}`) will be removed soon', struct_init.pos)
|
||||
}
|
||||
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
||||
// but `x := T{}` is ok.
|
||||
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
||||
|
@ -3386,6 +3389,10 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
}
|
||||
// c.expected_type = table.void_type
|
||||
match mut node {
|
||||
ast.EmptyStmt {
|
||||
print_backtrace()
|
||||
eprintln('Checker.stmt() EmptyStmt')
|
||||
}
|
||||
ast.NodeError {}
|
||||
ast.AsmStmt {
|
||||
c.asm_stmt(mut node)
|
||||
|
@ -3532,9 +3539,13 @@ fn (mut c Checker) branch_stmt(node ast.BranchStmt) {
|
|||
fn (mut c Checker) for_c_stmt(node ast.ForCStmt) {
|
||||
c.in_for_count++
|
||||
prev_loop_label := c.loop_label
|
||||
c.stmt(node.init)
|
||||
if node.has_init {
|
||||
c.stmt(node.init)
|
||||
}
|
||||
c.expr(node.cond)
|
||||
c.stmt(node.inc)
|
||||
if node.has_inc {
|
||||
c.stmt(node.inc)
|
||||
}
|
||||
c.check_loop_label(node.label, node.pos)
|
||||
c.stmts(node.stmts)
|
||||
c.loop_label = prev_loop_label
|
||||
|
@ -3975,6 +3986,10 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||
}
|
||||
match mut node {
|
||||
ast.NodeError {}
|
||||
ast.EmptyExpr {
|
||||
print_backtrace()
|
||||
c.error('checker.expr(): unhandled EmptyExpr', token.Position{})
|
||||
}
|
||||
ast.CTempVar {
|
||||
return node.typ
|
||||
}
|
||||
|
@ -5567,7 +5582,7 @@ fn (mut c Checker) find_obj_definition(obj ast.ScopeObject) ?ast.Expr {
|
|||
match obj {
|
||||
ast.Var, ast.ConstField, ast.GlobalField, ast.AsmRegister { name = obj.name }
|
||||
}
|
||||
mut expr := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
if obj is ast.Var {
|
||||
if obj.is_mut {
|
||||
return error('`$name` is mut and may have changed since its definition')
|
||||
|
@ -6202,7 +6217,9 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type {
|
|||
c.expr(expr)
|
||||
}
|
||||
}
|
||||
c.expr(node.where_expr)
|
||||
if node.where_expr !is ast.EmptyExpr {
|
||||
c.expr(node.where_expr)
|
||||
}
|
||||
|
||||
return table.void_type
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
vlib/v/checker/tests/sum_type_assign_non_variant_err.vv:11:6: error: cannot assign to `w`: expected `Stmt`, not `IfExpr`
|
||||
9 | fn main() {
|
||||
10 | mut w := Stmt{}
|
||||
10 | mut w := Stmt(AnotherThing{})
|
||||
11 | w = IfExpr{}
|
||||
| ~~~~~~~~
|
||||
12 | }
|
|
@ -7,6 +7,6 @@ type Stmt = Expr | AnotherThing
|
|||
struct AnotherThing {}
|
||||
|
||||
fn main() {
|
||||
mut w := Stmt{}
|
||||
mut w := Stmt(AnotherThing{})
|
||||
w = IfExpr{}
|
||||
}
|
|
@ -365,7 +365,7 @@ pub fn (mut f Fmt) node_str(node ast.Node) string {
|
|||
//=== General Stmt-related methods and helpers ===//
|
||||
|
||||
pub fn (mut f Fmt) stmts(stmts []ast.Stmt) {
|
||||
mut prev_stmt := if stmts.len > 0 { stmts[0] } else { ast.Stmt{} }
|
||||
mut prev_stmt := if stmts.len > 0 { stmts[0] } else { ast.empty_stmt() }
|
||||
f.indent++
|
||||
for stmt in stmts {
|
||||
if !f.pref.building_v && f.should_insert_newline_before_node(stmt, prev_stmt) {
|
||||
|
@ -383,6 +383,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
|||
}
|
||||
match node {
|
||||
ast.NodeError {}
|
||||
ast.EmptyStmt {}
|
||||
ast.AsmStmt {
|
||||
f.asm_stmt(node)
|
||||
}
|
||||
|
@ -482,6 +483,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
|||
}
|
||||
match mut node {
|
||||
ast.NodeError {}
|
||||
ast.EmptyExpr {}
|
||||
ast.AnonFn {
|
||||
f.fn_decl(node.decl)
|
||||
}
|
||||
|
@ -897,7 +899,11 @@ pub fn (mut f Fmt) const_decl(node ast.ConstDecl) {
|
|||
}
|
||||
f.indent++
|
||||
}
|
||||
mut prev_field := if node.fields.len > 0 { ast.Node(node.fields[0]) } else { ast.Node{} }
|
||||
mut prev_field := if node.fields.len > 0 {
|
||||
ast.Node(node.fields[0])
|
||||
} else {
|
||||
ast.Node(ast.NodeError{})
|
||||
}
|
||||
for field in node.fields {
|
||||
if field.comments.len > 0 {
|
||||
if f.should_insert_newline_before_node(ast.Expr(field.comments[0]), prev_field) {
|
||||
|
|
|
@ -1010,6 +1010,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
// println('g.stmt()')
|
||||
// g.writeln('//// stmt start')
|
||||
match node {
|
||||
ast.EmptyStmt {}
|
||||
ast.AsmStmt {
|
||||
g.write_v_source_line_info(node.pos)
|
||||
g.gen_asm_stmt(node)
|
||||
|
@ -2789,6 +2790,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
}
|
||||
// NB: please keep the type names in the match here in alphabetical order:
|
||||
match mut node {
|
||||
ast.EmptyExpr {
|
||||
g.error('g.expr(): unhandled EmptyExpr', token.Position{})
|
||||
}
|
||||
ast.AnonFn {
|
||||
// TODO: dont fiddle with buffers
|
||||
g.gen_anon_fn_decl(mut node)
|
||||
|
@ -4158,7 +4162,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
mut is_push := []bool{cap: n_channels}
|
||||
mut has_else := false
|
||||
mut has_timeout := false
|
||||
mut timeout_expr := ast.Expr{}
|
||||
mut timeout_expr := ast.empty_expr()
|
||||
mut exception_branch := -1
|
||||
for j, branch in node.branches {
|
||||
if branch.is_else {
|
||||
|
@ -4182,7 +4186,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) {
|
|||
elem_types << ''
|
||||
} else {
|
||||
// must be evaluated to tmp var before real `select` is performed
|
||||
objs << ast.Expr{}
|
||||
objs << ast.empty_expr()
|
||||
tmp_obj := g.new_tmp_var()
|
||||
tmp_objs << tmp_obj
|
||||
el_stype := g.typ(g.table.mktyp(expr.right_type))
|
||||
|
@ -5283,6 +5287,14 @@ fn (mut g Gen) write_builtin_types() {
|
|||
for builtin_name in c.builtins {
|
||||
sym := g.table.type_symbols[g.table.type_idxs[builtin_name]]
|
||||
if sym.kind == .interface_ {
|
||||
if g.pref.is_verbose {
|
||||
println('XAXAXA $sym.name')
|
||||
if isnil(sym.info) {
|
||||
println('FFF')
|
||||
}
|
||||
println(sym.info)
|
||||
println(sym.kind)
|
||||
}
|
||||
g.write_interface_typesymbol_declaration(sym)
|
||||
} else {
|
||||
builtin_types << sym
|
||||
|
|
|
@ -356,6 +356,7 @@ fn (mut g JsGen) stmts(stmts []ast.Stmt) {
|
|||
fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||
g.stmt_start_pos = g.ns.out.len
|
||||
match node {
|
||||
ast.EmptyStmt{}
|
||||
ast.AsmStmt {
|
||||
panic('inline asm is not supported by js')
|
||||
}
|
||||
|
@ -447,6 +448,7 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
|||
fn (mut g JsGen) expr(node ast.Expr) {
|
||||
match node {
|
||||
ast.NodeError {}
|
||||
ast.EmptyExpr {}
|
||||
ast.CTempVar {
|
||||
g.write('/* ast.CTempVar: node.name */')
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) {
|
|||
|
||||
pub fn (mut w Walker) stmt(node ast.Stmt) {
|
||||
match mut node {
|
||||
ast.EmptyStmt {}
|
||||
ast.AsmStmt {
|
||||
w.asm_io(node.output)
|
||||
w.asm_io(node.input)
|
||||
|
@ -153,6 +154,9 @@ fn (mut w Walker) exprs(exprs []ast.Expr) {
|
|||
|
||||
fn (mut w Walker) expr(node ast.Expr) {
|
||||
match mut node {
|
||||
ast.EmptyExpr {
|
||||
panic('Walker: EmptyExpr')
|
||||
}
|
||||
ast.AnonFn {
|
||||
w.fn_decl(mut node.decl)
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
|||
r0 := right[0]
|
||||
mut v := ast.Var{
|
||||
name: lx.name
|
||||
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
||||
expr: if left.len == right.len { right[i] } else { ast.empty_expr() }
|
||||
share: share
|
||||
is_mut: lx.is_mut || p.inside_for
|
||||
pos: lx.pos
|
||||
|
|
|
@ -21,7 +21,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
mut has_val := false
|
||||
mut has_type := false
|
||||
mut has_default := false
|
||||
mut default_expr := ast.Expr{}
|
||||
mut default_expr := ast.empty_expr()
|
||||
if p.tok.kind == .rsbr {
|
||||
last_pos = p.tok.position()
|
||||
// []typ => `[]` and `typ` must be on the same line
|
||||
|
@ -103,8 +103,8 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
|||
}
|
||||
mut has_len := false
|
||||
mut has_cap := false
|
||||
mut len_expr := ast.Expr{}
|
||||
mut cap_expr := ast.Expr{}
|
||||
mut len_expr := ast.empty_expr()
|
||||
mut cap_expr := ast.empty_expr()
|
||||
if p.tok.kind == .lcbr && exprs.len == 0 && array_type != table.void_type {
|
||||
// `[]int{ len: 10, cap: 100}` syntax
|
||||
p.next()
|
||||
|
|
|
@ -129,7 +129,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
|
|||
p.next()
|
||||
array_decompose = true
|
||||
}
|
||||
mut expr := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
if p.tok.kind == .name && p.peek_tok.kind == .colon {
|
||||
// `foo(key:val, key2:val2)`
|
||||
expr = p.struct_init(true) // short_syntax:true
|
||||
|
|
|
@ -35,9 +35,9 @@ fn (mut p Parser) for_stmt() ast.Stmt {
|
|||
if p.tok.kind == .key_mut {
|
||||
return p.error('`mut` is not needed in `for ;;` loops: use `for i := 0; i < n; i ++ {`')
|
||||
}
|
||||
mut init := ast.Stmt{}
|
||||
mut init := ast.empty_stmt()
|
||||
mut cond := p.new_true_expr()
|
||||
mut inc := ast.Stmt{}
|
||||
mut inc := ast.empty_stmt()
|
||||
mut has_init := false
|
||||
mut has_cond := false
|
||||
mut has_inc := false
|
||||
|
@ -136,7 +136,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
|
|||
// 0 .. 10
|
||||
// start := p.tok.lit.int()
|
||||
// TODO use RangeExpr
|
||||
mut high_expr := ast.Expr{}
|
||||
mut high_expr := ast.empty_expr()
|
||||
mut is_range := false
|
||||
if p.tok.kind == .dotdot {
|
||||
is_range = true
|
||||
|
|
|
@ -79,7 +79,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
|
|||
return ast.IfExpr{}
|
||||
}
|
||||
comments << p.eat_comments({})
|
||||
mut cond := ast.Expr{}
|
||||
mut cond := ast.empty_expr()
|
||||
mut is_guard := false
|
||||
// `if x := opt() {`
|
||||
if !is_comptime && p.peek_tok.kind == .decl_assign {
|
||||
|
@ -290,7 +290,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
|
|||
// final else
|
||||
mut is_else := false
|
||||
mut is_timeout := false
|
||||
mut stmt := ast.Stmt{}
|
||||
mut stmt := ast.empty_stmt()
|
||||
if p.tok.kind == .key_else {
|
||||
if has_timeout {
|
||||
p.error_with_pos('timeout `> t` and `else` are mutually exclusive `select` keys',
|
||||
|
|
|
@ -597,7 +597,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
|
|||
}
|
||||
// TODO remove dummy return statement
|
||||
// the compiler complains if it's not there
|
||||
return ast.Stmt{}
|
||||
return ast.empty_stmt()
|
||||
}
|
||||
|
||||
// TODO [if vfmt]
|
||||
|
@ -1757,7 +1757,7 @@ fn (p &Parser) is_generic_call() bool {
|
|||
|
||||
pub fn (mut p Parser) name_expr() ast.Expr {
|
||||
prev_tok_kind := p.prev_tok.kind
|
||||
mut node := ast.Expr{}
|
||||
mut node := ast.empty_expr()
|
||||
if p.expecting_type {
|
||||
p.expecting_type = false
|
||||
// get type position before moving to next
|
||||
|
@ -1801,7 +1801,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
|||
mut last_pos := first_pos
|
||||
chan_type := p.parse_chan_type()
|
||||
mut has_cap := false
|
||||
mut cap_expr := ast.Expr{}
|
||||
mut cap_expr := ast.empty_expr()
|
||||
p.check(.lcbr)
|
||||
if p.tok.kind == .rcbr {
|
||||
last_pos = p.tok.position()
|
||||
|
@ -1910,8 +1910,8 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
|||
// without the next line int would result in int*
|
||||
p.is_amp = false
|
||||
p.check(.lpar)
|
||||
mut expr := ast.Expr{}
|
||||
mut arg := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
mut arg := ast.empty_expr()
|
||||
mut has_arg := false
|
||||
expr = p.expr(0)
|
||||
// TODO, string(b, len)
|
||||
|
@ -2013,7 +2013,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
left: left
|
||||
pos: pos
|
||||
index: ast.RangeExpr{
|
||||
low: ast.Expr{}
|
||||
low: ast.empty_expr()
|
||||
high: high
|
||||
has_high: true
|
||||
pos: pos
|
||||
|
@ -2025,7 +2025,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
if p.tok.kind == .dotdot {
|
||||
// [start..end] or [start..]
|
||||
p.next()
|
||||
mut high := ast.Expr{}
|
||||
mut high := ast.empty_expr()
|
||||
if p.tok.kind != .rsbr {
|
||||
has_high = true
|
||||
high = p.expr(0)
|
||||
|
@ -2263,7 +2263,7 @@ fn (mut p Parser) string_expr() ast.Expr {
|
|||
if is_raw || is_cstr {
|
||||
p.next()
|
||||
}
|
||||
mut node := ast.Expr{}
|
||||
mut node := ast.empty_expr()
|
||||
val := p.tok.lit
|
||||
pos := p.tok.position()
|
||||
if p.peek_tok.kind != .str_dollar {
|
||||
|
@ -2372,7 +2372,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr {
|
|||
}
|
||||
lit := p.tok.lit
|
||||
full_lit := if is_neg { '-' + lit } else { lit }
|
||||
mut node := ast.Expr{}
|
||||
mut node := ast.empty_expr()
|
||||
if lit.index_any('.eE') >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] {
|
||||
node = ast.FloatLiteral{
|
||||
val: full_lit
|
||||
|
@ -2714,7 +2714,7 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
|
|||
p.error('global assign must have the type around the value, use `__global ( name = type(value) )`')
|
||||
return ast.GlobalDecl{}
|
||||
}
|
||||
mut expr := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
if has_expr {
|
||||
if p.tok.kind != .lpar {
|
||||
p.error('global assign must have a type and value, use `__global ( name = type(value) )` or `__global ( name type )`')
|
||||
|
@ -2769,7 +2769,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
|||
pos := p.tok.position()
|
||||
val := p.check_name()
|
||||
vals << val
|
||||
mut expr := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
mut has_expr := false
|
||||
// p.warn('enum val $val')
|
||||
if p.tok.kind == .assign {
|
||||
|
@ -2854,7 +2854,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
if name.len == 1 && name[0].is_capital() {
|
||||
p.error_with_pos('single letter capital names are reserved for generic template types.',
|
||||
decl_pos)
|
||||
return ast.TypeDecl{}
|
||||
return ast.FnTypeDecl{}
|
||||
}
|
||||
mut sum_variants := []ast.SumTypeVariant{}
|
||||
p.check(.assign)
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
eprintln('parsing file: ${p.file_name:-30} | tok.kind: ${p.tok.kind:-10} | tok.lit: ${p.tok.lit:-10} | tok_pos: ${tok_pos.str():-45} | expr($precedence)')
|
||||
}
|
||||
// println('\n\nparser.expr()')
|
||||
mut node := ast.Expr{}
|
||||
mut node := ast.empty_expr()
|
||||
is_stmt_ident := p.is_stmt_ident
|
||||
p.is_stmt_ident = false
|
||||
if !p.pref.is_fmt {
|
||||
|
@ -439,7 +439,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
|
|||
precedence := p.tok.precedence()
|
||||
mut pos := p.tok.position()
|
||||
p.next()
|
||||
mut right := ast.Expr{}
|
||||
mut right := ast.empty_expr()
|
||||
prev_expecting_type := p.expecting_type
|
||||
if op in [.key_is, .not_is] {
|
||||
p.expecting_type = true
|
||||
|
|
|
@ -22,7 +22,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
|||
}
|
||||
table_pos := p.tok.position()
|
||||
table_type := p.parse_type() // `User`
|
||||
mut where_expr := ast.Expr{}
|
||||
mut where_expr := ast.empty_expr()
|
||||
has_where := p.tok.kind == .name && p.tok.lit == 'where'
|
||||
mut query_one := false // one object is returned, not an array
|
||||
if has_where {
|
||||
|
@ -40,11 +40,11 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
|||
}
|
||||
}
|
||||
mut has_limit := false
|
||||
mut limit_expr := ast.Expr{}
|
||||
mut limit_expr := ast.empty_expr()
|
||||
mut has_offset := false
|
||||
mut offset_expr := ast.Expr{}
|
||||
mut offset_expr := ast.empty_expr()
|
||||
mut has_order := false
|
||||
mut order_expr := ast.Expr{}
|
||||
mut order_expr := ast.empty_expr()
|
||||
mut has_desc := false
|
||||
if p.tok.kind == .name && p.tok.lit == 'order' {
|
||||
p.check_name() // `order`
|
||||
|
@ -172,7 +172,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
|||
}
|
||||
|
||||
mut table_pos := p.tok.position()
|
||||
mut where_expr := ast.Expr{}
|
||||
mut where_expr := ast.empty_expr()
|
||||
if kind == .insert {
|
||||
table_pos = p.tok.position()
|
||||
table_type = p.parse_type()
|
||||
|
|
|
@ -239,7 +239,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
|
|||
// attrs are stored in `p.attrs`
|
||||
p.attributes()
|
||||
}
|
||||
mut default_expr := ast.Expr{}
|
||||
mut default_expr := ast.empty_expr()
|
||||
mut has_default_expr := false
|
||||
if !is_embed {
|
||||
if p.tok.kind == .assign {
|
||||
|
@ -352,12 +352,12 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
|
|||
// p.warn(is_short_syntax.str())
|
||||
saved_is_amp := p.is_amp
|
||||
p.is_amp = false
|
||||
mut update_expr := ast.Expr{}
|
||||
mut update_expr := ast.empty_expr()
|
||||
mut update_expr_comments := []ast.Comment{}
|
||||
mut has_update_expr := false
|
||||
for p.tok.kind !in [.rcbr, .rpar, .eof] {
|
||||
mut field_name := ''
|
||||
mut expr := ast.Expr{}
|
||||
mut expr := ast.empty_expr()
|
||||
mut field_pos := token.Position{}
|
||||
mut first_field_pos := token.Position{}
|
||||
mut comments := []ast.Comment{}
|
||||
|
|
Loading…
Reference in New Issue