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

View File

@ -1,65 +1,109 @@
struct A{ struct A{
mut: mut:
val int val int
nums []int nums []int
} }
struct B{ struct B{
mut: mut:
a A a A
} }
struct C { struct C {
mut: mut:
b B b B
nums []int nums []int
aarr []A aarr []A
num int num int
} }
struct User { struct User {
name string name string
age int age int
} }
struct Foo { struct Foo {
@type string @type string
} }
fn test_struct_levels() { //We need to make sure that this compiles with all the reserved names.
mut c := C{} struct ReservedKeywords {
assert c.nums.len == 0 delete int
c.nums << 3 exit int
assert c.nums.len == 1 unix int
assert c.nums[0] == 3 error int
c.nums[0] = 4 malloc int
assert c.nums[0] == 4 calloc int
c.b.a.val = 34 free int
assert c.b.a.val == 34 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].repeat(0)
c.b.a.nums << 0 c.b.a.nums << 0
c.b.a.nums << 2 c.b.a.nums << 2
assert c.b.a.nums.len == 2 assert c.b.a.nums.len == 2
assert c.b.a.nums[0] == 0 assert c.b.a.nums[0] == 0
assert c.b.a.nums[1] == 2 assert c.b.a.nums[1] == 2
c.b.a.nums [0] = 7 c.b.a.nums [0] = 7
assert c.b.a.nums[0] == 7 assert c.b.a.nums[0] == 7
c.aarr << A{val:8} c.aarr << A{val:8}
assert c.aarr.len == 1 assert c.aarr.len == 1
assert c.aarr[0].val == 8 assert c.aarr[0].val == 8
c.num = 20 c.num = 20
assert c.num == 20 assert c.num == 20
c.aarr[0].val = 10 c.aarr[0].val = 10
assert c.aarr[0].val == 10 assert c.aarr[0].val == 10
} }
fn test_struct_str() { fn test_struct_str() {
u := User{'Bob', 30} u := User{'Bob', 30}
println(u) // make sure the struct is printable println(u) // make sure the struct is printable
// assert u.str() == '{name:"Bob", age:30}' // TODO // assert u.str() == '{name:"Bob", age:30}' // TODO
} }
fn test_at() { fn test_at() {
foo := Foo{ @type: 'test' } foo := Foo{ @type: 'test' }
println(foo.@type) 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.
}