RELEASE=1
+USE_GCC=1
OBJ_FILES=\
build/onyxlex.o \
ifeq ($(RELEASE), 0)
CC=gcc
else
- CC=tcc
+ ifeq ($(USE_GCC),1)
+ CC=gcc
+ else
+ CC=tcc
+ endif
endif
endif
#private_file
heap_resize :: proc (ptr: rawptr, new_size: u32, align: u32) -> rawptr {
+ if ptr == null do return null;
+
hb_ptr := cast(^heap_block) (cast(u32) ptr - sizeof heap_block);
old_size := hb_ptr.size - sizeof heap_block;
buffer[len] = c;
len += 1;
}
+
+ case #char "b" {
+ b : bool;
+ if !vararg_get(va, ^b) do return;
+
+ s := "false";
+ if b do s = "true";
+
+ for a: s {
+ buffer[len] = a;
+ len += 1;
+ }
+ }
}
state = 0;
package core.map
+use package core { printf }
use package core.array as array
use package core.string as string
and converted to a cast(f32). Then, when it doesn't match the first one
and it tries the second, the parameter types are f32 and unsized int,
which is doesn't match the second one, when the original parameters would
- have matched correctly.
\ No newline at end of file
+ have matched correctly.
+
+[ ] `TileData :: [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;` results in a
+ segfault because it is an invalid top level node, but that is not checked
+ before it is tried to be used.
+
+[X] `TileData :: #type [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;` produces the
+ following error:
+ ```
+ (/home/brendan/dev/onyx/aoc/day20.onyx:25,19) Array type expects type 'i32' for size, got 'unsized int'.
+ 25 | TileData :: #type [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;
+ ```
+
+ This because the expression for the array size is not reducing and getting
+ converted to the fixed size integer. I suspect this is because for sizeof
+ and alignof expression, `fill_in_type` is not used, and that function has
+ the logic to handle the array subscript reduction and type resolution.
+
+[X] The following struct is causing a seg fault in the compiler. I believe it
+ is because of the duplicate struct member names and failing to get the position
+ in the file to report the error.
+ ```
+ Tile :: struct {
+ id : u32;
+ orientation : TileOrientation;
+ data : [] bool;
+ edges : [] u32;
+
+ pos_x : u32 = 0;
+ pos_x : u32 = 0;
+ }
+ ```
thought to remember that ranges in for-loops and slices are NOT inclusive
on the upper end.
+ [ ] Functions should be polymorphic on the size of array parameters. For example,
+ foo :: proc (arr: [$N] $T) { ... }
+ should be polymorphic on both the type of the array elements and the array
+ size. This would allow for better support for fixed size arrays, as well
+ as some needed built in functions such as:
+ array_to_slice :: proc (arr: [$N] $T) -> [] T {
+ return arr[0 .. N];
+ }
+
API Expansion:
There are many different places where the standard API for WASI and JS
backends could be improved. Here are some of the target areas.
struct AstDereference { AstTyped_base; AstTyped *expr; };
struct AstArrayAccess { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 elem_size; };
struct AstFieldAccess { AstTyped_base; AstTyped *expr; u32 offset; u32 idx; char* field; }; // If token is null, defer to field
-struct AstSizeOf { AstTyped_base; AstType *so_type; u64 size; };
-struct AstAlignOf { AstTyped_base; AstType *ao_type; u64 alignment; };
+struct AstSizeOf { AstTyped_base; AstType *so_ast_type; Type *so_type; u64 size; };
+struct AstAlignOf { AstTyped_base; AstType *ao_ast_type; Type *ao_type; u64 alignment; };
struct AstFileContents { AstTyped_base; OnyxToken *filename; u32 addr, size; };
struct AstStructLiteral {
AstTyped_base;
CHECK(function_header, AstFunction* func);
CHECK(memres, AstMemRes* memres);
-static inline void fill_in_type(AstTyped* node) {
- if (node->type_node && node->type_node->kind == Ast_Kind_Array_Type) {
- if (((AstArrayType *) node->type_node)->count_expr) {
- check_expression(&((AstArrayType *) node->type_node)->count_expr);
- resolve_expression_type(((AstArrayType *) node->type_node)->count_expr);
+static inline void fill_in_array_count(AstType* type_node) {
+ if (type_node == NULL) return;
+
+ if (type_node->kind == Ast_Kind_Type_Alias) {
+ fill_in_array_count(((AstTypeAlias *) type_node)->to);
+ }
+
+ if (type_node->kind == Ast_Kind_Array_Type) {
+ if (((AstArrayType *) type_node)->count_expr) {
+ check_expression(&((AstArrayType *) type_node)->count_expr);
+ resolve_expression_type(((AstArrayType *) type_node)->count_expr);
}
}
+}
+
+static inline void fill_in_type(AstTyped* node) {
+ fill_in_array_count(node->type_node);
if (node->type == NULL)
node->type = type_build_from_ast(semstate.allocator, node->type_node);
}
b32 check_size_of(AstSizeOf* so) {
- so->size = type_size_of(type_build_from_ast(semstate.allocator, so->so_type));
+ fill_in_array_count(so->so_ast_type);
+
+ so->so_type = type_build_from_ast(semstate.allocator, so->so_ast_type);
+ if (so->so_type == NULL) {
+ onyx_report_error(so->token->pos, "Error with type used here.");
+ return 1;
+ }
+ so->size = type_size_of(so->so_type);
return 0;
}
b32 check_align_of(AstAlignOf* ao) {
- ao->alignment = type_alignment_of(type_build_from_ast(semstate.allocator, ao->ao_type));
+ fill_in_array_count(ao->ao_ast_type);
+
+ ao->ao_type = type_build_from_ast(semstate.allocator, ao->ao_ast_type);
+ if (ao->ao_type == NULL) {
+ onyx_report_error(ao->token->pos, "Error with type used here.");
+ return 1;
+ }
+ ao->alignment = type_alignment_of(ao->ao_type);
return 0;
}
}
b32 check_struct(AstStructType* s_node) {
- bh_table(i32) mem_set;
- bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
-
- bh_arr_each(AstStructMember *, member, s_node->members) {
- token_toggle_end((*member)->token);
-
- if (bh_table_has(i32, mem_set, (*member)->token->text)) {
- onyx_report_error((*member)->token->pos,
- "Duplicate struct member '%s'.",
- (*member)->token->text);
-
- token_toggle_end((*member)->token);
- return 1;
- }
-
- bh_table_put(i32, mem_set, (*member)->token->text, 1);
- token_toggle_end((*member)->token);
- }
-
- bh_table_free(mem_set);
-
// NOTE: fills in the stcache
type_build_from_ast(semstate.allocator, (AstType *) s_node);
break;
case Ast_Kind_Size_Of:
- ((AstSizeOf *) nn)->so_type = (AstType *) ast_clone(a, ((AstSizeOf *) node)->so_type);
+ ((AstSizeOf *) nn)->so_ast_type = (AstType *) ast_clone(a, ((AstSizeOf *) node)->so_ast_type);
break;
case Ast_Kind_Align_Of:
- ((AstAlignOf *) nn)->ao_type = (AstType *) ast_clone(a, ((AstAlignOf *) node)->ao_type);
+ ((AstAlignOf *) nn)->ao_ast_type = (AstType *) ast_clone(a, ((AstAlignOf *) node)->ao_ast_type);
break;
case Ast_Kind_Struct_Literal: {
case Token_Type_Keyword_Sizeof: {
AstSizeOf* so_node = make_node(AstSizeOf, Ast_Kind_Size_Of);
so_node->token = expect_token(parser, Token_Type_Keyword_Sizeof);
- so_node->so_type = (AstType *) parse_type(parser);
+ so_node->so_ast_type = (AstType *) parse_type(parser);
so_node->type_node = (AstType *) &basic_type_i32;
retval = (AstTyped *) so_node;
case Token_Type_Keyword_Alignof: {
AstAlignOf* ao_node = make_node(AstAlignOf, Ast_Kind_Align_Of);
ao_node->token = expect_token(parser, Token_Type_Keyword_Alignof);
- ao_node->ao_type = (AstType *) parse_type(parser);
+ ao_node->ao_ast_type = (AstType *) parse_type(parser);
ao_node->type_node = (AstType *) &basic_type_i32;
retval = (AstTyped *) ao_node;
if (s_node->flags & Ast_Flag_Type_Is_Resolved) return type;
s_node->flags |= Ast_Flag_Type_Is_Resolved;
+
+ {
+ bh_table(i32) mem_set;
+ bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
+
+ bh_arr_each(AstStructMember *, member, s_node->members) {
+ token_toggle_end((*member)->token);
+
+ if (bh_table_has(i32, mem_set, (*member)->token->text)) {
+ onyx_report_error((*member)->token->pos,
+ "Duplicate struct member '%s'.",
+ (*member)->token->text);
+
+ token_toggle_end((*member)->token);
+ return type;
+ }
+
+ bh_table_put(i32, mem_set, (*member)->token->text, 1);
+ token_toggle_end((*member)->token);
+ }
+
+ bh_table_free(mem_set);
+ }
fori (i, 0, bh_arr_length(s_node->members)) {
AstStructMember *member = s_node->members[i];
static void symres_size_of(AstSizeOf* so) {
so->type_node = symres_type(so->type_node);
- so->so_type = symres_type(so->so_type);
+ so->so_ast_type = symres_type(so->so_ast_type);
}
static void symres_align_of(AstAlignOf* ao) {
ao->type_node = symres_type(ao->type_node);
- ao->ao_type = symres_type(ao->ao_type);
+ ao->ao_ast_type = symres_type(ao->ao_ast_type);
}
static void symres_field_access(AstFieldAccess** fa) {
}
}
- bh_arr_each(AstTyped *, expr, sl->values) symres_expression(expr);
+ bh_arr_each(AstTyped *, expr, sl->values) {
+ if (*expr == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal.");
+ else symres_expression(expr);
+ }
}
static void symres_array_literal(AstArrayLiteral* al) {
if (a_node->count_expr->kind != Ast_Kind_NumLit
|| a_node->count_expr->type->kind != Type_Kind_Basic
|| a_node->count_expr->type->Basic.kind != Basic_Kind_I32) {
+ onyx_report_error(type_node->token->pos, "Array type expects type 'i32' for size, got '%s'.",
+ type_get_name(a_node->count_expr->type));
return NULL;
}