compiler: enforce reserved keywords replacement

* compiler: Enforce reserved keywords replacement on empty value initialization

* compiler: Add test for reserved keywords enforcement

A new struct has been introduced in the tests that contains all C reserved keywords that are not reserved in V. Some read and write are tested too.
pull/2148/head
lutherwenxu 2019-09-28 19:13:09 +08:00 committed by Alexander Medvednikov
parent fd2d9c214c
commit 5c79c0e743
2 changed files with 99 additions and 54 deletions

View File

@ -3029,9 +3029,10 @@ fn (p mut Parser) struct_init(typ string) string {
}
// Zero values: init all fields (ints to 0, strings to '' etc)
for i, field in t.fields {
sanitized_name := if typ != 'Option' { p.table.var_cgen_name( field.name ) } else { field.name }
// println('### field.name')
// Skip if this field has already been assigned to
if field.name in inited_fields {
if sanitized_name in inited_fields {
continue
}
field_typ := field.typ
@ -3040,9 +3041,9 @@ fn (p mut Parser) struct_init(typ string) string {
}
// init map fields
if field_typ.starts_with('map_') {
p.gen_struct_field_init(field.name)
p.gen_struct_field_init(sanitized_name)
p.gen_empty_map(field_typ.right(4))
inited_fields << field.name
inited_fields << sanitized_name
if i != t.fields.len - 1 {
p.gen(',')
}
@ -3051,7 +3052,7 @@ fn (p mut Parser) struct_init(typ string) string {
}
def_val := type_default(field_typ)
if def_val != '' && def_val != '{0}' {
p.gen_struct_field_init(field.name)
p.gen_struct_field_init(sanitized_name)
p.gen(def_val)
if i != t.fields.len - 1 {
p.gen(',')

View File

@ -1,65 +1,109 @@
struct A{
mut:
val int
nums []int
}
mut:
val int
nums []int
}
struct B{
mut:
a A
}
mut:
a A
}
struct C {
mut:
b B
nums []int
aarr []A
num int
}
mut:
b B
nums []int
aarr []A
num int
}
struct User {
name string
age int
}
age int
}
struct Foo {
@type string
}
fn test_struct_levels() {
mut c := C{}
assert c.nums.len == 0
c.nums << 3
assert c.nums.len == 1
assert c.nums[0] == 3
c.nums[0] = 4
assert c.nums[0] == 4
c.b.a.val = 34
assert c.b.a.val == 34
@type string
}
//We need to make sure that this compiles with all the reserved names.
struct ReservedKeywords {
delete int
exit int
unix int
error int
malloc int
calloc int
free int
panic int
auto int
char int
do int
double int
extern int
float int
inline int
long int
register int
restrict int
short int
signed int
typedef int
unsigned int
void int
volatile int
while int
}
fn test_struct_levels() {
mut c := C{}
assert c.nums.len == 0
c.nums << 3
assert c.nums.len == 1
assert c.nums[0] == 3
c.nums[0] = 4
assert c.nums[0] == 4
c.b.a.val = 34
assert c.b.a.val == 34
c.b.a.nums = [0].repeat(0)
c.b.a.nums << 0
c.b.a.nums << 2
assert c.b.a.nums.len == 2
assert c.b.a.nums[0] == 0
assert c.b.a.nums[1] == 2
c.b.a.nums [0] = 7
assert c.b.a.nums[0] == 7
c.aarr << A{val:8}
assert c.aarr.len == 1
assert c.aarr[0].val == 8
c.num = 20
assert c.num == 20
c.aarr[0].val = 10
assert c.aarr[0].val == 10
}
c.b.a.nums << 0
c.b.a.nums << 2
assert c.b.a.nums.len == 2
assert c.b.a.nums[0] == 0
assert c.b.a.nums[1] == 2
c.b.a.nums [0] = 7
assert c.b.a.nums[0] == 7
c.aarr << A{val:8}
assert c.aarr.len == 1
assert c.aarr[0].val == 8
c.num = 20
assert c.num == 20
c.aarr[0].val = 10
assert c.aarr[0].val == 10
}
fn test_struct_str() {
u := User{'Bob', 30}
println(u) // make sure the struct is printable
// assert u.str() == '{name:"Bob", age:30}' // TODO
}
u := User{'Bob', 30}
println(u) // make sure the struct is printable
// assert u.str() == '{name:"Bob", age:30}' // TODO
}
fn test_at() {
foo := Foo{ @type: 'test' }
println(foo.@type)
}
foo := Foo{ @type: 'test' }
println(foo.@type)
}
fn test_reserved_keywords() {
//Make sure we can initialize them correctly using full syntax.
rk_holder := ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}
//Test a few as it'll take too long to test all. If it's initialized
//correctly, other fields are also probably valid.
assert rk_holder.unix == 5
assert rk_holder.while == 3
rk_holder2 := ReservedKeywords{inline: 9, volatile: 11}
//Make sure partial initialization works too.
assert rk_holder2.inline == 9
assert rk_holder2.volatile == 11
assert rk_holder2.while == 0 //Zero value as not specified.
}