From 5c79c0e743db1f37c6321f4130374ccd77fded13 Mon Sep 17 00:00:00 2001 From: lutherwenxu Date: Sat, 28 Sep 2019 19:13:09 +0800 Subject: [PATCH] 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. --- compiler/parser.v | 9 ++- compiler/tests/struct_test.v | 144 +++++++++++++++++++++++------------ 2 files changed, 99 insertions(+), 54 deletions(-) diff --git a/compiler/parser.v b/compiler/parser.v index eb299cd979..334677bc3a 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -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(',') diff --git a/compiler/tests/struct_test.v b/compiler/tests/struct_test.v index a55b263176..6ad3f7d60e 100644 --- a/compiler/tests/struct_test.v +++ b/compiler/tests/struct_test.v @@ -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. +}