diff --git a/cgenerate.cpp b/cgenerate.cpp index 1554f7f..ab9450b 100644 --- a/cgenerate.cpp +++ b/cgenerate.cpp @@ -277,8 +277,12 @@ gen_ast(Ast *ast){ else if(sym->type == type_string){ gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str); } + else if(sym->type == type_type){ + gen("typedef "); + gen_simple_decl(sym->type_val, node->name); + } else{ - parsing_error(node->pos, "Unhandled type of constant expression"); + parsing_error(node->pos, "C_Codegen: Unhandled type of constant expression"); } Ast_End(); diff --git a/globals.kl b/globals.kl index fe99d91..fb3406a 100644 --- a/globals.kl +++ b/globals.kl @@ -1,10 +1,10 @@ //----------------------------------------------------------------------------- // Function types //----------------------------------------------------------------------------- -test_function :: (thing: int): ^int -function_type: (thing: int): ^int = test_function +test_function :: (thing: int): *int +function_type: test_function const_function_alias :: test_function -null_function: (t: int): ^int = null +null_function: (t: int): *int = null //----------------------------------------------------------------------------- // Booleans @@ -35,10 +35,10 @@ array_item_imp: int = array2[2] //----------------------------------------------------------------------------- // Pointers //----------------------------------------------------------------------------- -pointer_decl : ^int -variable_from_deref: int = pointer_decl^ -pointer_from_var : ^int = ^variable_from_deref -boolean_pointer := ^boolean +pointer_decl : *int +variable_from_deref: int = *pointer_decl +pointer_from_var : *int = &variable_from_deref +boolean_pointer := &boolean //----------------------------------------------------------------------------- // Implicit type @@ -49,9 +49,9 @@ implicit_str :: "Hello world" //----------------------------------------------------------------------------- // Pointers //----------------------------------------------------------------------------- -pointer1: ^int = null -pointer2: ^int = pointer1 -pointer3: ^^int = null +pointer1: *int = null +pointer2: *int = pointer1 +pointer3: **int = null //----------------------------------------------------------------------------- // String types diff --git a/main.cpp b/main.cpp index 6f851cb..6dec1b5 100644 --- a/main.cpp +++ b/main.cpp @@ -23,7 +23,8 @@ int main(){ test_intern_table(); lex_test(); - String result = compile_file("lambdas.kl"_s); + String result = compile_file("globals.kl"_s); + // String result = compile_file("lambdas.kl"_s); // String result = compile_file("order_independent_globals.kl"_s); printf("%s", result.str); diff --git a/new_ast.cpp b/new_ast.cpp index e92cc94..9ff0c13 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -363,9 +363,9 @@ ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ } function Ast_Array * -ast_array(Token *pos, Ast_Expr *base){ +ast_array(Token *pos, Ast_Expr *expr){ AST_NEW(Array, ARRAY, pos); - result->base = base; + result->expr = expr; return result; } diff --git a/new_parse.cpp b/new_parse.cpp index f5db362..a6a380a 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -288,6 +288,7 @@ null_denotation(Token *token){ case TK_OpenBracket: { Ast_Array *result = ast_array(token, parse_expr()); token_expect(TK_CloseBracket); + result->base = parse_expr(); return result; }break; case TK_Keyword: { diff --git a/new_resolve.cpp b/new_resolve.cpp index 1c502d4..bff754b 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -14,6 +14,14 @@ enum Sym_State{ SYM_RESOLVED, }; +#define VALUE_FIELDS \ + S64 int_val; \ + Intern_String intern_val; \ + Ast_Resolved_Type *type_val; +#define INLINE_VALUE_FIELDS union{Value value; union{VALUE_FIELDS};} + +union Value{VALUE_FIELDS}; + struct Sym{ Intern_String name; Sym_Kind kind; @@ -21,24 +29,19 @@ struct Sym{ Ast *ast; Ast_Resolved_Type *type; - union{ - S64 int_val; - Intern_String intern_val; - }; + INLINE_VALUE_FIELDS; }; struct Operand{ Ast_Resolved_Type *type; bool is_const; - union { - S64 int_val; - Intern_String intern_val; - Ast_Resolved_Type *type_type; - }; + INLINE_VALUE_FIELDS; }; global Ast_Named empty_decl = {}; +// @todo: currently inserting into sym table type of [Type] instead of what type represents + function void sym_insert(Sym *sym){ U64 hash = hash_string(sym->name.s); @@ -148,62 +151,6 @@ sym_insert_builtins(){ function Sym *resolve_name(Token *pos, Intern_String name); function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *lambda_to_complete = 0); -// function Ast_Resolved_Type * -// eval_typespec(Ast_Expr *ast){ -// if(!ast) return 0; - -// switch(ast->kind){ -// Ast_Begin(AST_IDENT, Ast_Atom){ -// Sym *type_sym = sym_get(node->intern_val); -// if(!type_sym){ -// parsing_error(node->pos, "This type is not defined"); -// } -// if(type_sym->kind != SYM_TYPE){ -// parsing_error(node->pos, "This identifier is not a type"); -// } - -// sym_new_resolved(SYM_TYPESPEC, {}, type_sym->type, node); -// return type_sym->type; -// Ast_End(); -// } - -// Ast_Begin(AST_TYPESPEC_LAMBDA, Ast_Lambda){ -// Scratch scratch; -// Ast_Resolved_Type *ret = eval_typespec(node->lambda->ret); -// Array args = {scratch}; -// For(node->lambda->args) args.add(eval_typespec(it[0]->typespec)); - -// Ast_Resolved_Type *resolved_type = type_lambda(ret, args); -// sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); -// return resolved_type; -// Ast_End(); -// } - -// Ast_Begin(AST_TYPESPEC_POINTER, Ast_Typespec){ -// Ast_Resolved_Type *type = eval_typespec(node->base); -// Ast_Resolved_Type *resolved_type = type_pointer(type); - -// sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); -// return resolved_type; -// Ast_End(); -// } - -// Ast_Begin(AST_TYPESPEC_ARRAY, Ast_Typespec){ -// Ast_Resolved_Type *type = eval_typespec(node->arr.base); -// Operand expr = eval_expr(node->arr.expr); -// if(!expr.is_const) parsing_error(node->pos, "Array size is not a constant"); -// if(expr.type != type_int) parsing_error(node->pos, "Array size is expected to be of type [Int] is instead of type %s", type_names[expr.type->kind]); - -// Ast_Resolved_Type *resolved_type = type_array(type, expr.int_val); -// sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); -// return resolved_type; -// Ast_End(); -// } -// invalid_default_case; -// } -// return 0; -// } - function Ast_Resolved_Type * resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ Ast_Resolved_Type *result = 0; @@ -278,6 +225,15 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } +enum{AST_CAN_BE_NULL = 1}; +function Ast_Resolved_Type * +eval_typespec(Ast_Expr *ast, B32 ast_can_be_null){ + if(ast_can_be_null && ast == 0) return 0; + Operand resolved = eval_expr(ast); + if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind); + return resolved.type_val; +} + function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){ switch(ast->kind){ @@ -333,7 +289,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple else if(sym->kind == SYM_TYPE){ result.type = type_type; - result.type_type = sym->type; + result.type_val = sym->type; sym_new_resolved(SYM_TYPE, sym->name, sym->type, node); } @@ -354,7 +310,8 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple if(!expr.is_const) parsing_error(node->pos, "Array operator requires a constant value"); if(expr.type != type_int) parsing_error(node->pos, "Array index requires type [Int]"); - type.type_type = type_array(type.type_type, expr.int_val); + type.type_val = type_array(type.type_val, expr.int_val); + sym_new_resolved(SYM_TYPE, {}, type.type_val, node); return type; Ast_End(); } @@ -369,11 +326,14 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple For(node->args){ Operand type = eval_expr(it[0]->typespec); if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]"); - args.add(type.type_type); + args.add(type.type_val); } - lambda_type = type_lambda(ret_op.type_type, args); + lambda_type = type_lambda(ret_op.type_val, args); + sym_new_resolved(SYM_TYPE, {}, lambda_type, node); assert(lambda_type); + Operand result = {type_type, true}; + result.type_val = lambda_type; // @todo: We also need to make sure there is a return value when ret type is not void // @note: then try resolving the block of lambda if(node->block){ @@ -386,12 +346,13 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple sym_insert(arg_sym); } For(node->block->stmts){ - eval_stmt(it[0], ret_op.type_type); + eval_stmt(it[0], ret_op.type_val); } scope_close(scope_index); + result.type = lambda_type; } - return {lambda_type, true}; + return result; Ast_End(); } @@ -406,38 +367,35 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple } Ast_Begin(AST_COMPOUND, Ast_Compound){ - unused(node); - // Ast_Resolved_Type *type = eval_typespec(node->typespec); - // Ast_Resolved_Type *variable_type = expected_type; - // if(!type && variable_type) type = variable_type; - // else if(!variable_type && type); - // else if(variable_type != type) parsing_error(node->pos, "Variable type different from explicit compound type"); - // node->type = type; + Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL); + if(!type && expected_type) type = expected_type; + else if(!expected_type && type); + else if(expected_type != type) parsing_error(node->pos, "Variable type different from explicit compound type"); + node->type = type; - // if(type->kind == TYPE_Array){ - // if(node->exprs.len > type->arr.size) parsing_error(node->pos, "compound statement has too many items for this type"); - // Ast_Resolved_Type *item_type = type->arr.base; + if(type->kind == TYPE_Array){ + if(node->exprs.len > type->arr.size) parsing_error(node->pos, "compound statement has too many items for this type"); + Ast_Resolved_Type *item_type = type->arr.base; - // For(node->exprs){ - // assert(it[0]->kind == AST_COMPOUND_ITEM); - // Ast_Compound_Item *i = (Ast_Compound_Item *)it[0]; - // assert(i->kind == AST_COMPOUND_ITEM); - // if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); - // if(i->index){ - // Operand index_op = eval_expr(i->index); - // if(!index_op.is_const) parsing_error(i->pos, "Index in a compound expression is not a constant"); - // if(index_op.type != type_int) parsing_error(i->pos, "Index should be of type int"); - // if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store"); - // } - // Operand expr = eval_expr(i->item, item_type); - // resolve_type_pair(i->pos, expr.type, item_type); - // } - // } - // else parsing_error(node->pos, "Invalid compound expression type"); + For(node->exprs){ + assert(it[0]->kind == AST_COMPOUND_ITEM); + Ast_Compound_Item *i = (Ast_Compound_Item *)it[0]; + assert(i->kind == AST_COMPOUND_ITEM); + if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); + if(i->index){ + Operand index_op = eval_expr(i->index); + if(!index_op.is_const) parsing_error(i->pos, "Index in a compound expression is not a constant"); + if(index_op.type != type_int) parsing_error(i->pos, "Index should be of type int"); + if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store"); + } + Operand expr = eval_expr(i->item, item_type); + resolve_type_pair(i->pos, expr.type, item_type); + } + } + else parsing_error(node->pos, "Invalid compound expression type"); - // Operand result = {type, false}; - // return result; - not_implemented; + Operand result = {type, false}; + return result; Ast_End(); } @@ -445,7 +403,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Operand expr = eval_expr(node->expr); Operand typespec = eval_expr(node->typespec); if(typespec.type != type_type) parsing_error(node->pos, "Expected type in left of cast got instead %s", type_names[typespec.type->kind]); - Ast_Resolved_Type *type = typespec.type; + Ast_Resolved_Type *type = typespec.type_val; if(type == expr.type) return expr; @@ -473,9 +431,16 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Operand value = eval_expr(node->expr); switch(node->op){ case TK_Pointer:{ - if(value.type->kind != TYPE_Pointer) parsing_error(node->pos, "Dereferencing a value that is not a pointer"); - Operand result = {value.type->base}; - return result; + if(value.type->kind == TYPE_Pointer){ + Operand result = {value.type->base}; + return result; + } + else if(value.type->kind == TYPE_Type){ + Operand result = {type_type, true}; + result.type_val = type_pointer(value.type_val); + return result; + } + else{ parsing_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; } }break; case TK_Dereference:{ Operand result = {type_pointer(value.type)}; @@ -523,8 +488,8 @@ eval_decl(Ast *ast, Sym *sym){ Ast_Begin(AST_VAR, Ast_Var){ Operand type = node->typespec ? eval_expr(node->typespec) : Operand{}; if(type.type && (type.type != type_type)) parsing_error(node->typespec->pos, "Expected [Type] got instead %s", type_names[type.type->kind]); - Operand expr = node->expr ? eval_expr(node->expr, type.type_type) : Operand{}; - expr.type = resolve_type_pair(node->pos, type.type_type, expr.type); + Operand expr = node->expr ? eval_expr(node->expr, type.type_val) : Operand{}; + expr.type = resolve_type_pair(node->pos, type.type_val, expr.type); return expr; Ast_End(); } @@ -576,8 +541,7 @@ resolve_sym(Sym *sym){ sym->type = op.type; if(sym->kind == SYM_CONST){ assert(op.is_const); - if(op.type == type_int) sym->int_val = op.int_val; - else if(op.type == type_string) sym->intern_val = op.intern_val; + sym->value = op.value; } sym->state = SYM_RESOLVED;