name: str;
members: [] Member;
parameters: [] any;
+ tags: [] any;
}
Type_Info_Compound :: struct {
char *name;
bh_arr(AstStructMember *) members;
+ bh_arr(AstTyped *) meta_tags;
u32 min_alignment, min_size;
bh_arr(struct AstPolySolution) poly_sln; \
bh_arr(TypeWithOffset) linear_members; \
struct AstType *constructed_from; \
+ bh_arr(struct AstTyped *) meta_tags; \
}) \
TYPE_KIND(Compound, struct { \
u32 count; \
new_w := new_x1 - new_x0;
new_h := new_y1 - new_y0;
- array.push(^scissor_stack, .{ new_x0, new_y0, new_w, new_h });
+ array.push(^scissor_stack, .{ new_x0, new_y0, new_w + 1, new_h + 1 });
- gl.scissor(~~new_x0, window_height - ~~new_y1, ~~new_w, ~~new_h);
+ gl.scissor(~~new_x0, window_height - ~~new_y1, ~~math.ceil(new_w + 1), ~~math.ceil(new_h + 1));
}
pop_scissor :: (use ir: ^Immediate_Renderer) {
}
scrollable_region_start :: (use r: Rectangle, use src: Scrollable_Region_Controls = .{},
- site := #callsite, state: ^Scrollable_Region_State = null) -> Scrollable_Region_Handle {
- hash := get_site_hash(site, 0);
+ site := #callsite, increment := 0,
+ state: ^Scrollable_Region_State = null) -> Scrollable_Region_Handle {
+ hash := get_site_hash(site, increment);
x, y := Rectangle.top_left(r);
width, height := Rectangle.dimensions(r);
YIELD(aof->token->pos, "Trying to resolve type of expression to take a reference.");
}
- if ((aof->expr->kind != Ast_Kind_Subscript
- && aof->expr->kind != Ast_Kind_Dereference
- && aof->expr->kind != Ast_Kind_Field_Access
- && aof->expr->kind != Ast_Kind_Memres
- && aof->expr->kind != Ast_Kind_Local)
- || (aof->expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) {
+ AstTyped* expr = (AstTyped *) strip_aliases((AstNode *) aof->expr);
+
+ if ((expr->kind != Ast_Kind_Subscript
+ && expr->kind != Ast_Kind_Dereference
+ && expr->kind != Ast_Kind_Field_Access
+ && expr->kind != Ast_Kind_Memres
+ && expr->kind != Ast_Kind_Local)
+ || (expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) {
ERROR(aof->token->pos, "Cannot take the address of something that is not an l-value.");
}
- aof->expr->flags |= Ast_Flag_Address_Taken;
+ expr->flags |= Ast_Flag_Address_Taken;
- aof->type = type_make_pointer(context.ast_alloc, aof->expr->type);
+ aof->type = type_make_pointer(context.ast_alloc, expr->type);
return Check_Success;
}
if (s_node->entity_type && s_node->entity_type->state < Entity_State_Code_Gen)
YIELD(s_node->token->pos, "Waiting for struct type to be constructed before checking defaulted members.");
+ if (s_node->meta_tags) {
+ bh_arr_each(AstTyped *, meta, s_node->meta_tags) {
+ CHECK(expression, meta);
+ resolve_expression_type(*meta);
+
+ if (((*meta)->flags & Ast_Flag_Comptime) == 0) {
+ onyx_report_error((*meta)->token->pos, "#tag expressions are expected to be compile-time known.");
+ return Check_Error;
+ }
+ }
+ }
+
bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) {
if ((*smem)->initial_value && *(*smem)->initial_value) {
CHECK(expression, (*smem)->initial_value);
resolve_expression_type(*meta);
if (((*meta)->flags & Ast_Flag_Comptime) == 0) {
- onyx_report_error((*meta)->token->pos, "#meta expression are expected to be compile-time known.");
+ onyx_report_error((*meta)->token->pos, "#tag expressions are expected to be compile-time known.");
return Check_Error;
}
}
CheckStatus check_type(AstType* type) {
if (type == NULL) return Check_Success;
+ AstType* original_type = type;
while (type->kind == Ast_Kind_Type_Alias)
type = ((AstTypeAlias *) type)->to;
}
}
+ type = original_type;
+ while (type->kind == Ast_Kind_Type_Alias) {
+ type->flags |= Ast_Flag_Comptime;
+ type = ((AstTypeAlias *) type)->to;
+ }
+
type->flags |= Ast_Flag_Already_Checked;
return Check_Success;
}
case Token_Type_Literal_Float:
case Token_Type_Literal_True:
case Token_Type_Literal_False:
+ case '-':
*next_insertion = (AstType *) parse_expression(parser, 0);
next_insertion = NULL;
break;
}
bh_arr_new(global_heap_allocator, s_node->members, 4);
-
+
+ bh_arr(AstTyped *) struct_meta_tags=NULL;
while (parser->curr->type == '#') {
if (parser->hit_unexpected_token) return NULL;
s_node->min_size = numlit->value.i;
}
+ else if (parse_possible_directive(parser, "tag")) {
+ expect_token(parser, '(');
+
+ AstTyped* expr = parse_expression(parser, 0);
+
+ if (struct_meta_tags == NULL) bh_arr_new(global_heap_allocator, struct_meta_tags, 1);
+ bh_arr_push(struct_meta_tags, expr);
+
+ expect_token(parser, ')');
+ }
+
else {
OnyxToken* directive_token = expect_token(parser, '#');
OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
}
}
+ s_node->meta_tags = struct_meta_tags;
+
expect_token(parser, '{');
b32 member_is_used = 0;
} else {
bh_arr(AstTyped *) meta_tags=NULL;
while (parse_possible_directive(parser, "tag")) {
+ expect_token(parser, '(');
+
AstTyped* expr = parse_expression(parser, 0);
if (meta_tags == NULL) bh_arr_new(global_heap_allocator, meta_tags, 1);
bh_arr_push(meta_tags, expr);
- expect_token(parser, ';');
+ expect_token(parser, ')');
}
bh_arr_clear(member_list_temp);
AstStructType* st = (AstStructType *) t;
if (st->scope) scope_enter(st->scope);
+ if (st->meta_tags) {
+ bh_arr_each(AstTyped *, meta, st->meta_tags) {
+ SYMRES(expression, meta);
+ }
+ }
+
bh_arr_each(AstStructMember *, smem, st->members) {
if ((*smem)->initial_value != NULL) {
SYMRES(expression, &(*smem)->initial_value);
s_type->ast_type = type_node;
s_type->Struct.name = s_node->name;
s_type->Struct.mem_count = bh_arr_length(s_node->members);
+ s_type->Struct.meta_tags = s_node->meta_tags;
type_register(s_type);
s_type->Struct.memarr = NULL;
}
}
+ if (lval->kind == Ast_Kind_Field_Access) {
+ AstFieldAccess* fa = (AstFieldAccess *) lval;
+ if (fa->expr->kind == Ast_Kind_Param && type_is_structlike_strict(fa->expr->type)) {
+ emit_expression(mod, &code, assign->right);
+
+ u64 localidx = bh_imap_get(&mod->local_map, (u64) fa->expr);
+ WIL(WI_LOCAL_SET, localidx + fa->idx);
+
+ *pcode = code;
+ return;
+ }
+ }
+
if (lval->kind == Ast_Kind_Global) {
emit_expression(mod, &code, assign->right);
EMIT_FUNC(location_return_offset, AstTyped* expr, u64* offset_return) {
bh_arr(WasmInstruction) code = *pcode;
+ expr = (AstTyped *) strip_aliases((AstNode *) expr);
+
switch (expr->kind) {
case Ast_Kind_Param:
case Ast_Kind_Local: {
static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) {
b32 retval = 1;
+ if (node_is_type((AstNode *) node)) {
+ Type* constructed_type = type_build_from_ast(context.ast_alloc, (AstType *) node);
+ ((i32 *) data)[0] = constructed_type->id;
+ return 1;
+ }
+
switch (node->kind) {
case Ast_Kind_Array_Literal: {
AstArrayLiteral* al = (AstArrayLiteral *) node;
u32* param_locations = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(s->poly_sln));
u32* value_locations = bh_alloc_array(global_scratch_allocator, u32, s->mem_count);
u32* meta_locations = bh_alloc_array(global_scratch_allocator, u32, s->mem_count);
+ u32* struct_tag_locations = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(s->meta_tags));
memset(value_locations, 0, s->mem_count * sizeof(u32));
memset(meta_locations, 0, s->mem_count * sizeof(u32));
+ memset(struct_tag_locations, 0, bh_arr_length(s->meta_tags) * sizeof(u32));
u32 i = 0;
bh_arr_each(StructMember*, pmem, s->memarr) {
else bh_buffer_write_u32(&table_buffer, sln->value->type->id);
}
+ i = 0;
+ bh_arr_each(AstTyped *, tag, s->meta_tags) {
+ AstTyped* value = *tag;
+ assert(value->flags & Ast_Flag_Comptime);
+ assert(value->type);
+
+ u32 size = type_size_of(value->type);
+ bh_buffer_align(&table_buffer, type_alignment_of(value->type));
+ struct_tag_locations[i] = table_buffer.length;
+
+ bh_buffer_grow(&table_buffer, table_buffer.length + size);
+ u8* buffer = table_buffer.data + table_buffer.length;
+
+ assert(emit_raw_data_(module, buffer, value));
+ table_buffer.length += size;
+
+ i += 1;
+ }
+
+ bh_buffer_align(&table_buffer, 8);
+ u32 struct_tag_base = table_buffer.length;
+
+ fori (i, 0, bh_arr_length(s->meta_tags)) {
+ PATCH;
+ bh_buffer_write_u64(&table_buffer, struct_tag_locations[i]);
+ bh_buffer_write_u64(&table_buffer, s->meta_tags[i]->type->id);
+ }
+
u32 name_base = 0;
u32 name_length = 0;
if (s->name) {
PATCH;
bh_buffer_write_u64(&table_buffer, params_base);
bh_buffer_write_u64(&table_buffer, bh_arr_length(s->poly_sln));
+ PATCH;
+ bh_buffer_write_u64(&table_buffer, struct_tag_base);
+ bh_buffer_write_u64(&table_buffer, bh_arr_length(s->meta_tags));
break;
}