Make raw_data an intrinsic rather a @(builtin) runtime procedure

This commit is contained in:
gingerBill
2022-10-30 22:05:29 +00:00
parent 2cd895c50b
commit 6a14c3edb4
5 changed files with 90 additions and 34 deletions
+53
View File
@@ -3651,6 +3651,59 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
operand->mode = Addressing_NoValue;
break;
case BuiltinProc_raw_data:
{
Operand x = {};
check_expr(c, &x, ce->args[0]);
if (x.mode == Addressing_Invalid) {
return false;
}
if (!is_operand_value(x)) {
gbString s = expr_to_string(x.expr);
error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
gb_string_free(s);
return false;
}
Type *t = base_type(x.type);
operand->mode = Addressing_Value;
operand->type = nullptr;
switch (t->kind) {
case Type_Slice:
operand->type = alloc_type_multi_pointer(t->MultiPointer.elem);
break;
case Type_DynamicArray:
operand->type = alloc_type_multi_pointer(t->DynamicArray.elem);
break;
case Type_Basic:
if (t->Basic.kind == Basic_string) {
operand->type = alloc_type_multi_pointer(t_u8);
}
break;
case Type_Pointer:
case Type_MultiPointer:
{
Type *base = base_type(type_deref(t, true));
switch (base->kind) {
case Type_Array:
case Type_EnumeratedArray:
case Type_SimdVector:
operand->type = alloc_type_multi_pointer(base_array_type(base));
break;
}
}
break;
}
if (operand->type == nullptr) {
gbString s = type_to_string(x.type);
error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
gb_string_free(s);
return false;
}
}
break;
case BuiltinProc_read_cycle_counter:
operand->mode = Addressing_Value;
operand->type = t_i64;
+4
View File
@@ -42,6 +42,8 @@ enum BuiltinProcId {
BuiltinProc_unreachable,
BuiltinProc_raw_data,
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
// "Intrinsics"
@@ -338,6 +340,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("unreachable"), 0, false, Expr_Expr, BuiltinProcPkg_builtin, /*diverging*/true},
{STR_LIT("raw_data"), 1, false, Expr_Expr, BuiltinProcPkg_builtin},
{STR_LIT(""), 0, true, Expr_Expr, BuiltinProcPkg_builtin}, // DIRECTIVE
+31
View File
@@ -1850,6 +1850,37 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
lb_emit_unreachable(p);
return {};
case BuiltinProc_raw_data:
{
lbValue x = lb_build_expr(p, ce->args[0]);
Type *t = base_type(x.type);
lbValue res = {};
switch (t->kind) {
case Type_Slice:
res = lb_slice_elem(p, x);
res = lb_emit_conv(p, res, tv.type);
break;
case Type_DynamicArray:
res = lb_dynamic_array_elem(p, x);
res = lb_emit_conv(p, res, tv.type);
break;
case Type_Basic:
if (t->Basic.kind == Basic_string) {
res = lb_string_elem(p, x);
res = lb_emit_conv(p, res, tv.type);
} else if (t->Basic.kind == Basic_cstring) {
res = lb_emit_conv(p, x, tv.type);
}
break;
case Type_Pointer:
case Type_MultiPointer:
res = lb_emit_conv(p, x, tv.type);
break;
}
GB_ASSERT(res.value != nullptr);
return res;
}
// "Intrinsics"