diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 43c611d74..1037fc3a7 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1000,6 +1000,7 @@ typedef struct _Context Decl **functions; Decl **methods; Decl **vars; + Decl **incr_array; Decl **ct_ifs; Ast **defers; Decl *active_function_for_analysis; diff --git a/src/compiler/context.c b/src/compiler/context.c index dac4e4352..14511fdf6 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -83,6 +83,8 @@ void context_register_external_symbol(Context *context, Decl *decl) vec_add(context->external_symbol_list, decl); } + + void context_register_global_decl(Context *context, Decl *decl) { assert(decl->name); @@ -121,8 +123,10 @@ void context_register_global_decl(Context *context, Decl *decl) vec_add(context->enums, decl); decl_set_external_name(decl); break; - case DECL_ENUM_CONSTANT: case DECL_ARRAY_VALUE: + vec_add(context->incr_array, decl); + return; + case DECL_ENUM_CONSTANT: case DECL_IMPORT: case DECL_CT_ELSE: case DECL_CT_ELIF: diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 69275b1be..fe37e902a 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -653,9 +653,9 @@ static inline Decl *parse_incremental_array(Context *context) SEMA_TOKEN_ERROR(name, "Did you miss a declaration before the variable name?"); return poisoned_decl; } - CONSUME_OR(TOKEN_PLUS_ASSIGN, poisoned_decl); Decl *decl = decl_new(DECL_ARRAY_VALUE, name.id, VISIBLE_LOCAL); decl->incr_array_decl = TRY_EXPR_OR(parse_initializer(context), poisoned_decl); + TRY_CONSUME_EOS_OR(poisoned_decl); return decl; } diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 433ec94ec..7d1ecea0d 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -319,6 +319,7 @@ static inline bool sema_analyse_declare_stmt(Context *context, Ast *statement) { Decl *decl = statement->declare_stmt; assert(decl->decl_kind == DECL_VAR); + if (!sema_add_local(context, decl)) return decl_poison(decl); if (!sema_resolve_type_info(context, decl->var.type_info)) return decl_poison(decl); decl->type = decl->var.type_info->type; if (decl->var.init_expr) @@ -330,7 +331,6 @@ static inline bool sema_analyse_declare_stmt(Context *context, Ast *statement) return false; } } - if (!sema_add_local(context, decl)) return decl_poison(decl); return true; } diff --git a/test/test_suite/arrays/slice.c3 b/test/test_suite/arrays/slice.c3 new file mode 100644 index 000000000..b9b9d5475 --- /dev/null +++ b/test/test_suite/arrays/slice.c3 @@ -0,0 +1,7 @@ +func void test() +{ + int[3] x = { 1, 2, 3 }; + int[] z = &x; + z[1]; +// z.size(); +} \ No newline at end of file diff --git a/test/test_suite/expressions/arithmetics_sema_fail.c3 b/test/test_suite/expressions/arithmetics_sema_fail.c3 index 998636955..1fa43e870 100644 --- a/test/test_suite/expressions/arithmetics_sema_fail.c3 +++ b/test/test_suite/expressions/arithmetics_sema_fail.c3 @@ -83,7 +83,7 @@ func void test16() uint b = 2; ushort c = 3; a = a + c; - int c = a + b; // #error: Cannot add 'int' to 'uint' + int g = a + b; // #error: Cannot add 'int' to 'uint' } func void test17() diff --git a/test/test_suite/expressions/casts/cast_enum_to_various.c3 b/test/test_suite/expressions/casts/cast_enum_to_various.c3 index f0ac7ea6c..3fd6be19d 100644 --- a/test/test_suite/expressions/casts/cast_enum_to_various.c3 +++ b/test/test_suite/expressions/casts/cast_enum_to_various.c3 @@ -1,4 +1,4 @@ - +// #skip struct Struct { int x; @@ -32,6 +32,6 @@ func void test2(Enum e) func void test3(Enum e) { - EnumB h = cast(e as EnumB); - Func i = cast(e as Func); + //EnumB h = cast(e as EnumB); + //Func i = cast(e as Func); } diff --git a/test/test_suite/globals/incr_array.c3 b/test/test_suite/globals/incr_array.c3 index 591ed0fbe..0a606649d 100644 --- a/test/test_suite/globals/incr_array.c3 +++ b/test/test_suite/globals/incr_array.c3 @@ -1,38 +1,40 @@ // #skip - -i32[+] a; +int[+] a; a += 10; -public func i32 main() { +public func int main() +{ a += 20; // @error{cannot add values to incremental array in function scope} return 0; } - -const i32[+] A; +/* +const int[+] A; A += 10; A += 20; A += 30; +*/ -i32[+] b; +int[+] b; -func void test1() { - i32[+] d; // @error{incremental arrays not allowed in function scope} +func void test1() +{ + int[+] d; // @error{incremental arrays not allowed in function scope} } -i32[+] c; +int[+] c; func void test2() { b += 10; // @error{cannot add values to incremental array in function scope} } -i32[+] a = {} // @error{incremental array cannot have initializer} +int[+] x = {}; // @error{incremental array cannot have initializer} -i32 g; -i8[2] h = { 1, 2 } +int g; +char[2] h = { 1, 2 }; g += 10; // @error{'a' is not an incremental array} @@ -42,13 +44,13 @@ h += 30; // @error{'d' is not an incremental array} test2 += 20; // @error{'main' is not an incremental array} -i32[+] i; +int[+] i; i += xyz; // @error{use of undeclared identifier c} a += test2; // @error{invalid type conversion from 'i32 ()' to 'i32'} -i32[+] k; +int[+] k; k += 1; k += 2; @@ -56,7 +58,7 @@ k += 3; public func void test3() { - i32 c = a; // @error{invalid type conversion from 'i32[3]' to 'i32'} + int c = a; // @error{invalid type conversion from 'i32[3]' to 'i32'} } struct Point @@ -67,7 +69,7 @@ struct Point Point[+] points; -points += { 10, 11 } -points += { 20, main } // @error{invalid type conversion from 'i32 ()' to 'i32'} -points += { 30, 31 } +points += { 10, 11 }; +points += { 20, main }; // @error{invalid type conversion from 'i32 ()' to 'i32'} +points += { 30, 31 }; diff --git a/test/test_suite/struct/member_expr.c3 b/test/test_suite/struct/member_expr.c3 new file mode 100644 index 000000000..06609d4b3 --- /dev/null +++ b/test/test_suite/struct/member_expr.c3 @@ -0,0 +1,64 @@ + +typedef func int(int) as Func; + +typedef func int(Foo*, int) as Func2; + +struct Foo +{ + int a; + Func callback; +} + +func int Foo.func2(Foo* f, int i) +{ + return f.a + i; +} + +func void test_unknown_member() +{ + int a = Foo.b; // #error: No function or member 'Foo.b' found. +} + +/* +func void test_regular_member1() +{ + int a = Foo.a.sizeof; + int b = Foo.a; // @error{member 'a' cannot be used without instance} + +} + +func void test_regular_member2() +{ + int a = Foo.a(); // @error{member 'a' cannot be used without instance} +} + +func void test_function_member1() +{ + Func a = Foo.callback; // @error{member 'callback' cannot be used without instance} +} + +func void test_function_member2() +{ + int a = Foo.callback.sizeof; + int b = Foo.callback(1); // @error{member 'callback' cannot be used without instance} +} + +func void test_static_struct_func() +{ + Func a = Foo.func1; + int b = Foo.func1(1); + int c = Foo.func1.sizeof; +} + +func void test_nonstatic_stuct_func1() +{ + Func2 a = Foo.func2; +} + +func void test_nonstatic_stuct_func2() +{ + int a = Foo.func2.sizeof; + int b = Foo.func2(nil, 2); +} + +*/ \ No newline at end of file