From ee8372145d62bf90c0fe43c78b96a02b6247321e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jul 2023 14:26:47 +0100 Subject: Begin working on proper expressions --- src/tilde_expr.cpp | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 259 insertions(+), 6 deletions(-) (limited to 'src/tilde_expr.cpp') diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 22da43cbd..fc22e12d9 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -1,3 +1,11 @@ +gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value) { + if (value.kind == cgValue_Symbol) { + GB_ASSERT(is_type_internally_pointer_like(value.type)); + value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), value.type); + } + return value; +} + gb_internal cgContextData *cg_push_context_onto_stack(cgProcedure *p, cgAddr ctx) { ctx.kind = cgAddr_Context; cgContextData *cd = array_add_and_get(&p->context_stack); @@ -43,7 +51,7 @@ gb_internal cgValue cg_find_value_from_entity(cgModule *m, Entity *e) { return *found; } - // GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); + GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); return {}; } @@ -57,6 +65,10 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp return {}; } + cgAddr *local_found = map_get(&p->variable_map, e); + if (local_found) { + return *local_found; + } cgValue v = {}; @@ -78,7 +90,9 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp if (v.node == nullptr) { - return cg_addr(cg_find_value_from_entity(m, e)); + cgValue v = cg_find_value_from_entity(m, e); + v = cg_flatten_value(p, v); + return cg_addr(v); } return cg_addr(v); @@ -90,6 +104,17 @@ gb_internal cgValue cg_typeid(cgModule *m, Type *t) { } +gb_internal cgValue cg_correct_endianness(cgProcedure *p, cgValue value) { + Type *src = core_type(value.type); + GB_ASSERT(is_type_integer(src) || is_type_float(src)); + if (is_type_different_to_arch_endianness(src)) { + GB_PANIC("TODO(bill): cg_correct_endianness"); + // Type *platform_src_type = integer_endian_type_to_platform_type(src); + // value = cg_emit_byte_swap(p, value, platform_src_type); + } + return value; +} + gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *type) { // TODO(bill): cg_emit_conv return value; @@ -98,10 +123,7 @@ gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *type) { gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type) { GB_ASSERT(type_size_of(value.type) == type_size_of(type)); - if (value.kind == cgValue_Symbol) { - GB_ASSERT(is_type_pointer(value.type)); - value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), type); - } + value = cg_flatten_value(p, value); i64 src_align = type_align_of(value.type); i64 dst_align = type_align_of(type); @@ -133,6 +155,217 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type) } +gb_internal cgAddr cg_build_addr_slice_expr(cgProcedure *p, Ast *expr) { + ast_node(se, SliceExpr, expr); + + cgValue low = cg_const_int(p, t_int, 0); + cgValue high = {}; + + if (se->low != nullptr) { + low = cg_correct_endianness(p, cg_build_expr(p, se->low)); + } + if (se->high != nullptr) { + high = cg_correct_endianness(p, cg_build_expr(p, se->high)); + } + + bool no_indices = se->low == nullptr && se->high == nullptr; + gb_unused(no_indices); + + cgAddr addr = cg_build_addr(p, se->expr); + cgValue base = cg_addr_load(p, addr); + Type *type = base_type(base.type); + + if (is_type_pointer(type)) { + type = base_type(type_deref(type)); + addr = cg_addr(base); + base = cg_addr_load(p, addr); + } + + switch (type->kind) { + case Type_Slice: { + // Type *slice_type = type; + // cgValue len = cg_slice_len(p, base); + // if (high.value == nullptr) high = len; + + // if (!no_indices) { + // cg_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr); + // } + + // cgValue elem = cg_emit_ptr_offset(p, cg_slice_elem(p, base), low); + // cgValue new_len = cg_emit_arith(p, Token_Sub, high, low, t_int); + + // cgAddr slice = cg_add_local_generated(p, slice_type, false); + // cg_fill_slice(p, slice, elem, new_len); + // return slice; + GB_PANIC("cg_build_addr_slice_expr Type_Slice"); + break; + } + + case Type_RelativeSlice: + GB_PANIC("TODO(bill): Type_RelativeSlice should be handled above already on the cg_addr_load"); + break; + + case Type_DynamicArray: { + // Type *elem_type = type->DynamicArray.elem; + // Type *slice_type = alloc_type_slice(elem_type); + + // lbValue len = lb_dynamic_array_len(p, base); + // if (high.value == nullptr) high = len; + + // if (!no_indices) { + // lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr); + // } + + // lbValue elem = lb_emit_ptr_offset(p, lb_dynamic_array_elem(p, base), low); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + + // lbAddr slice = lb_add_local_generated(p, slice_type, false); + // lb_fill_slice(p, slice, elem, new_len); + // return slice; + GB_PANIC("cg_build_addr_slice_expr Type_DynamicArray"); + break; + } + + case Type_MultiPointer: { + // lbAddr res = lb_add_local_generated(p, type_of_expr(expr), false); + // if (se->high == nullptr) { + // lbValue offset = base; + // LLVMValueRef indices[1] = {low.value}; + // offset.value = LLVMBuildGEP2(p->builder, lb_type(p->module, offset.type->MultiPointer.elem), offset.value, indices, 1, ""); + // lb_addr_store(p, res, offset); + // } else { + // low = lb_emit_conv(p, low, t_int); + // high = lb_emit_conv(p, high, t_int); + + // lb_emit_multi_pointer_slice_bounds_check(p, se->open, low, high); + + // LLVMValueRef indices[1] = {low.value}; + // LLVMValueRef ptr = LLVMBuildGEP2(p->builder, lb_type(p->module, base.type->MultiPointer.elem), base.value, indices, 1, ""); + // LLVMValueRef len = LLVMBuildSub(p->builder, high.value, low.value, ""); + + // LLVMValueRef gep0 = lb_emit_struct_ep(p, res.addr, 0).value; + // LLVMValueRef gep1 = lb_emit_struct_ep(p, res.addr, 1).value; + // LLVMBuildStore(p->builder, ptr, gep0); + // LLVMBuildStore(p->builder, len, gep1); + // } + // return res; + GB_PANIC("cg_build_addr_slice_expr Type_MultiPointer"); + break; + } + + case Type_Array: { + // Type *slice_type = alloc_type_slice(type->Array.elem); + // lbValue len = lb_const_int(p->module, t_int, type->Array.count); + + // if (high.value == nullptr) high = len; + + // bool low_const = type_and_value_of_expr(se->low).mode == Addressing_Constant; + // bool high_const = type_and_value_of_expr(se->high).mode == Addressing_Constant; + + // if (!low_const || !high_const) { + // if (!no_indices) { + // lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr); + // } + // } + // lbValue elem = lb_emit_ptr_offset(p, lb_array_elem(p, lb_addr_get_ptr(p, addr)), low); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + + // lbAddr slice = lb_add_local_generated(p, slice_type, false); + // lb_fill_slice(p, slice, elem, new_len); + // return slice; + GB_PANIC("cg_build_addr_slice_expr Type_Array"); + break; + } + + case Type_Basic: { + // GB_ASSERT(type == t_string); + // lbValue len = lb_string_len(p, base); + // if (high.value == nullptr) high = len; + + // if (!no_indices) { + // lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr); + // } + + // lbValue elem = lb_emit_ptr_offset(p, lb_string_elem(p, base), low); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + + // lbAddr str = lb_add_local_generated(p, t_string, false); + // lb_fill_string(p, str, elem, new_len); + // return str; + GB_PANIC("cg_build_addr_slice_expr Type_Basic"); + break; + } + + + case Type_Struct: + // if (is_type_soa_struct(type)) { + // lbValue len = lb_soa_struct_len(p, lb_addr_get_ptr(p, addr)); + // if (high.value == nullptr) high = len; + + // if (!no_indices) { + // lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr); + // } + // #if 1 + + // lbAddr dst = lb_add_local_generated(p, type_of_expr(expr), true); + // if (type->Struct.soa_kind == StructSoa_Fixed) { + // i32 field_count = cast(i32)type->Struct.fields.count; + // for (i32 i = 0; i < field_count; i++) { + // lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i); + // lbValue field_src = lb_emit_struct_ep(p, lb_addr_get_ptr(p, addr), i); + // field_src = lb_emit_array_ep(p, field_src, low); + // lb_emit_store(p, field_dst, field_src); + // } + + // lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + // lb_emit_store(p, len_dst, new_len); + // } else if (type->Struct.soa_kind == StructSoa_Slice) { + // if (no_indices) { + // lb_addr_store(p, dst, base); + // } else { + // i32 field_count = cast(i32)type->Struct.fields.count - 1; + // for (i32 i = 0; i < field_count; i++) { + // lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i); + // lbValue field_src = lb_emit_struct_ev(p, base, i); + // field_src = lb_emit_ptr_offset(p, field_src, low); + // lb_emit_store(p, field_dst, field_src); + // } + + + // lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + // lb_emit_store(p, len_dst, new_len); + // } + // } else if (type->Struct.soa_kind == StructSoa_Dynamic) { + // i32 field_count = cast(i32)type->Struct.fields.count - 3; + // for (i32 i = 0; i < field_count; i++) { + // lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i); + // lbValue field_src = lb_emit_struct_ev(p, base, i); + // field_src = lb_emit_ptr_offset(p, field_src, low); + // lb_emit_store(p, field_dst, field_src); + // } + + + // lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count); + // lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int); + // lb_emit_store(p, len_dst, new_len); + // } + + // return dst; + // #endif + // } + GB_PANIC("cg_build_addr_slice_expr Type_Struct"); + break; + + } + + GB_PANIC("Unknown slicable type"); + return {}; +} + + + gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr); gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) { @@ -252,6 +485,11 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { return cg_value(cast(TB_Node *)nullptr, e->type); } GB_ASSERT(e->kind != Entity_ProcGroup); + + cgAddr *addr = map_get(&p->variable_map, e); + if (addr) { + return cg_addr_load(p, *addr); + } // return cg_find_ident(p, m, e, expr); GB_PANIC("TODO: cg_find_ident"); return {}; @@ -327,6 +565,17 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { cgValue value = cg_build_expr(p, ac->expr); return cg_emit_conv(p, value, type); case_end; + + case_ast_node(se, SliceExpr, expr); + if (is_type_slice(type_of_expr(se->expr))) { + // NOTE(bill): Quick optimization + if (se->high == nullptr && + (se->low == nullptr || cg_is_expr_constant_zero(se->low))) { + return cg_build_expr(p, se->expr); + } + } + return cg_addr_load(p, cg_build_addr(p, expr)); + case_end; } GB_PANIC("TODO(bill): cg_build_expr_internal %.*s", LIT(ast_strings[expr->kind])); return {}; @@ -384,6 +633,10 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { Entity *e = entity_of_node(expr); return cg_build_addr_from_entity(p, e, expr); case_end; + + case_ast_node(se, SliceExpr, expr); + return cg_build_addr_slice_expr(p, expr); + case_end; } TokenPos token_pos = ast_token(expr).pos; -- cgit v1.2.3