Fix up some bigint logic issues
This commit is contained in:
parent
752ab8212c
commit
da4d07c665
22
compile.c
22
compile.c
@ -37,7 +37,7 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actual->tag == IntType && needed->tag == NumType) {
|
if ((actual->tag == IntType || actual->tag == BigIntType) && needed->tag == NumType) {
|
||||||
*code = CORD_all(type_to_cord(actual), "_to_", type_to_cord(needed), "(", *code, ")");
|
*code = CORD_all(type_to_cord(actual), "_to_", type_to_cord(needed), "(", *code, ")");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1022,7 +1022,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
|||||||
}
|
}
|
||||||
return loop;
|
return loop;
|
||||||
}
|
}
|
||||||
case IntType: {
|
case BigIntType: {
|
||||||
CORD n = compile(env, for_->iter);
|
CORD n = compile(env, for_->iter);
|
||||||
if (for_->empty) {
|
if (for_->empty) {
|
||||||
return CORD_all(
|
return CORD_all(
|
||||||
@ -1164,7 +1164,7 @@ CORD expr_as_text(env_t *env, CORD expr, type_t *t, CORD color)
|
|||||||
case MemoryType: return CORD_asprintf("Memory$as_text(stack(%r), %r, &$Memory)", expr, color);
|
case MemoryType: return CORD_asprintf("Memory$as_text(stack(%r), %r, &$Memory)", expr, color);
|
||||||
case BoolType: return CORD_asprintf("Bool$as_text((Bool_t[1]){%r}, %r, &$Bool)", expr, color);
|
case BoolType: return CORD_asprintf("Bool$as_text((Bool_t[1]){%r}, %r, &$Bool)", expr, color);
|
||||||
case CStringType: return CORD_asprintf("CString$as_text(stack(%r), %r, &$CString)", expr, color);
|
case CStringType: return CORD_asprintf("CString$as_text(stack(%r), %r, &$CString)", expr, color);
|
||||||
case IntType: {
|
case BigIntType: case IntType: {
|
||||||
CORD name = type_to_cord(t);
|
CORD name = type_to_cord(t);
|
||||||
return CORD_asprintf("%r$as_text(stack(%r), %r, &$%r)", name, expr, color, name);
|
return CORD_asprintf("%r$as_text(stack(%r), %r, &$%r)", name, expr, color, name);
|
||||||
}
|
}
|
||||||
@ -1387,11 +1387,11 @@ CORD compile_math_method(env_t *env, binop_e op, ast_t *lhs, ast_t *rhs, type_t
|
|||||||
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
||||||
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
||||||
} else if (lhs_t->tag == NumType || lhs_t->tag == IntType) {
|
} else if (lhs_t->tag == NumType || lhs_t->tag == IntType || lhs_t->tag == BigIntType) {
|
||||||
binding_t *b = get_namespace_binding(env, rhs, "scaled_by");
|
binding_t *b = get_namespace_binding(env, rhs, "scaled_by");
|
||||||
if (binding_works(b, rhs_t, lhs_t, rhs_t))
|
if (binding_works(b, rhs_t, lhs_t, rhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, rhs), ", ", compile(env, lhs), ")");
|
return CORD_all(b->code, "(", compile(env, rhs), ", ", compile(env, lhs), ")");
|
||||||
} else if (rhs_t->tag == NumType || rhs_t->tag == IntType) {
|
} else if (rhs_t->tag == NumType || rhs_t->tag == IntType|| rhs_t->tag == BigIntType) {
|
||||||
binding_t *b = get_namespace_binding(env, lhs, "scaled_by");
|
binding_t *b = get_namespace_binding(env, lhs, "scaled_by");
|
||||||
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
||||||
@ -1407,7 +1407,7 @@ CORD compile_math_method(env_t *env, binop_e op, ast_t *lhs, ast_t *rhs, type_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_DIVIDE: case BINOP_MOD: case BINOP_MOD1: {
|
case BINOP_DIVIDE: case BINOP_MOD: case BINOP_MOD1: {
|
||||||
if (rhs_t->tag == NumType || rhs_t->tag == IntType) {
|
if (rhs_t->tag == NumType || rhs_t->tag == IntType || rhs_t->tag == BigIntType) {
|
||||||
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
||||||
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
||||||
@ -1415,7 +1415,7 @@ CORD compile_math_method(env_t *env, binop_e op, ast_t *lhs, ast_t *rhs, type_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_LSHIFT: case BINOP_RSHIFT: {
|
case BINOP_LSHIFT: case BINOP_RSHIFT: {
|
||||||
if (rhs_t->tag == IntType) {
|
if (rhs_t->tag == IntType || rhs_t->tag == BigIntType) {
|
||||||
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
||||||
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
||||||
@ -1423,7 +1423,7 @@ CORD compile_math_method(env_t *env, binop_e op, ast_t *lhs, ast_t *rhs, type_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_POWER: {
|
case BINOP_POWER: {
|
||||||
if (rhs_t->tag == NumType || rhs_t->tag == IntType) {
|
if (rhs_t->tag == NumType || rhs_t->tag == IntType || rhs_t->tag == BigIntType) {
|
||||||
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
binding_t *b = get_namespace_binding(env, lhs, binop_method_names[op]);
|
||||||
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
if (binding_works(b, lhs_t, rhs_t, lhs_t))
|
||||||
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
return CORD_all(b->code, "(", compile(env, lhs), ", ", compile(env, rhs), ")");
|
||||||
@ -2677,7 +2677,7 @@ CORD compile(env_t *env, ast_t *ast)
|
|||||||
type_t *container_t = value_type(indexed_type);
|
type_t *container_t = value_type(indexed_type);
|
||||||
type_t *index_t = get_type(env, indexing->index);
|
type_t *index_t = get_type(env, indexing->index);
|
||||||
if (container_t->tag == ArrayType) {
|
if (container_t->tag == ArrayType) {
|
||||||
if (index_t->tag != IntType)
|
if (index_t->tag != IntType && index_t->tag != BigIntType)
|
||||||
code_err(indexing->index, "Arrays can only be indexed by integers, not %T", index_t);
|
code_err(indexing->index, "Arrays can only be indexed by integers, not %T", index_t);
|
||||||
type_t *item_type = Match(container_t, ArrayType)->item_type;
|
type_t *item_type = Match(container_t, ArrayType)->item_type;
|
||||||
CORD arr = compile_to_pointer_depth(env, indexing->indexed, 0, false);
|
CORD arr = compile_to_pointer_depth(env, indexing->indexed, 0, false);
|
||||||
@ -2792,7 +2792,7 @@ CORD compile_namespace_definitions(env_t *env, const char *ns_name, ast_t *block
|
|||||||
CORD compile_type_info(env_t *env, type_t *t)
|
CORD compile_type_info(env_t *env, type_t *t)
|
||||||
{
|
{
|
||||||
switch (t->tag) {
|
switch (t->tag) {
|
||||||
case BoolType: case IntType: case NumType: case CStringType:
|
case BoolType: case IntType: case BigIntType: case NumType: case CStringType:
|
||||||
return CORD_asprintf("&$%r", type_to_cord(t));
|
return CORD_asprintf("&$%r", type_to_cord(t));
|
||||||
case TextType: {
|
case TextType: {
|
||||||
auto text = Match(t, TextType);
|
auto text = Match(t, TextType);
|
||||||
@ -2930,7 +2930,7 @@ CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type)
|
|||||||
"}\n");
|
"}\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IntType: case NumType: {
|
case IntType: case BigIntType: case NumType: {
|
||||||
CORD type_name = type_to_cord(t);
|
CORD type_name = type_to_cord(t);
|
||||||
code = CORD_all(code, "else if (pop_flag(argv, &i, \"", flag, "\", &flag)) {\n",
|
code = CORD_all(code, "else if (pop_flag(argv, &i, \"", flag, "\", &flag)) {\n",
|
||||||
"if (flag == CORD_EMPTY)\n"
|
"if (flag == CORD_EMPTY)\n"
|
||||||
|
@ -411,7 +411,7 @@ env_t *for_scope(env_t *env, ast_t *ast)
|
|||||||
}
|
}
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
case IntType: {
|
case BigIntType: {
|
||||||
if (for_->vars) {
|
if (for_->vars) {
|
||||||
if (for_->vars->next)
|
if (for_->vars->next)
|
||||||
code_err(for_->vars->next->ast, "This is too many variables for this loop");
|
code_err(for_->vars->next->ast, "This is too many variables for this loop");
|
||||||
@ -495,7 +495,7 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name)
|
|||||||
switch (cls_type->tag) {
|
switch (cls_type->tag) {
|
||||||
case ArrayType: return NULL;
|
case ArrayType: return NULL;
|
||||||
case TableType: return NULL;
|
case TableType: return NULL;
|
||||||
case BoolType: case IntType: case NumType: {
|
case BoolType: case IntType: case BigIntType: case NumType: {
|
||||||
binding_t *b = get_binding(env, CORD_to_const_char_star(type_to_cord(cls_type)));
|
binding_t *b = get_binding(env, CORD_to_const_char_star(type_to_cord(cls_type)));
|
||||||
assert(b);
|
assert(b);
|
||||||
return get_binding(Match(b->type, TypeInfoType)->env, name);
|
return get_binding(Match(b->type, TypeInfoType)->env, name);
|
||||||
@ -519,7 +519,6 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name)
|
|||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
code_err(self, "No such method!");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
typecheck.c
24
typecheck.c
@ -687,9 +687,8 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
if (value_t->tag == ArrayType) {
|
if (value_t->tag == ArrayType) {
|
||||||
if (!indexing->index) return indexed_t;
|
if (!indexing->index) return indexed_t;
|
||||||
type_t *index_t = get_type(env, indexing->index);
|
type_t *index_t = get_type(env, indexing->index);
|
||||||
if (index_t->tag == IntType) {
|
if (index_t->tag == IntType || index_t->tag == BigIntType)
|
||||||
return Match(value_t, ArrayType)->item_type;
|
return Match(value_t, ArrayType)->item_type;
|
||||||
}
|
|
||||||
code_err(indexing->index, "I only know how to index lists using integers, not %T", index_t);
|
code_err(indexing->index, "I only know how to index lists using integers, not %T", index_t);
|
||||||
} else if (value_t->tag == TableType) {
|
} else if (value_t->tag == TableType) {
|
||||||
code_err(ast, "Tables use the table:get(key) method, not square bracket indexing like table[key]");
|
code_err(ast, "Tables use the table:get(key) method, not square bracket indexing like table[key]");
|
||||||
@ -705,7 +704,8 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
|
|
||||||
if (fn_type_t->tag == TypeInfoType) {
|
if (fn_type_t->tag == TypeInfoType) {
|
||||||
type_t *t = Match(fn_type_t, TypeInfoType)->type;
|
type_t *t = Match(fn_type_t, TypeInfoType)->type;
|
||||||
if (t->tag == StructType || t->tag == IntType || t->tag == NumType || t->tag == TextType || t->tag == CStringType)
|
if (t->tag == StructType || t->tag == IntType || t->tag == BigIntType || t->tag == NumType
|
||||||
|
|| t->tag == TextType || t->tag == CStringType)
|
||||||
return t; // Constructor
|
return t; // Constructor
|
||||||
code_err(call->fn, "This is not a type that has a constructor");
|
code_err(call->fn, "This is not a type that has a constructor");
|
||||||
}
|
}
|
||||||
@ -898,9 +898,9 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
// Check for a binop method like plus() etc:
|
// Check for a binop method like plus() etc:
|
||||||
switch (binop->op) {
|
switch (binop->op) {
|
||||||
case BINOP_MULT: {
|
case BINOP_MULT: {
|
||||||
if ((lhs_t->tag == NumType || lhs_t->tag == IntType) && binding_works("scaled_by", binop->rhs, rhs_t, lhs_t, rhs_t))
|
if (is_numeric_type(lhs_t) && binding_works("scaled_by", binop->rhs, rhs_t, lhs_t, rhs_t))
|
||||||
return rhs_t;
|
return rhs_t;
|
||||||
else if ((rhs_t->tag == NumType || rhs_t->tag == IntType) && binding_works("scaled_by", binop->lhs, lhs_t, rhs_t, lhs_t))
|
else if (is_numeric_type(rhs_t) && binding_works("scaled_by", binop->lhs, lhs_t, rhs_t, lhs_t))
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
else if (type_eq(lhs_t, rhs_t) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
else if (type_eq(lhs_t, rhs_t) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
@ -912,17 +912,17 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_DIVIDE: case BINOP_MOD: case BINOP_MOD1: {
|
case BINOP_DIVIDE: case BINOP_MOD: case BINOP_MOD1: {
|
||||||
if ((rhs_t->tag == NumType || rhs_t->tag == IntType) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
if (is_numeric_type(rhs_t) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_LSHIFT: case BINOP_RSHIFT: {
|
case BINOP_LSHIFT: case BINOP_RSHIFT: {
|
||||||
if (rhs_t->tag == IntType && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
if (is_int_type(rhs_t) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BINOP_POWER: {
|
case BINOP_POWER: {
|
||||||
if ((rhs_t->tag == NumType || rhs_t->tag == IntType) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
if (is_numeric_type(rhs_t) && binding_works(binop_method_names[binop->op], binop->lhs, lhs_t, rhs_t, lhs_t))
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -944,7 +944,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
if (type_eq(lhs_ptr->pointed, rhs_ptr->pointed))
|
if (type_eq(lhs_ptr->pointed, rhs_ptr->pointed))
|
||||||
return Type(PointerType, .pointed=lhs_ptr->pointed, .is_optional=lhs_ptr->is_optional || rhs_ptr->is_optional,
|
return Type(PointerType, .pointed=lhs_ptr->pointed, .is_optional=lhs_ptr->is_optional || rhs_ptr->is_optional,
|
||||||
.is_readonly=lhs_ptr->is_readonly || rhs_ptr->is_readonly);
|
.is_readonly=lhs_ptr->is_readonly || rhs_ptr->is_readonly);
|
||||||
} else if (lhs_t->tag == IntType && rhs_t->tag == IntType) {
|
} else if (is_int_type(lhs_t) && is_int_type(rhs_t)) {
|
||||||
return get_math_type(env, ast, lhs_t, rhs_t);
|
return get_math_type(env, ast, lhs_t, rhs_t);
|
||||||
}
|
}
|
||||||
code_err(ast, "I can't figure out the type of this `and` expression because the left side is a %T, but the right side is a %T",
|
code_err(ast, "I can't figure out the type of this `and` expression because the left side is a %T, but the right side is a %T",
|
||||||
@ -955,7 +955,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
return lhs_t;
|
return lhs_t;
|
||||||
} else if (lhs_t->tag == BoolType && (rhs_t->tag == AbortType || rhs_t->tag == ReturnType)) {
|
} else if (lhs_t->tag == BoolType && (rhs_t->tag == AbortType || rhs_t->tag == ReturnType)) {
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
} else if (lhs_t->tag == IntType && rhs_t->tag == IntType) {
|
} else if (is_int_type(lhs_t) && is_int_type(rhs_t)) {
|
||||||
return get_math_type(env, ast, lhs_t, rhs_t);
|
return get_math_type(env, ast, lhs_t, rhs_t);
|
||||||
} else if (lhs_t->tag == PointerType) {
|
} else if (lhs_t->tag == PointerType) {
|
||||||
auto lhs_ptr = Match(lhs_t, PointerType);
|
auto lhs_ptr = Match(lhs_t, PointerType);
|
||||||
@ -974,7 +974,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
case BINOP_XOR: {
|
case BINOP_XOR: {
|
||||||
if (lhs_t->tag == BoolType && rhs_t->tag == BoolType) {
|
if (lhs_t->tag == BoolType && rhs_t->tag == BoolType) {
|
||||||
return lhs_t;
|
return lhs_t;
|
||||||
} else if (lhs_t->tag == IntType && rhs_t->tag == IntType) {
|
} else if (is_int_type(lhs_t) && is_int_type(rhs_t)) {
|
||||||
return get_math_type(env, ast, lhs_t, rhs_t);
|
return get_math_type(env, ast, lhs_t, rhs_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +1016,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
|||||||
type_t *value_t;
|
type_t *value_t;
|
||||||
type_t *iter_value_t = value_type(iter_t);
|
type_t *iter_value_t = value_type(iter_t);
|
||||||
switch (iter_value_t->tag) {
|
switch (iter_value_t->tag) {
|
||||||
case IntType: value_t = iter_value_t; break;
|
case BigIntType: case IntType: value_t = iter_value_t; break;
|
||||||
case ArrayType: value_t = Match(iter_value_t, ArrayType)->item_type; break;
|
case ArrayType: value_t = Match(iter_value_t, ArrayType)->item_type; break;
|
||||||
case TableType: value_t = Match(iter_value_t, TableType)->key_type; break;
|
case TableType: value_t = Match(iter_value_t, TableType)->key_type; break;
|
||||||
case FunctionType: case ClosureType: {
|
case FunctionType: case ClosureType: {
|
||||||
|
15
types.c
15
types.c
@ -273,7 +273,10 @@ bool can_promote(type_t *actual, type_t *needed)
|
|||||||
if (actual->tag == NumType && needed->tag == IntType)
|
if (actual->tag == NumType && needed->tag == IntType)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actual->tag == IntType && needed->tag == NumType)
|
if (actual->tag == IntType && (needed->tag == NumType || needed->tag == BigIntType))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (actual->tag == BigIntType && needed->tag == NumType)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (actual->tag == IntType && needed->tag == IntType) {
|
if (actual->tag == IntType && needed->tag == IntType) {
|
||||||
@ -402,6 +405,16 @@ bool can_have_cycles(type_t *t)
|
|||||||
return _can_have_cycles(t, &seen);
|
return _can_have_cycles(t, &seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_int_type(type_t *t)
|
||||||
|
{
|
||||||
|
return t->tag == IntType || t->tag == BigIntType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_numeric_type(type_t *t)
|
||||||
|
{
|
||||||
|
return t->tag == IntType || t->tag == BigIntType || t->tag == NumType;
|
||||||
|
}
|
||||||
|
|
||||||
type_t *replace_type(type_t *t, type_t *target, type_t *replacement)
|
type_t *replace_type(type_t *t, type_t *target, type_t *replacement)
|
||||||
{
|
{
|
||||||
if (type_eq(t, target))
|
if (type_eq(t, target))
|
||||||
|
2
types.h
2
types.h
@ -141,6 +141,8 @@ bool can_send_over_channel(type_t *t);
|
|||||||
bool can_promote(type_t *actual, type_t *needed);
|
bool can_promote(type_t *actual, type_t *needed);
|
||||||
bool can_leave_uninitialized(type_t *t);
|
bool can_leave_uninitialized(type_t *t);
|
||||||
bool can_have_cycles(type_t *t);
|
bool can_have_cycles(type_t *t);
|
||||||
|
bool is_int_type(type_t *t);
|
||||||
|
bool is_numeric_type(type_t *t);
|
||||||
type_t *replace_type(type_t *t, type_t *target, type_t *replacement);
|
type_t *replace_type(type_t *t, type_t *target, type_t *replacement);
|
||||||
size_t type_size(type_t *t);
|
size_t type_size(type_t *t);
|
||||||
size_t type_align(type_t *t);
|
size_t type_align(type_t *t);
|
||||||
|
Loading…
Reference in New Issue
Block a user