add int_type builtin function
parent
50310cf9df
commit
6ff996f60f
|
@ -1139,6 +1139,7 @@ enum BuiltinFnId {
|
||||||
BuiltinFnIdFence,
|
BuiltinFnIdFence,
|
||||||
BuiltinFnIdDivExact,
|
BuiltinFnIdDivExact,
|
||||||
BuiltinFnIdTruncate,
|
BuiltinFnIdTruncate,
|
||||||
|
BuiltinFnIdIntType,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuiltinFnEntry {
|
struct BuiltinFnEntry {
|
||||||
|
|
|
@ -4790,6 +4790,52 @@ static TypeTableEntry *analyze_compile_err(CodeGen *g, ImportTableEntry *import,
|
||||||
return g->builtin_types.entry_invalid;
|
return g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TypeTableEntry *analyze_int_type(CodeGen *g, ImportTableEntry *import,
|
||||||
|
BlockContext *context, AstNode *node)
|
||||||
|
{
|
||||||
|
AstNode **is_signed_node = &node->data.fn_call_expr.params.at(0);
|
||||||
|
AstNode **bit_count_node = &node->data.fn_call_expr.params.at(1);
|
||||||
|
AstNode **is_wrap_node = &node->data.fn_call_expr.params.at(2);
|
||||||
|
|
||||||
|
TypeTableEntry *bool_type = g->builtin_types.entry_bool;
|
||||||
|
TypeTableEntry *usize_type = g->builtin_types.entry_usize;
|
||||||
|
TypeTableEntry *is_signed_type = analyze_expression(g, import, context, bool_type, *is_signed_node);
|
||||||
|
TypeTableEntry *bit_count_type = analyze_expression(g, import, context, usize_type, *bit_count_node);
|
||||||
|
TypeTableEntry *is_wrap_type = analyze_expression(g, import, context, bool_type, *is_wrap_node);
|
||||||
|
|
||||||
|
if (is_signed_type->id == TypeTableEntryIdInvalid ||
|
||||||
|
bit_count_type->id == TypeTableEntryIdInvalid ||
|
||||||
|
is_wrap_type->id == TypeTableEntryIdInvalid)
|
||||||
|
{
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstExprValue *is_signed_val = &get_resolved_expr(*is_signed_node)->const_val;
|
||||||
|
ConstExprValue *bit_count_val = &get_resolved_expr(*bit_count_node)->const_val;
|
||||||
|
ConstExprValue *is_wrap_val = &get_resolved_expr(*is_wrap_node)->const_val;
|
||||||
|
|
||||||
|
AstNode *bad_node = nullptr;
|
||||||
|
if (!is_signed_val->ok) {
|
||||||
|
bad_node = *is_signed_node;
|
||||||
|
} else if (!bit_count_val->ok) {
|
||||||
|
bad_node = *bit_count_node;
|
||||||
|
} else if (!is_wrap_val->ok) {
|
||||||
|
bad_node = *is_wrap_node;
|
||||||
|
}
|
||||||
|
if (bad_node) {
|
||||||
|
add_node_error(g, bad_node, buf_sprintf("unable to evaluate constant expression"));
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool depends_on_compile_var = is_signed_val->depends_on_compile_var ||
|
||||||
|
bit_count_val->depends_on_compile_var || is_wrap_val->depends_on_compile_var;
|
||||||
|
|
||||||
|
TypeTableEntry *int_type = get_int_type(g, is_signed_val->data.x_bool, is_wrap_val->data.x_bool,
|
||||||
|
bit_count_val->data.x_bignum.data.x_uint);
|
||||||
|
return resolve_expr_const_val_as_type(g, node, int_type, depends_on_compile_var);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||||
TypeTableEntry *expected_type, AstNode *node)
|
TypeTableEntry *expected_type, AstNode *node)
|
||||||
{
|
{
|
||||||
|
@ -5136,6 +5182,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
|
||||||
return analyze_truncate(g, import, context, node);
|
return analyze_truncate(g, import, context, node);
|
||||||
case BuiltinFnIdCompileErr:
|
case BuiltinFnIdCompileErr:
|
||||||
return analyze_compile_err(g, import, context, node);
|
return analyze_compile_err(g, import, context, node);
|
||||||
|
case BuiltinFnIdIntType:
|
||||||
|
return analyze_int_type(g, import, context, node);
|
||||||
}
|
}
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,6 +540,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
|
||||||
case BuiltinFnIdImport:
|
case BuiltinFnIdImport:
|
||||||
case BuiltinFnIdCImport:
|
case BuiltinFnIdCImport:
|
||||||
case BuiltinFnIdCompileErr:
|
case BuiltinFnIdCompileErr:
|
||||||
|
case BuiltinFnIdIntType:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
case BuiltinFnIdCtz:
|
case BuiltinFnIdCtz:
|
||||||
case BuiltinFnIdClz:
|
case BuiltinFnIdClz:
|
||||||
|
@ -4657,6 +4658,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "div_exact", 2);
|
create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "div_exact", 2);
|
||||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2);
|
create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2);
|
||||||
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compile_err", 1);
|
create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compile_err", 1);
|
||||||
|
create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "int_type", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(CodeGen *g, Buf *source_path) {
|
static void init(CodeGen *g, Buf *source_path) {
|
||||||
|
|
|
@ -834,6 +834,7 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_
|
||||||
case BuiltinFnIdFrameAddress:
|
case BuiltinFnIdFrameAddress:
|
||||||
case BuiltinFnIdReturnAddress:
|
case BuiltinFnIdReturnAddress:
|
||||||
case BuiltinFnIdCompileErr:
|
case BuiltinFnIdCompileErr:
|
||||||
|
case BuiltinFnIdIntType:
|
||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1689,3 +1689,26 @@ struct DivResult {
|
||||||
quotient: u64,
|
quotient: u64,
|
||||||
remainder: u64,
|
remainder: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#attribute("test")
|
||||||
|
fn int_type_builtin() {
|
||||||
|
assert(@int_type(true, 8, false) == i8);
|
||||||
|
assert(@int_type(true, 16, false) == i16);
|
||||||
|
assert(@int_type(true, 32, false) == i32);
|
||||||
|
assert(@int_type(true, 64, false) == i64);
|
||||||
|
|
||||||
|
assert(@int_type(false, 8, false) == u8);
|
||||||
|
assert(@int_type(false, 16, false) == u16);
|
||||||
|
assert(@int_type(false, 32, false) == u32);
|
||||||
|
assert(@int_type(false, 64, false) == u64);
|
||||||
|
|
||||||
|
assert(@int_type(true, 8, true) == i8w);
|
||||||
|
assert(@int_type(true, 16, true) == i16w);
|
||||||
|
assert(@int_type(true, 32, true) == i32w);
|
||||||
|
assert(@int_type(true, 64, true) == i64w);
|
||||||
|
|
||||||
|
assert(@int_type(false, 8, true) == u8w);
|
||||||
|
assert(@int_type(false, 16, true) == u16w);
|
||||||
|
assert(@int_type(false, 32, true) == u32w);
|
||||||
|
assert(@int_type(false, 64, true) == u64w);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue