parser: fix enum default value in struct
* parser: fix enum default value in struct * Add a test for the enum default values in structs. * Fix compilation of vfmt. * Run vfmt over enum_default_value_in_struct_test.v * Cleanup spurious , in vfmt output for enum declarations Co-authored-by: Delyan Angelov <delian66@gmail.com>pull/4364/head
parent
0ced7116b6
commit
79dad0bca9
|
@ -144,7 +144,6 @@ fn main() {
|
|||
}
|
||||
exit(1)
|
||||
}
|
||||
println('vfmt done')
|
||||
}
|
||||
|
||||
fn (foptions &FormatOptions) format_file(file string) {
|
||||
|
|
|
@ -101,13 +101,14 @@ pub:
|
|||
|
||||
pub struct StructField {
|
||||
pub:
|
||||
name string
|
||||
pos token.Position
|
||||
comment Comment
|
||||
default_expr string // token literal //Expr
|
||||
attr string
|
||||
name string
|
||||
pos token.Position
|
||||
comment Comment
|
||||
default_expr Expr
|
||||
has_default_expr bool
|
||||
attr string
|
||||
mut:
|
||||
typ table.Type
|
||||
typ table.Type
|
||||
}
|
||||
|
||||
pub struct Field {
|
||||
|
|
|
@ -136,6 +136,9 @@ pub fn (x Expr) str() string {
|
|||
TypeOf {
|
||||
return 'typeof(${it.expr.str()})'
|
||||
}
|
||||
EnumVal {
|
||||
return '.${it.val}'
|
||||
}
|
||||
CallExpr {
|
||||
sargs := args2str(it.args)
|
||||
if it.is_method {
|
||||
|
|
|
@ -216,10 +216,8 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
|||
if field.has_expr {
|
||||
f.write(' = ')
|
||||
f.expr(field.expr)
|
||||
f.writeln(',')
|
||||
} else {
|
||||
f.writeln('')
|
||||
}
|
||||
f.writeln('')
|
||||
}
|
||||
f.writeln('}\n')
|
||||
}
|
||||
|
@ -407,8 +405,8 @@ fn (f mut Fmt) struct_decl(node ast.StructDecl) {
|
|||
f.write('\t$field.name ')
|
||||
f.write(strings.repeat(` `, max - field.name.len))
|
||||
f.write(f.type_to_str(field.typ))
|
||||
if field.default_expr != '' {
|
||||
f.write(' = $field.default_expr')
|
||||
if field.has_default_expr {
|
||||
f.write(' = ${field.default_expr.str()}')
|
||||
}
|
||||
// f.write('// $field.pos.line_nr')
|
||||
if field.comment.text != '' && field.comment.pos.line_nr == field.pos.line_nr {
|
||||
|
|
|
@ -1077,10 +1077,9 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
g.write("'$it.val'")
|
||||
}
|
||||
ast.EnumVal {
|
||||
// g.write('/*EnumVal*/${it.mod}${it.enum_name}_$it.val')
|
||||
// g.write('${it.mod}${it.enum_name}_$it.val')
|
||||
styp := g.typ(it.typ)
|
||||
g.write(styp)
|
||||
g.write('_$it.val')
|
||||
g.write('${styp}_$it.val')
|
||||
}
|
||||
ast.FloatLiteral {
|
||||
g.write(it.val)
|
||||
|
@ -1971,17 +1970,17 @@ fn (g mut Gen) const_decl_simple_define(name, val string) {
|
|||
g.definitions.writeln(val)
|
||||
}
|
||||
|
||||
fn (g mut Gen) struct_init(it ast.StructInit) {
|
||||
fn (g mut Gen) struct_init(struct_init ast.StructInit) {
|
||||
mut info := table.Struct{}
|
||||
mut is_struct := false
|
||||
sym := g.table.get_type_symbol(it.typ)
|
||||
sym := g.table.get_type_symbol(struct_init.typ)
|
||||
if sym.kind == .struct_ {
|
||||
is_struct = true
|
||||
info = sym.info as table.Struct
|
||||
}
|
||||
// info := g.table.get_type_symbol(it.typ).info as table.Struct
|
||||
// println(info.fields.len)
|
||||
styp := g.typ(it.typ)
|
||||
styp := g.typ(struct_init.typ)
|
||||
is_amp := g.is_amp
|
||||
if is_amp {
|
||||
g.out.go_back(1) // delete the & already generated in `prefix_expr()
|
||||
|
@ -1991,20 +1990,20 @@ fn (g mut Gen) struct_init(it ast.StructInit) {
|
|||
}
|
||||
mut fields := []string
|
||||
mut inited_fields := []string // TODO this is done in checker, move to ast node
|
||||
if it.fields.len == 0 && it.exprs.len > 0 {
|
||||
if struct_init.fields.len == 0 && struct_init.exprs.len > 0 {
|
||||
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
||||
for f in info.fields {
|
||||
fields << f.name
|
||||
}
|
||||
} else {
|
||||
fields = it.fields
|
||||
fields = struct_init.fields
|
||||
}
|
||||
// / User set fields
|
||||
// User set fields
|
||||
for i, field in fields {
|
||||
field_name := c_name(field)
|
||||
inited_fields << field
|
||||
g.write('\t.$field_name = ')
|
||||
g.expr_with_cast(it.exprs[i], it.expr_types[i], it.expected_types[i])
|
||||
g.expr_with_cast(struct_init.exprs[i], struct_init.expr_types[i], struct_init.expected_types[i])
|
||||
g.writeln(',')
|
||||
}
|
||||
// The rest of the fields are zeroed.
|
||||
|
@ -2018,11 +2017,16 @@ fn (g mut Gen) struct_init(it ast.StructInit) {
|
|||
continue
|
||||
}
|
||||
field_name := c_name(field.name)
|
||||
zero := if field.default_val != '' { field.default_val } else { g.type_default(field.typ) }
|
||||
g.writeln('\t.$field_name = $zero,') // zer0')
|
||||
if field.has_default_expr {
|
||||
g.expr(field.default_expr)
|
||||
g.writeln(',')
|
||||
} else {
|
||||
zero := g.type_default(field.typ)
|
||||
g.writeln('\t.$field_name = $zero,')
|
||||
}
|
||||
}
|
||||
}
|
||||
if it.fields.len == 0 && info.fields.len == 0 {
|
||||
if struct_init.fields.len == 0 && info.fields.len == 0 {
|
||||
g.write('0')
|
||||
}
|
||||
g.write('}')
|
||||
|
|
|
@ -1555,13 +1555,20 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
|||
println('XXXX' + s.str())
|
||||
}
|
||||
*/
|
||||
mut default_expr := '' // ast.Expr{}
|
||||
mut default_expr := ast.Expr{}
|
||||
mut has_default_expr := false
|
||||
if p.tok.kind == .assign {
|
||||
// Default value
|
||||
p.next()
|
||||
default_expr = p.tok.lit
|
||||
p.expr(0)
|
||||
// default_expr = p.expr(0)
|
||||
// default_expr = p.tok.lit
|
||||
// p.expr(0)
|
||||
default_expr = p.expr(0)
|
||||
match default_expr {
|
||||
ast.EnumVal { it.typ = typ }
|
||||
// TODO: implement all types??
|
||||
else {}
|
||||
}
|
||||
has_default_expr = true
|
||||
}
|
||||
if p.tok.kind == .comment {
|
||||
comment = p.comment()
|
||||
|
@ -1572,11 +1579,13 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
|||
typ: typ
|
||||
comment: comment
|
||||
default_expr: default_expr
|
||||
has_default_expr: has_default_expr
|
||||
}
|
||||
fields << table.Field{
|
||||
name: field_name
|
||||
typ: typ
|
||||
default_val: default_expr
|
||||
default_expr: default_expr
|
||||
has_default_expr: has_default_expr
|
||||
}
|
||||
// println('struct field $ti.name $field_name')
|
||||
}
|
||||
|
|
|
@ -559,6 +559,8 @@ pub:
|
|||
name string
|
||||
mut:
|
||||
typ Type
|
||||
default_expr ast.Expr
|
||||
has_default_expr bool
|
||||
default_val string
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
pub enum MyEnum {
|
||||
first = 20
|
||||
second
|
||||
third
|
||||
}
|
||||
|
||||
pub struct MyStruct {
|
||||
mut:
|
||||
e MyEnum = .second
|
||||
}
|
||||
|
||||
fn test_enum_first_value() {
|
||||
assert MyEnum.first == 20
|
||||
}
|
||||
|
||||
fn test_enum_default_value() {
|
||||
d := MyStruct{}
|
||||
assert int(d.e) == 21
|
||||
assert 'd.e: $d.e | int(d.e): ${int(d.e).str()}' == 'd.e: second | int(d.e): 21'
|
||||
}
|
||||
|
||||
fn test_enum_non_default_value() {
|
||||
t := MyStruct{
|
||||
e: .third
|
||||
}
|
||||
assert int(t.e) == 22
|
||||
assert 't.e: $t.e | int(t.e): ${int(t.e).str()}' == 't.e: third | int(t.e): 22'
|
||||
}
|
Loading…
Reference in New Issue