Add char * which is supposed to work like in C and int
This commit is contained in:
@@ -28,7 +28,9 @@ imp_array := [5]S64{1,2}
|
|||||||
imp_array_c: [5]S64 = {[0] = 1, [2] = 2, [1] = 0} // @todo this should be illegal
|
imp_array_c: [5]S64 = {[0] = 1, [2] = 2, [1] = 0} // @todo this should be illegal
|
||||||
// without_size: []S64 = {} // @todo: this should be slice, converting from array should be implicit
|
// without_size: []S64 = {} // @todo: this should be slice, converting from array should be implicit
|
||||||
|
|
||||||
string: char = "string"
|
string: *char = "string"
|
||||||
|
first_letter := string[0]
|
||||||
|
decl_char: char = 55
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Pointers
|
// Pointers
|
||||||
|
|||||||
4
ast.cpp
4
ast.cpp
@@ -64,13 +64,13 @@ struct Ast_Type;
|
|||||||
struct Ast_Expr:Ast{ };
|
struct Ast_Expr:Ast{ };
|
||||||
|
|
||||||
#define VALUE_FIELDS \
|
#define VALUE_FIELDS \
|
||||||
Ast_Type *type; \
|
Ast_Type *type; \
|
||||||
union{ \
|
union{ \
|
||||||
bool bool_val; \
|
bool bool_val; \
|
||||||
F64 f64_val; \
|
F64 f64_val; \
|
||||||
Intern_String intern_val; \
|
Intern_String intern_val; \
|
||||||
BigInt big_int_val;\
|
BigInt big_int_val;\
|
||||||
Ast_Type *type_val; \
|
Ast_Type *type_val; \
|
||||||
};
|
};
|
||||||
#define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};}
|
#define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};}
|
||||||
struct Value{VALUE_FIELDS};
|
struct Value{VALUE_FIELDS};
|
||||||
|
|||||||
13
ccodegen.cpp
13
ccodegen.cpp
@@ -90,11 +90,13 @@ gen_value(Value a){
|
|||||||
const char *string = bigint_to_error_string(scratch, &a.big_int_val, 10);
|
const char *string = bigint_to_error_string(scratch, &a.big_int_val, 10);
|
||||||
gen("%s", string);
|
gen("%s", string);
|
||||||
}break;
|
}break;
|
||||||
case TYPE_CHAR:
|
CASE_STRING:
|
||||||
gen("\"%s\"", a.intern_val.str);
|
if(is_pointer(a.type)){
|
||||||
break;
|
assert(a.type == type_pointer_to_char);
|
||||||
case TYPE_STRING: case TYPE_UNTYPED_STRING:
|
gen("\"%s\"", a.intern_val.str);
|
||||||
gen("LIT(\"%s\")", a.intern_val.str);
|
} else{
|
||||||
|
gen("LIT(\"%s\")", a.intern_val.str);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break;
|
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break;
|
||||||
CASE_FLOAT: gen("%f", a.f64_val); break;
|
CASE_FLOAT: gen("%f", a.f64_val); break;
|
||||||
@@ -380,6 +382,7 @@ gen_ast(Ast *ast){
|
|||||||
gen_value(node->value);
|
gen_value(node->value);
|
||||||
}break;
|
}break;
|
||||||
CASE_STRING:{
|
CASE_STRING:{
|
||||||
|
assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1);
|
||||||
gen("// const String %s = ", node->name.str);
|
gen("// const String %s = ", node->name.str);
|
||||||
gen_value(node->value);
|
gen_value(node->value);
|
||||||
}break;
|
}break;
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ struct Parse_Ctx:Lexer{
|
|||||||
};
|
};
|
||||||
|
|
||||||
global B32 emit_line_directives;
|
global B32 emit_line_directives;
|
||||||
|
function void init_type();
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Constructors
|
// Constructors
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -227,4 +227,6 @@ parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator)
|
|||||||
|
|
||||||
lex_init(ctx->perm, ctx->heap, ctx);
|
lex_init(ctx->perm, ctx->heap, ctx);
|
||||||
pctx = ctx;
|
pctx = ctx;
|
||||||
|
|
||||||
|
init_type();
|
||||||
}
|
}
|
||||||
4
main.cpp
4
main.cpp
@@ -181,7 +181,7 @@ int main(int argument_count, char **arguments){
|
|||||||
test_intern_table();
|
test_intern_table();
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
emit_line_directives = true;
|
emit_line_directives = true;
|
||||||
if(argument_count > 1){
|
if(argument_count > 1){
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
@@ -203,7 +203,7 @@ int main(int argument_count, char **arguments){
|
|||||||
|
|
||||||
system((const char *)run_program.str);
|
system((const char *)run_program.str);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<String> files = {scratch};
|
Array<String> files = {scratch};
|
||||||
// files.add("lambdas.kl"_s);
|
// files.add("lambdas.kl"_s);
|
||||||
|
|||||||
@@ -373,6 +373,7 @@ insert_builtin_types_into_package(Ast_Package *p){
|
|||||||
insert_type_into_package(p, "Bool"_s , type_bool);
|
insert_type_into_package(p, "Bool"_s , type_bool);
|
||||||
insert_type_into_package(p, "String"_s, type_string);
|
insert_type_into_package(p, "String"_s, type_string);
|
||||||
insert_type_into_package(p, "char"_s, type_char);
|
insert_type_into_package(p, "char"_s, type_char);
|
||||||
|
insert_type_into_package(p, "int"_s, type_int);
|
||||||
insert_type_into_package(p, "S8"_s, type_s8);
|
insert_type_into_package(p, "S8"_s, type_s8);
|
||||||
insert_type_into_package(p, "S16"_s, type_s16);
|
insert_type_into_package(p, "S16"_s, type_s16);
|
||||||
insert_type_into_package(p, "S32"_s, type_s32);
|
insert_type_into_package(p, "S32"_s, type_s32);
|
||||||
@@ -394,7 +395,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context =
|
|||||||
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
|
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
|
||||||
type_complete(resolved.type);
|
type_complete(resolved.type);
|
||||||
if(resolved.type != type_type)
|
if(resolved.type != type_type)
|
||||||
compiler_error(ast->pos, "Expected [Type] got instead %s", type_names[resolved.type->kind]);
|
compiler_error(ast->pos, "Expected [Type] got instead %s", docname(resolved.type));
|
||||||
return resolved.type_val;
|
return resolved.type_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,7 +805,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
node->type = type_pointer(value.type_val);
|
node->type = type_pointer(value.type_val);
|
||||||
return operand_type(node->type);
|
return operand_type(node->type);
|
||||||
}
|
}
|
||||||
else{ compiler_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; }
|
else{ compiler_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", docname(value.type)); return {}; }
|
||||||
}
|
}
|
||||||
else if(node->op == TK_Dereference){
|
else if(node->op == TK_Dereference){
|
||||||
node->type = type_pointer(value.type);
|
node->type = type_pointer(value.type);
|
||||||
|
|||||||
@@ -230,3 +230,7 @@ type_complete(Ast_Type *type){
|
|||||||
pctx->ordered_decls.add((Ast_Decl *)type->ast);
|
pctx->ordered_decls.add((Ast_Decl *)type->ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
init_type(){
|
||||||
|
type_pointer_to_char = type_pointer(type_char);
|
||||||
|
}
|
||||||
81
types.h
81
types.h
@@ -13,6 +13,8 @@ enum Ast_Type_Kind{
|
|||||||
TYPE_S32,
|
TYPE_S32,
|
||||||
TYPE_S16,
|
TYPE_S16,
|
||||||
TYPE_S8 ,
|
TYPE_S8 ,
|
||||||
|
TYPE_INT,
|
||||||
|
TYPE_CHAR,
|
||||||
TYPE_U64,
|
TYPE_U64,
|
||||||
TYPE_U32,
|
TYPE_U32,
|
||||||
TYPE_U16,
|
TYPE_U16,
|
||||||
@@ -22,7 +24,6 @@ enum Ast_Type_Kind{
|
|||||||
TYPE_POINTER,
|
TYPE_POINTER,
|
||||||
TYPE_BOOL, // LAST_NUMERIC
|
TYPE_BOOL, // LAST_NUMERIC
|
||||||
TYPE_STRING,
|
TYPE_STRING,
|
||||||
TYPE_CHAR,
|
|
||||||
TYPE_VOID,
|
TYPE_VOID,
|
||||||
TYPE_ARRAY,
|
TYPE_ARRAY,
|
||||||
TYPE_LAMBDA,
|
TYPE_LAMBDA,
|
||||||
@@ -41,47 +42,14 @@ enum Ast_Type_Kind{
|
|||||||
TYPE_LAST_NUMERIC = TYPE_BOOL,
|
TYPE_LAST_NUMERIC = TYPE_BOOL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64
|
#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64: case TYPE_CHAR: case TYPE_INT
|
||||||
#define CASE_UINT case TYPE_U8:case TYPE_U16:case TYPE_U32:case TYPE_U64
|
#define CASE_UINT case TYPE_U8:case TYPE_U16:case TYPE_U32:case TYPE_U64
|
||||||
#define CASE_INT case TYPE_UNTYPED_INT: CASE_SINT: CASE_UINT
|
#define CASE_INT case TYPE_UNTYPED_INT: CASE_SINT: CASE_UINT
|
||||||
#define CASE_BOOL case TYPE_UNTYPED_BOOL: case TYPE_BOOL
|
#define CASE_BOOL case TYPE_UNTYPED_BOOL: case TYPE_BOOL
|
||||||
#define CASE_FLOAT case TYPE_UNTYPED_FLOAT: case TYPE_F32: case TYPE_F64
|
#define CASE_FLOAT case TYPE_UNTYPED_FLOAT: case TYPE_F32: case TYPE_F64
|
||||||
#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_CHAR
|
#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_POINTER
|
||||||
#define CASE_UNTYPED case TYPE_UNTYPED_INT: case TYPE_UNTYPED_BOOL: case TYPE_UNTYPED_FLOAT: case TYPE_UNTYPED_STRING
|
#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_Type]",
|
|
||||||
"[Completing]",
|
|
||||||
"[Incomplete]",
|
|
||||||
|
|
||||||
"[Untyped_Bool]",
|
|
||||||
"[Untyped_Int]",
|
|
||||||
"[Untyped_Float]",
|
|
||||||
"[Untyped_String]",
|
|
||||||
|
|
||||||
"[S64]",
|
|
||||||
"[S32]",
|
|
||||||
"[S16]",
|
|
||||||
"[S8]",
|
|
||||||
"[U64]",
|
|
||||||
"[U32]",
|
|
||||||
"[U16]",
|
|
||||||
"[U8]",
|
|
||||||
"[Float32]",
|
|
||||||
"[Float64]",
|
|
||||||
"[Bool]",
|
|
||||||
"[String]",
|
|
||||||
"[char]",
|
|
||||||
"[void]",
|
|
||||||
"[Pointer]",
|
|
||||||
"[Array]",
|
|
||||||
"[Lambda]",
|
|
||||||
"[Struct]",
|
|
||||||
"[Union]",
|
|
||||||
"[Enum]",
|
|
||||||
"[Type]",
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ast;
|
struct Ast;
|
||||||
struct Ast_Type;
|
struct Ast_Type;
|
||||||
struct Ast_Resolved_Member{
|
struct Ast_Resolved_Member{
|
||||||
@@ -96,6 +64,7 @@ struct Ast_Type{
|
|||||||
Ast_Type_Kind kind;
|
Ast_Type_Kind kind;
|
||||||
SizeU size;
|
SizeU size;
|
||||||
SizeU align;
|
SizeU align;
|
||||||
|
S32 is_unsigned;
|
||||||
|
|
||||||
Ast *ast;
|
Ast *ast;
|
||||||
union{
|
union{
|
||||||
@@ -142,6 +111,7 @@ docname(Ast_Type *type){
|
|||||||
case TYPE_BOOL: return "[Bool]";
|
case TYPE_BOOL: return "[Bool]";
|
||||||
case TYPE_STRING: return "[String]";
|
case TYPE_STRING: return "[String]";
|
||||||
case TYPE_CHAR: return "[char]";
|
case TYPE_CHAR: return "[char]";
|
||||||
|
case TYPE_INT: return "[int]";
|
||||||
case TYPE_VOID: return "[void]";
|
case TYPE_VOID: return "[void]";
|
||||||
case TYPE_POINTER: return "[Pointer]";
|
case TYPE_POINTER: return "[Pointer]";
|
||||||
case TYPE_ARRAY: return "[Array]";
|
case TYPE_ARRAY: return "[Array]";
|
||||||
@@ -184,7 +154,6 @@ const SizeU pointer_size = sizeof(SizeU);
|
|||||||
const SizeU pointer_align = __alignof(SizeU);
|
const SizeU pointer_align = __alignof(SizeU);
|
||||||
global Ast_Type type__void = {TYPE_VOID};
|
global Ast_Type type__void = {TYPE_VOID};
|
||||||
global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
|
global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)};
|
||||||
global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)};
|
|
||||||
global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
|
global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)};
|
||||||
global Ast_Type type__type = {TYPE_TYPE};
|
global Ast_Type type__type = {TYPE_TYPE};
|
||||||
|
|
||||||
@@ -196,17 +165,22 @@ 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__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)};
|
||||||
global Ast_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)};
|
global Ast_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)};
|
||||||
|
|
||||||
global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)};
|
global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8), true};
|
||||||
global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)};
|
global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16), true};
|
||||||
global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)};
|
global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32), true};
|
||||||
global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)};
|
global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64), true};
|
||||||
|
|
||||||
global Ast_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)};
|
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_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_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)};
|
||||||
global Ast_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)};
|
global Ast_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)};
|
||||||
|
|
||||||
|
global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)};
|
||||||
|
global Ast_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)};
|
||||||
global Ast_Type *type_char = &type__char;
|
global Ast_Type *type_char = &type__char;
|
||||||
|
global Ast_Type *type_int = &type__int;
|
||||||
|
global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime
|
||||||
|
|
||||||
global Ast_Type *type_type = &type__type;
|
global Ast_Type *type_type = &type__type;
|
||||||
global Ast_Type *type_void = &type__void;
|
global Ast_Type *type_void = &type__void;
|
||||||
global Ast_Type *type_string = &type__string;
|
global Ast_Type *type_string = &type__string;
|
||||||
@@ -238,12 +212,12 @@ 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_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_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_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 || a->kind == TYPE_CHAR;}
|
force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;}
|
||||||
force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;}
|
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_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_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_signed_int(Ast_Type *a){return !a->is_unsigned;}
|
||||||
force_inline B32 is_unsigned_int(Ast_Type *a){return a->kind >= TYPE_U64 && a->kind <= TYPE_U8;}
|
force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;}
|
||||||
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_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_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_f64(Ast_Type *a){return a->kind == TYPE_F64;}
|
||||||
@@ -256,22 +230,3 @@ is_numeric(Ast_Type *type){
|
|||||||
return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) ||
|
return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) ||
|
||||||
(type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC);
|
(type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
function U64
|
|
||||||
int_type_max(Ast_Type *type){
|
|
||||||
switch(type->kind){
|
|
||||||
case TYPE_BOOL: return 1;
|
|
||||||
case TYPE_UNTYPED_BOOL: return 1;
|
|
||||||
case TYPE_UNTYPED_INT: return S64MAX;
|
|
||||||
case TYPE_S64: return S64MAX;
|
|
||||||
case TYPE_S32: return S32MAX;
|
|
||||||
case TYPE_S16: return S16MAX;
|
|
||||||
case TYPE_S8: return S8MAX;
|
|
||||||
case TYPE_U64: return U64MAX;
|
|
||||||
case TYPE_U32: return U32MAX;
|
|
||||||
case TYPE_U16: return U16MAX;
|
|
||||||
case TYPE_U8: return U8MAX;
|
|
||||||
invalid_default_case;
|
|
||||||
}
|
|
||||||
invalid_return;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user