Add char * which is supposed to work like in C and int

This commit is contained in:
Krzosa Karol
2022-06-12 11:58:36 +02:00
parent 4d6a8efd06
commit cd3098da45
8 changed files with 43 additions and 76 deletions

View File

@@ -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
// 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

View File

@@ -90,11 +90,13 @@ gen_value(Value a){
const char *string = bigint_to_error_string(scratch, &a.big_int_val, 10);
gen("%s", string);
}break;
case TYPE_CHAR:
CASE_STRING:
if(is_pointer(a.type)){
assert(a.type == type_pointer_to_char);
gen("\"%s\"", a.intern_val.str);
break;
case TYPE_STRING: case TYPE_UNTYPED_STRING:
} else{
gen("LIT(\"%s\")", a.intern_val.str);
}
break;
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break;
CASE_FLOAT: gen("%f", a.f64_val); break;
@@ -380,6 +382,7 @@ gen_ast(Ast *ast){
gen_value(node->value);
}break;
CASE_STRING:{
assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1);
gen("// const String %s = ", node->name.str);
gen_value(node->value);
}break;

View File

@@ -185,7 +185,7 @@ struct Parse_Ctx:Lexer{
};
global B32 emit_line_directives;
function void init_type();
//-----------------------------------------------------------------------------
// Constructors
//-----------------------------------------------------------------------------
@@ -227,4 +227,6 @@ parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator)
lex_init(ctx->perm, ctx->heap, ctx);
pctx = ctx;
init_type();
}

View File

@@ -181,7 +181,7 @@ int main(int argument_count, char **arguments){
test_intern_table();
#if 1
#if 0
emit_line_directives = true;
if(argument_count > 1){
Scratch scratch;

View File

@@ -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, "String"_s, type_string);
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, "S16"_s, type_s16);
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))
type_complete(resolved.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;
}
@@ -804,7 +805,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
node->type = type_pointer(value.type_val);
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){
node->type = type_pointer(value.type);

View File

@@ -230,3 +230,7 @@ type_complete(Ast_Type *type){
pctx->ordered_decls.add((Ast_Decl *)type->ast);
}
function void
init_type(){
type_pointer_to_char = type_pointer(type_char);
}

81
types.h
View File

@@ -13,6 +13,8 @@ enum Ast_Type_Kind{
TYPE_S32,
TYPE_S16,
TYPE_S8 ,
TYPE_INT,
TYPE_CHAR,
TYPE_U64,
TYPE_U32,
TYPE_U16,
@@ -22,7 +24,6 @@ enum Ast_Type_Kind{
TYPE_POINTER,
TYPE_BOOL, // LAST_NUMERIC
TYPE_STRING,
TYPE_CHAR,
TYPE_VOID,
TYPE_ARRAY,
TYPE_LAMBDA,
@@ -41,47 +42,14 @@ enum Ast_Type_Kind{
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_INT case TYPE_UNTYPED_INT: CASE_SINT: CASE_UINT
#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_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
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_Type;
struct Ast_Resolved_Member{
@@ -96,6 +64,7 @@ struct Ast_Type{
Ast_Type_Kind kind;
SizeU size;
SizeU align;
S32 is_unsigned;
Ast *ast;
union{
@@ -142,6 +111,7 @@ docname(Ast_Type *type){
case TYPE_BOOL: return "[Bool]";
case TYPE_STRING: return "[String]";
case TYPE_CHAR: return "[char]";
case TYPE_INT: return "[int]";
case TYPE_VOID: return "[void]";
case TYPE_POINTER: return "[Pointer]";
case TYPE_ARRAY: return "[Array]";
@@ -184,7 +154,6 @@ const SizeU pointer_size = sizeof(SizeU);
const SizeU pointer_align = __alignof(SizeU);
global Ast_Type type__void = {TYPE_VOID};
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__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__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)};
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_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8), true};
global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16), true};
global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32), true};
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_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_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_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_void = &type__void;
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_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 || 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_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_signed_int(Ast_Type *a){return !a->is_unsigned;}
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_f32(Ast_Type *a){return a->kind == TYPE_F32;}
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) ||
(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;
}