Compound arrays
This commit is contained in:
26
ast.cpp
26
ast.cpp
@@ -60,17 +60,17 @@ struct Ast{
|
||||
Ast_Flag flags;
|
||||
};
|
||||
|
||||
struct Ast_Resolved_Type;
|
||||
struct Ast_Type;
|
||||
struct Ast_Expr:Ast{ };
|
||||
|
||||
#define VALUE_FIELDS \
|
||||
Ast_Resolved_Type *type; \
|
||||
Ast_Type *type; \
|
||||
union{ \
|
||||
bool bool_val; \
|
||||
F64 f64_val; \
|
||||
Intern_String intern_val; \
|
||||
BigInt big_int_val;\
|
||||
Ast_Resolved_Type *type_val; \
|
||||
Ast_Type *type_val; \
|
||||
};
|
||||
#define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};}
|
||||
struct Value{VALUE_FIELDS};
|
||||
@@ -82,7 +82,7 @@ struct Ast_Atom: Ast_Expr{
|
||||
};
|
||||
|
||||
struct Ast_Call_Item: Ast_Expr{
|
||||
Ast_Atom *name;
|
||||
Ast_Atom *name; // for calls only name, for compounds name | index
|
||||
Ast_Expr *item;
|
||||
Ast_Expr *index;
|
||||
};
|
||||
@@ -93,27 +93,27 @@ struct Ast_Call: Ast_Expr{
|
||||
Ast_Expr *typespec;
|
||||
};
|
||||
Array<Ast_Call_Item *> exprs;
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
};
|
||||
|
||||
struct Ast_Unary: Ast_Expr{
|
||||
Token_Kind op;
|
||||
Ast_Expr *expr;
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
U64 padding[2]; // For folding constants into atoms
|
||||
};
|
||||
|
||||
struct Ast_Cast: Ast_Expr{
|
||||
Ast_Expr *expr;
|
||||
Ast_Expr *typespec;
|
||||
Ast_Resolved_Type *before_type;
|
||||
Ast_Resolved_Type *after_type;
|
||||
Ast_Type *before_type;
|
||||
Ast_Type *after_type;
|
||||
};
|
||||
|
||||
struct Ast_Index: Ast_Expr{
|
||||
Ast_Expr *expr;
|
||||
Ast_Expr *index;
|
||||
Ast_Resolved_Type *original_type;
|
||||
Ast_Type *original_type;
|
||||
};
|
||||
|
||||
struct Ast_Binary: Ast_Expr{
|
||||
@@ -121,7 +121,7 @@ struct Ast_Binary: Ast_Expr{
|
||||
Ast_Expr *left;
|
||||
Ast_Expr *right;
|
||||
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
};
|
||||
|
||||
// Problem: We are parsing out of order, in the middle of parsing a function
|
||||
@@ -157,13 +157,13 @@ struct Ast_Lambda : Ast_Expr {
|
||||
Array<Ast_Decl *> args;
|
||||
Ast_Expr *ret;
|
||||
Ast_Scope *scope;
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
};
|
||||
|
||||
struct Ast_Array: Ast_Expr{
|
||||
Ast_Expr *base;
|
||||
Ast_Expr *expr;
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -466,7 +466,7 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
||||
}
|
||||
|
||||
function Ast_Decl *
|
||||
ast_type(Token *pos, Intern_String name, Ast_Resolved_Type *type){
|
||||
ast_type(Token *pos, Intern_String name, Ast_Type *type){
|
||||
AST_NEW(Decl, TYPE, pos, AST_DECL);
|
||||
result->type = type_type;
|
||||
result->type_val = type;
|
||||
|
||||
23
ccodegen.cpp
23
ccodegen.cpp
@@ -28,7 +28,7 @@ gen_line(Ast *node){
|
||||
// 4 Add type name on the left side
|
||||
|
||||
function void
|
||||
gen_simple_decl_prefix(Ast_Resolved_Type *ast){
|
||||
gen_simple_decl_prefix(Ast_Type *ast){
|
||||
switch(ast->kind){
|
||||
case TYPE_POINTER: gen_simple_decl_prefix(ast->base); gen("*"); break;
|
||||
case TYPE_ARRAY: gen_simple_decl_prefix(ast->base); break;
|
||||
@@ -46,7 +46,7 @@ gen_simple_decl_prefix(Ast_Resolved_Type *ast){
|
||||
}
|
||||
|
||||
function void
|
||||
gen_simple_decl_postfix(Ast_Resolved_Type *ast){
|
||||
gen_simple_decl_postfix(Ast_Type *ast){
|
||||
switch(ast->kind){
|
||||
case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break;
|
||||
case TYPE_ARRAY:
|
||||
@@ -62,7 +62,7 @@ gen_simple_decl_postfix(Ast_Resolved_Type *ast){
|
||||
}
|
||||
|
||||
function void
|
||||
gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){
|
||||
gen_simple_decl(Ast_Type *ast, Intern_String name = {}){
|
||||
if(ast->kind == TYPE_LAMBDA) {
|
||||
gen_simple_decl_prefix(ast->func.ret);
|
||||
gen("(*%s)(", name.str);
|
||||
@@ -117,7 +117,7 @@ enum {
|
||||
};
|
||||
|
||||
function void
|
||||
gen_var(Intern_String name, Ast_Resolved_Type *type, Ast_Expr *expr, B32 emit_value){
|
||||
gen_var(Intern_String name, Ast_Type *type, Ast_Expr *expr, B32 emit_value){
|
||||
gen_simple_decl(type, name);
|
||||
|
||||
if(emit_value == DONT_EMIT_VALUE){
|
||||
@@ -211,7 +211,7 @@ gen_expr(Ast_Expr *ast){
|
||||
CASE(CAST, Cast){
|
||||
gen("(");
|
||||
gen("(");
|
||||
gen_simple_decl(node->after_type, {});
|
||||
gen_simple_decl(node->after_type);
|
||||
gen(")");
|
||||
gen_expr(node->expr);
|
||||
gen(")");
|
||||
@@ -234,6 +234,19 @@ gen_expr(Ast_Expr *ast){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(COMPOUND, Call){
|
||||
gen("(");
|
||||
gen_simple_decl(node->type);
|
||||
gen(")");
|
||||
gen("{");
|
||||
For(node->exprs){
|
||||
gen_expr(it->item);
|
||||
if(!node->exprs.is_last(&it)) gen(", ");
|
||||
}
|
||||
gen("}");
|
||||
BREAK();
|
||||
}
|
||||
|
||||
invalid_default_case;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ Boolean: Bool = true
|
||||
// Compound expressions
|
||||
//-----------------------------------------------------------------------------
|
||||
array1: [4]S64 = {1,2,3,4}
|
||||
|
||||
imp_array := [5]S64{1,2}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Pointers
|
||||
|
||||
@@ -218,7 +218,7 @@ constexpr S128 U8_max() {return {0, U8MAX};}
|
||||
constexpr S128 U8_min() {return {};}
|
||||
|
||||
function B32
|
||||
is_out_of_bounds(S128 value, Ast_Resolved_Type *type){
|
||||
is_out_of_bounds(S128 value, Ast_Type *type){
|
||||
#define BOUNDS_CASE(T) case TYPE_##T: return (value < T##_min()) || (value > T##_max())
|
||||
switch(type->kind){
|
||||
BOUNDS_CASE(S8);
|
||||
|
||||
28
main.cpp
28
main.cpp
@@ -77,6 +77,7 @@ Expr:
|
||||
|
||||
|
||||
@todo
|
||||
[ ] - Remodel compound from call to {}
|
||||
[ ] - Switch
|
||||
[ ] - Add c string
|
||||
[ ] - Some way to take slice of data
|
||||
@@ -86,14 +87,7 @@ Expr:
|
||||
[ ] - Array of inferred size
|
||||
[ ] - Add single line lambda expressions
|
||||
[ ] - Ternary operator
|
||||
[ ] - Remodel compound from call to {}
|
||||
|
||||
[ ] - Scope
|
||||
[ ] - Field access rewrite
|
||||
[ ] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix
|
||||
[ ] - Order independent constants in structs
|
||||
[ ] - Fix recursive lambdas in structs
|
||||
[ ] - Fixing access to functions/structs, in C we cant have functons inside of structs / functions so we need to rewrite the tree
|
||||
[ ] - Disable ability to parse inner structs, functions, constants etc. ?
|
||||
[ ] - Write up on order independent declarations
|
||||
|
||||
[ ] - Casting to basic types by call S64(x)
|
||||
@@ -111,6 +105,12 @@ Expr:
|
||||
[ ] - Conditional compilation #if
|
||||
|
||||
@donzo
|
||||
[x] - Scope
|
||||
[x] - Field access rewrite
|
||||
[-] - Constants embeded in structs should be able to refer to other constants in that namespace without prefix
|
||||
[-] - Order independent constants in structs
|
||||
[-] - Fix recursive lambdas in structs
|
||||
[-] - Fixing access to functions/structs, in C we cant have functons inside of structs / functions so we need to rewrite the tree
|
||||
[x] - Emitting #line
|
||||
[x] - Making sure debugger works
|
||||
[x] - We need ++ -- operators
|
||||
@@ -203,13 +203,13 @@ int main(int argument_count, char **arguments){
|
||||
#endif
|
||||
Scratch scratch;
|
||||
Array<String> files = {scratch};
|
||||
files.add("lambdas.kl"_s);
|
||||
files.add("order1.kl"_s);
|
||||
files.add("order2.kl"_s);
|
||||
files.add("new_types.kl"_s);
|
||||
files.add("enums.kl"_s);
|
||||
// files.add("lambdas.kl"_s);
|
||||
// files.add("order1.kl"_s);
|
||||
// files.add("order2.kl"_s);
|
||||
// files.add("new_types.kl"_s);
|
||||
// files.add("enums.kl"_s);
|
||||
files.add("globals.kl"_s);
|
||||
files.add("euler.kl"_s);
|
||||
// files.add("euler.kl"_s);
|
||||
String result = compile_files(files);
|
||||
printf("%s", result.str);
|
||||
__debugbreak();
|
||||
|
||||
119
typechecking.cpp
119
typechecking.cpp
@@ -16,7 +16,7 @@ check_value_bounds(Token *pos, Value *a){
|
||||
}
|
||||
|
||||
function Value
|
||||
convert_untyped_to_typed(Token *pos, Value a, Ast_Resolved_Type *new_type){
|
||||
convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){
|
||||
assert(new_type);
|
||||
if(a.type == 0) return a;
|
||||
if(is_typed(a.type)) return a;
|
||||
@@ -193,7 +193,7 @@ digit_count(const Value *a){
|
||||
function void
|
||||
eval_unary(Token *pos, Token_Kind op, Operand *operand){
|
||||
Value *a = &operand->value;
|
||||
Ast_Resolved_Type *type = a->type;
|
||||
Ast_Type *type = a->type;
|
||||
if(!is_numeric(type))
|
||||
compiler_error(pos, "Unary [%s] cant be applied to value of type %s", name(op), docname(type));
|
||||
|
||||
@@ -268,7 +268,7 @@ enum{
|
||||
};
|
||||
|
||||
function void
|
||||
make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Resolved_Type *type, U64 debug_flag){
|
||||
make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *type, U64 debug_flag){
|
||||
if(type == expr->type){
|
||||
assert(type);
|
||||
assert(expr->type);
|
||||
@@ -359,7 +359,7 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
||||
}
|
||||
|
||||
function void
|
||||
insert_type_into_package(Ast_Package *p, String name, Ast_Resolved_Type *type){
|
||||
insert_type_into_package(Ast_Package *p, String name, Ast_Type *type){
|
||||
Intern_String string = pctx->intern(name);
|
||||
Ast_Decl *decl = ast_type(&null_token, string, type);
|
||||
decl->parent_scope = p;
|
||||
@@ -384,12 +384,12 @@ insert_builtin_types_into_package(Ast_Package *p){
|
||||
insert_type_into_package(p, "F64"_s, type_f64);
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags){
|
||||
function Ast_Type *
|
||||
resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL))
|
||||
return 0;
|
||||
|
||||
Operand resolved = resolve_expr(ast, flags);
|
||||
Operand resolved = resolve_expr(ast, flags, compound_context);
|
||||
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
|
||||
type_complete(resolved.type);
|
||||
if(resolved.type != type_type)
|
||||
@@ -398,14 +398,14 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags){
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags){
|
||||
resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
if(!expr){
|
||||
if(flags == AST_CAN_BE_NULL)
|
||||
return {};
|
||||
else compiler_error(0, "Compiler error: Null expression");
|
||||
}
|
||||
|
||||
Operand op = resolve_expr(expr, flags);
|
||||
Operand op = resolve_expr(expr, flags, compound_context);
|
||||
if(!is_bool(op.type)){
|
||||
compiler_error(expr->pos, "Expected type [Bool] got instead type %s :: %s", docname(op.type), error);
|
||||
}
|
||||
@@ -414,8 +414,8 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags){
|
||||
}
|
||||
|
||||
function Operand
|
||||
require_const_int(Ast_Expr *expr, Resolve_Flag flags){
|
||||
Operand op = resolve_expr(expr, flags);
|
||||
require_const_int(Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context = 0){
|
||||
Operand op = resolve_expr(expr, flags, compound_context);
|
||||
|
||||
if(expr == 0 && flags)
|
||||
return op;
|
||||
@@ -433,7 +433,7 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags){
|
||||
// @note: Ret is return value of function passed down the stack
|
||||
// to check if type matches
|
||||
function void
|
||||
resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
||||
resolve_stmt(Ast *ast, Ast_Type *ret){
|
||||
if(!ast) return;
|
||||
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_PACKAGE);
|
||||
|
||||
@@ -496,15 +496,15 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
|
||||
}
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
function Ast_Type *
|
||||
resolve_lambda_type(Ast_Lambda *lambda){
|
||||
Scratch scratch;
|
||||
Ast_Resolved_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL);
|
||||
Array<Ast_Resolved_Type *> args = {scratch};
|
||||
Ast_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL);
|
||||
Array<Ast_Type *> args = {scratch};
|
||||
|
||||
For(lambda->args){
|
||||
Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL);
|
||||
Ast_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
|
||||
Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL, type);
|
||||
make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL);
|
||||
it->type = type;
|
||||
args.add(type);
|
||||
@@ -514,7 +514,7 @@ resolve_lambda_type(Ast_Lambda *lambda){
|
||||
}
|
||||
|
||||
function void
|
||||
try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Resolved_Type *lambda_type){
|
||||
try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Type *lambda_type){
|
||||
if(lambda->scope){
|
||||
For(lambda->args){
|
||||
insert_into_scope(lambda->scope, it);
|
||||
@@ -534,8 +534,8 @@ try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Resolved_Type *l
|
||||
function Operand
|
||||
resolve_cast(Ast_Cast *node){
|
||||
Operand expr = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CANT_BE_NULL);
|
||||
Ast_Resolved_Type *original_type = expr.type;
|
||||
Ast_Type *type = resolve_typespec(node->typespec, AST_CANT_BE_NULL);
|
||||
Ast_Type *original_type = expr.type;
|
||||
node->before_type = expr.type;
|
||||
|
||||
switch(expr.type->kind){
|
||||
@@ -580,6 +580,43 @@ resolve_cast(Ast_Cast *node){
|
||||
return expr;
|
||||
}
|
||||
|
||||
function void
|
||||
resolve_compound_array(Ast_Call *node, Ast_Type *type){
|
||||
Ast_Type *item_type = type->arr.base;
|
||||
S64 size = type->arr.size;
|
||||
|
||||
if(node->exprs.len > size)
|
||||
compiler_error(node->pos, "Too many items in compound expression, expected: %lld got: %lld", size, node->exprs.len);
|
||||
|
||||
S64 default_counter = 0;
|
||||
For(node->exprs){
|
||||
if(it->name)
|
||||
compiler_error(it->pos, "Array doesn't have named fields");
|
||||
|
||||
if(it->index){
|
||||
default_counter = -1;
|
||||
Operand op = require_const_int(it->index, AST_CANT_BE_NULL);
|
||||
S64 i = bigint_as_signed(&op.value.big_int_val); // @todo: what happens when big num is here???
|
||||
|
||||
if(i >= size)
|
||||
compiler_error(it->pos, "Index %lld is out of range of array of size %lld", i, size);
|
||||
|
||||
}
|
||||
else{
|
||||
if(default_counter == -1)
|
||||
compiler_error(it->pos, "Mixing expicit indexes and default is illegal");
|
||||
}
|
||||
|
||||
Operand item = resolve_expr(it->item, AST_CANT_BE_NULL);
|
||||
make_sure_value_is_compatible_with_type(it->pos, &item, item_type, TYPE_AND_EXPR_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
function void
|
||||
resolve_compound_struct(Ast_Call *node, Ast_Type *type){
|
||||
|
||||
}
|
||||
|
||||
global Ast_Scope *field_access_scope; // @memes
|
||||
|
||||
function Operand
|
||||
@@ -605,7 +642,7 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
||||
field_access_scope = context;
|
||||
Operand op = resolve_expr(node, AST_CANT_BE_NULL);
|
||||
|
||||
Ast_Resolved_Type *type = op.type;
|
||||
Ast_Type *type = op.type;
|
||||
if(op.type == type_type && is_enum(op.type_val)) type = op.type_val;
|
||||
if(current) current->type = type;
|
||||
if(is_pointer(type)) type = type->base;
|
||||
@@ -626,7 +663,7 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
|
||||
}
|
||||
|
||||
function Operand
|
||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
||||
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
|
||||
assert(is_flag_set(ast->flags, AST_EXPR));
|
||||
assert(ast->parent_scope->kind == AST_SCOPE || ast->parent_scope->kind == AST_PACKAGE);
|
||||
@@ -769,6 +806,34 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(COMPOUND, Call){
|
||||
Operand op = resolve_expr(node->typespec, AST_CAN_BE_NULL);
|
||||
|
||||
Ast_Type *type = op.type;
|
||||
if(type){
|
||||
if(type != type_type)
|
||||
compiler_error(node->pos, "Expected type [Type] got instead %s", docname(type));
|
||||
type = op.type_val;
|
||||
}
|
||||
if(!type)
|
||||
type = compound_context;
|
||||
if(!type)
|
||||
compiler_error(node->pos, "Couldn't infer type of compound expression");
|
||||
|
||||
type_complete(type);
|
||||
node->type = type;
|
||||
if(is_array(type)){
|
||||
resolve_compound_array(node, type);
|
||||
}
|
||||
else if(is_struct(type)){
|
||||
resolve_compound_struct(node, type);
|
||||
}
|
||||
|
||||
return operand_lvalue(type);
|
||||
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(CALL, Call){
|
||||
Operand name = resolve_expr(node->name, AST_CANT_BE_NULL);
|
||||
if(name.type->kind != TYPE_LAMBDA)
|
||||
@@ -807,7 +872,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){
|
||||
|
||||
if(item){
|
||||
set_flag(item->flags, AST_ITEM_INCLUDED);
|
||||
Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL);
|
||||
Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type);
|
||||
make_sure_value_is_compatible_with_type(node->pos, &expr, lambda_arg->type, TYPE_AND_EXPR_REQUIRED);
|
||||
items.add(item);
|
||||
}
|
||||
@@ -868,6 +933,8 @@ resolve_decl(Ast_Decl *ast){
|
||||
}
|
||||
|
||||
CASE(CONST, Decl){
|
||||
// @warning: if in the future we add type here then pass it to resolve expr for
|
||||
// compound
|
||||
Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL);
|
||||
if(!op.is_const){
|
||||
compiler_error(node->pos, "Assigning a value that is not constant to a constant declaration");
|
||||
@@ -883,8 +950,8 @@ resolve_decl(Ast_Decl *ast){
|
||||
}
|
||||
|
||||
CASE(VAR, Decl){
|
||||
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL | RESOLVE_TYPESPEC_COMPLETE);
|
||||
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL);
|
||||
Ast_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL | RESOLVE_TYPESPEC_COMPLETE);
|
||||
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL, type);
|
||||
assert(op.type != 0 || type != 0);
|
||||
|
||||
make_sure_value_is_compatible_with_type(node->pos, &op, type, EXPR_CAN_BE_NULL|TYPE_CAN_BE_NULL);
|
||||
@@ -893,7 +960,7 @@ resolve_decl(Ast_Decl *ast){
|
||||
}
|
||||
|
||||
CASE(ENUM, Decl){
|
||||
Ast_Resolved_Type *type_of_enum = resolve_typespec(node->typespec, AST_CAN_BE_NULL);
|
||||
Ast_Type *type_of_enum = resolve_typespec(node->typespec, AST_CAN_BE_NULL);
|
||||
|
||||
node->type = type_type;
|
||||
node->type_val = type_enum(node, type_of_enum);
|
||||
|
||||
@@ -16,7 +16,7 @@ FLAG32(Search_Flag){
|
||||
SEARCH_ALSO_FOR_PACKAGE = bit_flag(2),
|
||||
};
|
||||
|
||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags);
|
||||
function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0);
|
||||
function void resolve_decl(Ast_Decl *ast);
|
||||
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
|
||||
|
||||
@@ -34,7 +34,7 @@ operand(Ast_Decl *sym){
|
||||
}
|
||||
|
||||
function Operand
|
||||
operand_type(Ast_Resolved_Type *type){
|
||||
operand_type(Ast_Type *type){
|
||||
Operand result = {};
|
||||
result.type = type_type;
|
||||
result.is_const = true;
|
||||
@@ -64,7 +64,7 @@ operand_str(Intern_String intern_val){
|
||||
}
|
||||
|
||||
function Operand
|
||||
operand_lambda(Ast_Resolved_Type *type){
|
||||
operand_lambda(Ast_Type *type){
|
||||
Operand result = {};
|
||||
result.type = type;
|
||||
result.is_const = true;
|
||||
@@ -81,7 +81,7 @@ operand_const_rvalue(Value value){
|
||||
}
|
||||
|
||||
function Operand
|
||||
operand_lvalue(Ast_Resolved_Type *type){
|
||||
operand_lvalue(Ast_Type *type){
|
||||
Operand result = {};
|
||||
result.type = type;
|
||||
result.is_const = false;
|
||||
@@ -90,7 +90,7 @@ operand_lvalue(Ast_Resolved_Type *type){
|
||||
}
|
||||
|
||||
function Operand
|
||||
operand_rvalue(Ast_Resolved_Type *type){
|
||||
operand_rvalue(Ast_Type *type){
|
||||
Operand result = {};
|
||||
result.type = type;
|
||||
result.is_const = false;
|
||||
@@ -101,25 +101,25 @@ operand_rvalue(Ast_Resolved_Type *type){
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hash consed types
|
||||
//-----------------------------------------------------------------------------
|
||||
function Ast_Resolved_Type *
|
||||
type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){
|
||||
Ast_Resolved_Type *result = exp_alloc_type(allocator, Ast_Resolved_Type, AF_ZeroMemory);
|
||||
function Ast_Type *
|
||||
type_new(Allocator *allocator, Ast_Type_Kind kind, SizeU size, SizeU align){
|
||||
Ast_Type *result = exp_alloc_type(allocator, Ast_Type, AF_ZeroMemory);
|
||||
result->kind = kind;
|
||||
result->size = size;
|
||||
result->align = align;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
type_copy(Allocator *a, Ast_Resolved_Type *type){
|
||||
Ast_Resolved_Type *result = exp_alloc_type(a, Ast_Resolved_Type);
|
||||
memory_copy(result, type, sizeof(Ast_Resolved_Type));
|
||||
function Ast_Type *
|
||||
type_copy(Allocator *a, Ast_Type *type){
|
||||
Ast_Type *result = exp_alloc_type(a, Ast_Type);
|
||||
memory_copy(result, type, sizeof(Ast_Type));
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
type_pointer(Ast_Resolved_Type *base){
|
||||
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, (void *)base);
|
||||
function Ast_Type *
|
||||
type_pointer(Ast_Type *base){
|
||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base);
|
||||
if(!result){
|
||||
result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align);
|
||||
result->base = base;
|
||||
@@ -129,15 +129,15 @@ type_pointer(Ast_Resolved_Type *base){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
type_array(Ast_Resolved_Type *base, B32 size_present, S64 size){
|
||||
function Ast_Type *
|
||||
type_array(Ast_Type *base, B32 size_present, S64 size){
|
||||
if(!size_present){
|
||||
size = ARRAY_SIZE_INFERRED;
|
||||
}
|
||||
|
||||
U64 hash_base = hash_ptr(base);
|
||||
U64 hash = hash_mix(hash_base, hash_u64(size));
|
||||
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash);
|
||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
||||
if(result){
|
||||
assert(result->kind == TYPE_ARRAY);
|
||||
assert(result->arr.size == size);
|
||||
@@ -153,11 +153,11 @@ type_array(Ast_Resolved_Type *base, B32 size_present, S64 size){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
type_lambda(Ast *ast, Ast_Resolved_Type *ret, Array<Ast_Resolved_Type *> args){
|
||||
function Ast_Type *
|
||||
type_lambda(Ast *ast, Ast_Type *ret, Array<Ast_Type *> args){
|
||||
U64 hash = hash_ptr(ret);
|
||||
For(args) hash = hash_mix(hash, hash_ptr(it));
|
||||
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash);
|
||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
||||
|
||||
if(result){
|
||||
assert(result->kind == TYPE_LAMBDA);
|
||||
@@ -176,27 +176,27 @@ type_lambda(Ast *ast, Ast_Resolved_Type *ret, Array<Ast_Resolved_Type *> args){
|
||||
}
|
||||
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
type_enum(Ast_Decl *ast, Ast_Resolved_Type *type){
|
||||
function Ast_Type *
|
||||
type_enum(Ast_Decl *ast, Ast_Type *type){
|
||||
if(!type){
|
||||
type = type_s64;
|
||||
}
|
||||
|
||||
Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align);
|
||||
Ast_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align);
|
||||
result->base = type;
|
||||
result->ast = ast;
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Resolved_Type *
|
||||
function Ast_Type *
|
||||
type_incomplete(Ast *ast){
|
||||
Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
|
||||
Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0);
|
||||
result->ast = ast;
|
||||
return result;
|
||||
}
|
||||
|
||||
function void
|
||||
type_struct_complete(Ast_Resolved_Type *type, Ast_Decl *node){
|
||||
type_struct_complete(Ast_Type *type, Ast_Decl *node){
|
||||
assert(node->kind == AST_STRUCT);
|
||||
// @todo: compute size, alignement, offset !!!
|
||||
// @note: resolve all the struct members first
|
||||
@@ -212,7 +212,7 @@ type_struct_complete(Ast_Resolved_Type *type, Ast_Decl *node){
|
||||
}
|
||||
|
||||
function void
|
||||
type_complete(Ast_Resolved_Type *type){
|
||||
type_complete(Ast_Type *type){
|
||||
if(!type) {
|
||||
return;
|
||||
}
|
||||
|
||||
136
types.h
136
types.h
@@ -1,7 +1,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Resolved Types
|
||||
//-----------------------------------------------------------------------------
|
||||
enum Ast_Resolved_Type_Kind{
|
||||
enum Ast_Type_Kind{
|
||||
TYPE_NONE,
|
||||
TYPE_COMPLETING,
|
||||
TYPE_INCOMPLETE,
|
||||
@@ -49,7 +49,7 @@ enum Ast_Resolved_Type_Kind{
|
||||
#define CASE_UNTYPED case TYPE_UNTYPED_INT: case TYPE_UNTYPED_BOOL: case TYPE_UNTYPED_FLOAT: case TYPE_UNTYPED_STRING
|
||||
|
||||
const char *type_names[] = {
|
||||
"[Invalid Ast_Resolved_Type]",
|
||||
"[Invalid Ast_Type]",
|
||||
"[Completing]",
|
||||
"[Incomplete]",
|
||||
|
||||
@@ -81,24 +81,24 @@ const char *type_names[] = {
|
||||
};
|
||||
|
||||
struct Ast;
|
||||
struct Ast_Resolved_Type;
|
||||
struct Ast_Type;
|
||||
struct Ast_Resolved_Member{
|
||||
Ast_Resolved_Type *type;
|
||||
Ast_Type *type;
|
||||
Intern_String name;
|
||||
U64 offset;
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE_INFERRED (-1)
|
||||
struct Ast_Resolved_Type{
|
||||
Ast_Resolved_Type_Kind kind;
|
||||
struct Ast_Type{
|
||||
Ast_Type_Kind kind;
|
||||
SizeU size;
|
||||
SizeU align;
|
||||
|
||||
Ast *ast;
|
||||
union{
|
||||
Ast_Resolved_Type *base;
|
||||
Ast_Type *base;
|
||||
struct{
|
||||
Ast_Resolved_Type *base;
|
||||
Ast_Type *base;
|
||||
S64 size;
|
||||
// @note: if you have array with size "[32]"
|
||||
// you still want to pass that array into
|
||||
@@ -110,16 +110,16 @@ struct Ast_Resolved_Type{
|
||||
Array<Ast_Resolved_Member> members;
|
||||
}agg;
|
||||
struct{
|
||||
Ast_Resolved_Type *ret;
|
||||
Array<Ast_Resolved_Type *> args;
|
||||
Ast_Type *ret;
|
||||
Array<Ast_Type *> args;
|
||||
}func;
|
||||
};
|
||||
};
|
||||
|
||||
function const char *
|
||||
docname(Ast_Resolved_Type *type){
|
||||
docname(Ast_Type *type){
|
||||
switch(type->kind){
|
||||
case TYPE_NONE: return "[Invalid Ast_Resolved_Type]";
|
||||
case TYPE_NONE: return "[Invalid Ast_Type]";
|
||||
case TYPE_COMPLETING: return "[Completing]";
|
||||
case TYPE_INCOMPLETE: return "[Incomplete]";
|
||||
case TYPE_UNTYPED_BOOL: return "[Untyped_Bool]";
|
||||
@@ -152,7 +152,7 @@ docname(Ast_Resolved_Type *type){
|
||||
}
|
||||
|
||||
function const char *
|
||||
name(Ast_Resolved_Type *type){
|
||||
name(Ast_Type *type){
|
||||
switch(type->kind){
|
||||
case TYPE_VOID: return "void";
|
||||
case TYPE_BOOL: return "Bool";
|
||||
@@ -177,81 +177,81 @@ name(Ast_Resolved_Type *type){
|
||||
//-----------------------------------------------------------------------------
|
||||
const SizeU pointer_size = sizeof(SizeU);
|
||||
const SizeU pointer_align = __alignof(SizeU);
|
||||
global Ast_Resolved_Type type__void = {TYPE_VOID};
|
||||
global Ast_Resolved_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
|
||||
global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
|
||||
global Ast_Resolved_Type type__type = {TYPE_TYPE};
|
||||
global Ast_Type type__void = {TYPE_VOID};
|
||||
global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
|
||||
global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
|
||||
global Ast_Type type__type = {TYPE_TYPE};
|
||||
|
||||
global Ast_Resolved_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)};
|
||||
global Ast_Resolved_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)};
|
||||
global Ast_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)};
|
||||
global Ast_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)};
|
||||
|
||||
global Ast_Resolved_Type type__s8 = {TYPE_S8, sizeof(S8), __alignof(S8)};
|
||||
global Ast_Resolved_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)};
|
||||
global Ast_Resolved_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)};
|
||||
global Ast_Resolved_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)};
|
||||
global Ast_Type type__s8 = {TYPE_S8, sizeof(S8), __alignof(S8)};
|
||||
global Ast_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)};
|
||||
global Ast_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)};
|
||||
global Ast_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)};
|
||||
|
||||
global Ast_Resolved_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)};
|
||||
global Ast_Resolved_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)};
|
||||
global Ast_Resolved_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)};
|
||||
global Ast_Resolved_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)};
|
||||
global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)};
|
||||
global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)};
|
||||
global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)};
|
||||
global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)};
|
||||
|
||||
global Ast_Resolved_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)};
|
||||
global Ast_Resolved_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)};
|
||||
global Ast_Resolved_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)};
|
||||
global Ast_Resolved_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)};
|
||||
global Ast_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)};
|
||||
global Ast_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)};
|
||||
global Ast_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)};
|
||||
global Ast_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)};
|
||||
|
||||
global Ast_Resolved_Type *type_type = &type__type;
|
||||
global Ast_Resolved_Type *type_void = &type__void;
|
||||
global Ast_Resolved_Type *type_string = &type__string;
|
||||
global Ast_Resolved_Type *type_bool = &type__bool;
|
||||
global Ast_Type *type_type = &type__type;
|
||||
global Ast_Type *type_void = &type__void;
|
||||
global Ast_Type *type_string = &type__string;
|
||||
global Ast_Type *type_bool = &type__bool;
|
||||
|
||||
global Ast_Resolved_Type *type_f32 = &type__f32;
|
||||
global Ast_Resolved_Type *type_f64 = &type__f64;
|
||||
global Ast_Type *type_f32 = &type__f32;
|
||||
global Ast_Type *type_f64 = &type__f64;
|
||||
|
||||
global Ast_Resolved_Type *type_s8 = &type__s8 ;
|
||||
global Ast_Resolved_Type *type_s16 = &type__s16;
|
||||
global Ast_Resolved_Type *type_s32 = &type__s32;
|
||||
global Ast_Resolved_Type *type_s64 = &type__s64;
|
||||
global Ast_Type *type_s8 = &type__s8 ;
|
||||
global Ast_Type *type_s16 = &type__s16;
|
||||
global Ast_Type *type_s32 = &type__s32;
|
||||
global Ast_Type *type_s64 = &type__s64;
|
||||
|
||||
global Ast_Resolved_Type *type_u8 = &type__u8 ;
|
||||
global Ast_Resolved_Type *type_u16 = &type__u16;
|
||||
global Ast_Resolved_Type *type_u32 = &type__u32;
|
||||
global Ast_Resolved_Type *type_u64 = &type__u64;
|
||||
global Ast_Type *type_u8 = &type__u8 ;
|
||||
global Ast_Type *type_u16 = &type__u16;
|
||||
global Ast_Type *type_u32 = &type__u32;
|
||||
global Ast_Type *type_u64 = &type__u64;
|
||||
|
||||
global Ast_Resolved_Type *untyped_string = &type__untyped_string;
|
||||
global Ast_Resolved_Type *untyped_bool = &type__untyped_bool;
|
||||
global Ast_Resolved_Type *untyped_int = &type__untyped_int;
|
||||
global Ast_Resolved_Type *untyped_float = &type__untyped_float;
|
||||
global Ast_Type *untyped_string = &type__untyped_string;
|
||||
global Ast_Type *untyped_bool = &type__untyped_bool;
|
||||
global Ast_Type *untyped_int = &type__untyped_int;
|
||||
global Ast_Type *untyped_float = &type__untyped_float;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Type constructors and utillities
|
||||
//-----------------------------------------------------------------------------
|
||||
force_inline B32 is_struct(Ast_Resolved_Type *a){return a->kind == TYPE_STRUCT;}
|
||||
force_inline B32 is_lambda(Ast_Resolved_Type *a){return a->kind == TYPE_LAMBDA;}
|
||||
force_inline B32 is_array(Ast_Resolved_Type *a){return a->kind == TYPE_ARRAY;}
|
||||
force_inline B32 is_enum(Ast_Resolved_Type *a){return a->kind == TYPE_ENUM;}
|
||||
force_inline B32 is_pointer(Ast_Resolved_Type *a){return a->kind == TYPE_POINTER;}
|
||||
force_inline B32 is_string(Ast_Resolved_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING;}
|
||||
force_inline B32 is_untyped_int(Ast_Resolved_Type *a){return a->kind == TYPE_UNTYPED_INT;}
|
||||
force_inline B32 is_typed_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);}
|
||||
force_inline B32 is_int(Ast_Resolved_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;}
|
||||
force_inline B32 is_signed_int(Ast_Resolved_Type *a){return a->kind >= TYPE_S64 && a->kind <= TYPE_S8;}
|
||||
force_inline B32 is_unsigned_int(Ast_Resolved_Type *a){return a->kind >= TYPE_U64 && a->kind <= TYPE_U8;}
|
||||
force_inline B32 is_float(Ast_Resolved_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;}
|
||||
force_inline B32 is_f32(Ast_Resolved_Type *a){return a->kind == TYPE_F32;}
|
||||
force_inline B32 is_f64(Ast_Resolved_Type *a){return a->kind == TYPE_F64;}
|
||||
force_inline B32 is_bool(Ast_Resolved_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;}
|
||||
force_inline B32 is_untyped(Ast_Resolved_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;}
|
||||
force_inline B32 is_typed(Ast_Resolved_Type *a){return !is_untyped(a);}
|
||||
force_inline B32 is_struct(Ast_Type *a){return a->kind == TYPE_STRUCT;}
|
||||
force_inline B32 is_lambda(Ast_Type *a){return a->kind == TYPE_LAMBDA;}
|
||||
force_inline B32 is_array(Ast_Type *a){return a->kind == TYPE_ARRAY;}
|
||||
force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;}
|
||||
force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;}
|
||||
force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING;}
|
||||
force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;}
|
||||
force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);}
|
||||
force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;}
|
||||
force_inline B32 is_signed_int(Ast_Type *a){return a->kind >= TYPE_S64 && a->kind <= TYPE_S8;}
|
||||
force_inline B32 is_unsigned_int(Ast_Type *a){return a->kind >= TYPE_U64 && a->kind <= TYPE_U8;}
|
||||
force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;}
|
||||
force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;}
|
||||
force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;}
|
||||
force_inline B32 is_bool(Ast_Type *a){return a->kind == TYPE_BOOL || a->kind == TYPE_UNTYPED_BOOL;}
|
||||
force_inline B32 is_untyped(Ast_Type *a){return a->kind >= TYPE_UNTYPED_FIRST && a->kind <= TYPE_UNTYPED_LAST;}
|
||||
force_inline B32 is_typed(Ast_Type *a){return !is_untyped(a);}
|
||||
|
||||
force_inline B32
|
||||
is_numeric(Ast_Resolved_Type *type){
|
||||
is_numeric(Ast_Type *type){
|
||||
return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) ||
|
||||
(type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC);
|
||||
}
|
||||
|
||||
function U64
|
||||
int_type_max(Ast_Resolved_Type *type){
|
||||
int_type_max(Ast_Type *type){
|
||||
switch(type->kind){
|
||||
case TYPE_BOOL: return 1;
|
||||
case TYPE_UNTYPED_BOOL: return 1;
|
||||
|
||||
Reference in New Issue
Block a user