1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast: use const empty_expr instead of fn empty_expr (thanks to Joe Conigliaro for the idea) (#15175)

This commit is contained in:
Delyan Angelov 2022-07-22 12:14:46 +03:00 committed by GitHub
parent c6aea659e3
commit e9809572b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 64 additions and 71 deletions

View File

@ -146,30 +146,23 @@ pub fn (cty ComptimeType) str() string {
}
}
pub struct EmptyExpr {
x int
}
pub fn empty_expr() Expr {
return EmptyExpr{}
}
pub type EmptyExpr = u8
pub struct EmptyStmt {
pub:
pos token.Pos
}
pub fn empty_stmt() Stmt {
return EmptyStmt{}
}
pub struct EmptyNode {
x int
pub:
pos token.Pos
}
pub fn empty_node() Node {
return EmptyNode{}
}
pub const empty_expr = Expr(EmptyExpr(0))
pub const empty_stmt = Stmt(EmptyStmt{})
pub const empty_node = Node(EmptyNode{})
// `{stmts}` or `unsafe {stmts}`
pub struct Block {

View File

@ -15,7 +15,7 @@ pub type ComptTimeConstValue = EmptyExpr
| u8
pub fn empty_comptime_const_expr() ComptTimeConstValue {
return EmptyExpr{}
return EmptyExpr(0)
}
pub fn (val ComptTimeConstValue) i8() ?i8 {

View File

@ -7,9 +7,9 @@ pub fn resolve_init(node StructInit, typ Type, t &Table) Expr {
mut has_len := false
mut has_cap := false
mut has_default := false
mut len_expr := empty_expr()
mut cap_expr := empty_expr()
mut default_expr := empty_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 {

View File

@ -1432,7 +1432,7 @@ pub fn (mut t Table) bitsize_to_type(bit_size int) Type {
if bit_size % 8 != 0 { // there is no way to do `i2131(32)` so this should never be reached
t.panic('compiler bug: bitsizes must be multiples of 8')
}
return new_type(t.find_or_register_array_fixed(u8_type, bit_size / 8, empty_expr()))
return new_type(t.find_or_register_array_fixed(u8_type, bit_size / 8, empty_expr))
}
}
}

View File

@ -3103,7 +3103,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.empty_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')

View File

@ -177,7 +177,7 @@ pub fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
}
}
if node.is_fixed {
idx := c.table.find_or_register_array_fixed(elem_type, node.exprs.len, ast.empty_expr())
idx := c.table.find_or_register_array_fixed(elem_type, node.exprs.len, ast.empty_expr)
if elem_type.has_flag(.generic) {
node.typ = ast.new_type(idx).set_flag(.generic)
} else {

View File

@ -411,7 +411,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.empty_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) {

View File

@ -272,7 +272,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
module_built: module_built
timers_should_print: timers_should_print
timers: util.new_timers(should_print: timers_should_print, label: 'global_cgen')
inner_loop: &ast.EmptyStmt{}
inner_loop: &ast.empty_stmt
field_data_type: ast.Type(table.find_type_idx('FieldData'))
is_cc_msvc: pref.ccompiler == 'msvc'
use_segfault_handler: !('no_segfault_handler' in pref.compile_defines || pref.os == .wasm32)
@ -576,7 +576,7 @@ fn cgen_process_one_file_cb(p &pool.PoolProcessor, idx int, wid int) &Gen {
should_print: global_g.timers_should_print
label: 'cgen_process_one_file_cb idx: $idx, wid: $wid'
)
inner_loop: &ast.EmptyStmt{}
inner_loop: &ast.empty_stmt
field_data_type: ast.Type(global_g.table.find_type_idx('FieldData'))
array_sort_fn: global_g.array_sort_fn
waiter_fns: global_g.waiter_fns
@ -3704,7 +3704,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.empty_expr()
mut timeout_expr := ast.empty_expr
mut exception_branch := -1
for j, branch in node.branches {
if branch.is_else {
@ -3727,7 +3727,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.empty_expr()
objs << ast.empty_expr
tmp_obj := g.new_tmp_var()
tmp_objs << tmp_obj
el_stype := g.typ(ast.mktyp(expr.right_type))

View File

@ -419,7 +419,7 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
if elem_sym.kind == .sum_type && left.sym.kind != .sum_type {
if node.left_type in elem_sym.sumtype_info().variants {
new_node_left := ast.CastExpr{
arg: ast.EmptyExpr{}
arg: ast.empty_expr
typ: elem_type
expr: node.left
expr_type: node.left_type
@ -439,7 +439,7 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
if elem_type_.sym.kind == .sum_type {
if node.left_type in elem_type_.sym.sumtype_info().variants {
new_node_left := ast.CastExpr{
arg: ast.EmptyExpr{}
arg: ast.empty_expr
typ: elem_type
expr: node.left
expr_type: node.left_type
@ -509,7 +509,7 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
if elem_type_.sym.kind == .sum_type {
if node.left_type in elem_type_.sym.sumtype_info().variants {
new_node_left := ast.CastExpr{
arg: ast.EmptyExpr{}
arg: ast.empty_expr
typ: elem_type
expr: node.left
expr_type: node.left_type

View File

@ -390,7 +390,7 @@ pub fn (mut f Gen) node_str(node ast.Node) string {
//=== General Stmt-related methods and helpers ===//
pub fn (mut f Gen) stmts(stmts []ast.Stmt) {
mut prev_stmt := if stmts.len > 0 { stmts[0] } else { ast.empty_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) {

View File

@ -210,7 +210,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
}
mut v := ast.Var{
name: lx.name
expr: if left.len == right.len { right[i] } else { ast.empty_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

View File

@ -21,7 +21,7 @@ fn (mut p Parser) array_init() ast.ArrayInit {
mut has_type := false
mut has_default := false
mut has_it := false
mut default_expr := ast.empty_expr()
mut default_expr := ast.empty_expr
if p.tok.kind == .rsbr {
last_pos = p.tok.pos()
// []typ => `[]` and `typ` must be on the same line
@ -125,8 +125,8 @@ fn (mut p Parser) array_init() ast.ArrayInit {
}
mut has_len := false
mut has_cap := false
mut len_expr := ast.empty_expr()
mut cap_expr := ast.empty_expr()
mut len_expr := ast.empty_expr
mut cap_expr := ast.empty_expr
if p.tok.kind == .lcbr && exprs.len == 0 && array_type != ast.void_type {
// `[]int{ len: 10, cap: 100}` syntax
p.next()

View File

@ -10,7 +10,7 @@ import v.token
pub fn (mut p Parser) expr(precedence int) ast.Expr {
return p.check_expr(precedence) or {
if token.is_decl(p.tok.kind) && p.disallow_declarations_in_script_mode() {
return ast.empty_expr()
return ast.empty_expr
}
p.error_with_pos('invalid expression: unexpected $p.tok', p.tok.pos())
}
@ -18,7 +18,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
pub fn (mut p Parser) check_expr(precedence int) ?ast.Expr {
p.trace_parser('expr($precedence)')
mut node := ast.empty_expr()
mut node := ast.empty_expr
is_stmt_ident := p.is_stmt_ident
p.is_stmt_ident = false
if !p.pref.is_fmt {
@ -509,7 +509,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
if p.inside_if_cond {
p.if_cond_comments << p.eat_comments()
}
mut right := ast.empty_expr()
mut right := ast.empty_expr
prev_expecting_type := p.expecting_type
if op in [.key_is, .not_is] {
p.expecting_type = true

View File

@ -120,7 +120,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
p.next()
array_decompose = true
}
mut expr := ast.empty_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('void_type', .short_syntax)

View File

@ -34,9 +34,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.empty_stmt()
mut init := ast.empty_stmt
mut cond := p.new_true_expr()
mut inc := ast.empty_stmt()
mut inc := ast.empty_stmt
mut has_init := false
mut has_cond := false
mut has_inc := false
@ -137,7 +137,7 @@ fn (mut p Parser) for_stmt() ast.Stmt {
// 0 .. 10
// start := p.tok.lit.int()
// TODO use RangeExpr
mut high_expr := ast.empty_expr()
mut high_expr := ast.empty_expr
mut is_range := false
if p.tok.kind == .dotdot {
is_range = true

View File

@ -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.empty_expr()
mut cond := ast.empty_expr
mut is_guard := false
// if guard `if x,y := opt() {`
@ -361,7 +361,7 @@ fn (mut p Parser) select_expr() ast.SelectExpr {
// final else
mut is_else := false
mut is_timeout := false
mut stmt := ast.empty_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',

View File

@ -698,7 +698,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt {
return p.comment_stmt()
}
else {
return p.other_stmts(ast.empty_stmt())
return p.other_stmts(ast.empty_stmt)
}
}
if p.should_abort {
@ -707,7 +707,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.empty_stmt()
return ast.empty_stmt
}
fn comptime_if_expr_contains_top_stmt(if_expr ast.IfExpr) bool {
@ -743,7 +743,7 @@ fn (mut p Parser) other_stmts(cur_stmt ast.Stmt) ast.Stmt {
p.open_scope()
mut stmts := []ast.Stmt{}
if cur_stmt != ast.empty_stmt() {
if cur_stmt != ast.empty_stmt {
stmts << cur_stmt
}
for p.tok.kind != .eof {
@ -1707,7 +1707,7 @@ fn (mut p Parser) parse_attr() ast.Attr {
mut name := ''
mut has_arg := false
mut arg := ''
mut comptime_cond := ast.empty_expr()
mut comptime_cond := ast.empty_expr
mut comptime_cond_opt := false
if p.tok.kind == .key_if {
kind = .comptime_define
@ -2191,7 +2191,7 @@ fn (mut p Parser) is_generic_cast() bool {
pub fn (mut p Parser) name_expr() ast.Expr {
prev_tok_kind := p.prev_tok.kind
mut node := ast.empty_expr()
mut node := ast.empty_expr
if p.expecting_type {
if p.tok.kind == .dollar {
node = p.parse_comptime_type()
@ -2249,7 +2249,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
chan_type := p.parse_chan_type()
elem_type_pos = elem_type_pos.extend(p.prev_tok.pos())
mut has_cap := false
mut cap_expr := ast.empty_expr()
mut cap_expr := ast.empty_expr
p.check(.lcbr)
if p.tok.kind == .rcbr {
last_pos = p.tok.pos()
@ -2380,8 +2380,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.empty_expr()
mut arg := ast.empty_expr()
mut expr := ast.empty_expr
mut arg := ast.empty_expr
mut has_arg := false
expr = p.expr(0)
// TODO, string(b, len)
@ -2505,7 +2505,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
typ: to_typ
typname: p.table.sym(to_typ).name
expr: expr
arg: ast.empty_expr()
arg: ast.empty_expr
has_arg: false
pos: start_pos.extend(end_pos)
}
@ -2535,7 +2535,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
has_low = false
// [..end]
p.next()
mut high := ast.empty_expr()
mut high := ast.empty_expr
mut has_high := false
if p.tok.kind != .rsbr {
high = p.expr(0)
@ -2564,7 +2564,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
left: left
pos: pos_high
index: ast.RangeExpr{
low: ast.empty_expr()
low: ast.empty_expr
high: high
has_high: has_high
pos: pos_high
@ -2590,7 +2590,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
left: left
pos: pos_high
index: ast.RangeExpr{
low: ast.empty_expr()
low: ast.empty_expr
high: high
has_high: has_high
pos: pos_high
@ -2610,7 +2610,7 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr {
if p.tok.kind == .dotdot {
// either [start..end] or [start..]
p.next()
mut high := ast.empty_expr()
mut high := ast.empty_expr
if p.tok.kind != .rsbr {
has_high = true
high = p.expr(0)
@ -2977,7 +2977,7 @@ fn (mut p Parser) string_expr() ast.Expr {
if is_raw || is_cstr {
p.next()
}
mut node := ast.empty_expr()
mut node := ast.empty_expr
val := p.tok.lit
mut pos := p.tok.pos()
pos.last_line = pos.line_nr + val.count('\n')
@ -3090,7 +3090,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.empty_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
@ -3498,7 +3498,7 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
pos := p.tok.pos()
name := p.check_name()
has_expr := p.tok.kind == .assign
mut expr := ast.empty_expr()
mut expr := ast.empty_expr
mut typ := ast.void_type
mut typ_pos := token.Pos{}
if has_expr {
@ -3596,7 +3596,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
pos := p.tok.pos()
val := p.check_name()
vals << val
mut expr := ast.empty_expr()
mut expr := ast.empty_expr
mut has_expr := false
// p.warn('enum val $val')
if p.tok.kind == .assign {

View File

@ -24,7 +24,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
}
table_pos := p.tok.pos()
table_type := p.parse_type() // `User`
mut where_expr := ast.empty_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 {
@ -47,11 +47,11 @@ fn (mut p Parser) sql_expr() ast.Expr {
}
}
mut has_limit := false
mut limit_expr := ast.empty_expr()
mut limit_expr := ast.empty_expr
mut has_offset := false
mut offset_expr := ast.empty_expr()
mut offset_expr := ast.empty_expr
mut has_order := false
mut order_expr := ast.empty_expr()
mut order_expr := ast.empty_expr
mut has_desc := false
if p.tok.kind == .name && p.tok.lit == 'order' {
p.check_name() // `order`
@ -232,7 +232,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
}
mut table_pos := p.tok.pos()
mut where_expr := ast.empty_expr()
mut where_expr := ast.empty_expr
if kind == .insert {
table_pos = p.tok.pos()
table_type = p.parse_type()

View File

@ -267,7 +267,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
}
}
}
mut default_expr := ast.empty_expr()
mut default_expr := ast.empty_expr
mut has_default_expr := false
if !is_embed {
if p.tok.kind == .assign {
@ -402,12 +402,12 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind) ast.Struc
no_keys := p.peek_tok.kind != .colon && p.tok.kind != .rcbr && p.tok.kind != .ellipsis // `Vec{a,b,c}
saved_is_amp := p.is_amp
p.is_amp = false
mut update_expr := ast.empty_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.empty_expr()
mut expr := ast.empty_expr
mut field_pos := token.Pos{}
mut first_field_pos := token.Pos{}
mut comments := []ast.Comment{}

View File

@ -374,7 +374,7 @@ pub fn (mut t Transformer) expr_stmt_if_expr(mut node ast.IfExpr) ast.Expr {
/*
FIXME: optimization causes cgen error `g.expr(): unhandled EmptyExpr`
if original.branches.len == 0 { // no remain branches to walk through
return ast.EmptyExpr{}
return ast.empty_expr
}*/
if node.branches.len == 1 && node.branches[0].cond.type_name() == 'unknown v.ast.Expr' {
node.branches[0].cond = ast.BoolLiteral{
@ -484,7 +484,7 @@ pub fn (mut t Transformer) for_stmt(mut node ast.ForStmt) ast.Stmt {
match node.cond {
ast.BoolLiteral {
if !(node.cond as ast.BoolLiteral).val { // for false { ... } should be eleminated
return ast.EmptyStmt{}
return ast.empty_stmt
}
}
else {