diff --git a/cgenerate.cpp b/cgenerate.cpp index acf0449..1554f7f 100644 --- a/cgenerate.cpp +++ b/cgenerate.cpp @@ -122,7 +122,7 @@ gen_expr(Ast_Expr *ast){ Ast_Begin(AST_CAST, Ast_Cast){ gen("("); gen("("); - gen_simple_decl(resolved_typespec_get(node->typespec), {}); + gen_simple_decl(resolved_type_get(node->typespec), {}); gen(")"); gen_expr(node->expr); gen(")"); @@ -248,12 +248,12 @@ gen_ast(Ast *ast){ if(node->expr->kind == AST_LAMBDA){ Ast_Lambda *lambda = (Ast_Lambda *)node->expr; gen("static "); - Ast_Resolved_Type *ret = resolved_typespec_get(lambda->ret); + Ast_Resolved_Type *ret = resolved_type_get(lambda->ret); gen_simple_decl(ret, node->name); gen("("); For(lambda->args){ assert(it[0]->kind == AST_LAMBDA_ARG); - Ast_Resolved_Type *type = resolved_typespec_get(it[0]->typespec); + Ast_Resolved_Type *type = resolved_type_get(it[0]->typespec); gen_simple_decl(type, it[0]->name); if(it != (lambda->args.end() - 1)) gen(", "); } diff --git a/main.cpp b/main.cpp index d3efa15..6f851cb 100644 --- a/main.cpp +++ b/main.cpp @@ -9,11 +9,6 @@ /// @todo /// [ ] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int -/* -thing1 :: *int // type -thing2 :: *get_value // value from pointer - -*/ int main(){ @@ -28,8 +23,8 @@ int main(){ test_intern_table(); lex_test(); - // String result = compile_file("lambdas.kl"_s); - String result = compile_file("order_independent_globals.kl"_s); + String result = compile_file("lambdas.kl"_s); + // String result = compile_file("order_independent_globals.kl"_s); printf("%s", result.str); // compile_file("lambdas.kl"_s); diff --git a/new_ast.cpp b/new_ast.cpp index 0247fa1..e92cc94 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -123,7 +123,6 @@ struct Ast{ }; struct Ast_Resolved_Type; -struct Ast_Typespec; struct Ast_Expr:Ast{}; struct Ast_Atom: Ast_Expr{ @@ -141,7 +140,7 @@ struct Ast_Compound_Item: Ast_Expr{ struct Ast_Compound: Ast_Expr{ Ast_Resolved_Type *type; - Ast_Typespec *typespec; + Ast_Expr *typespec; Array exprs; }; @@ -152,7 +151,7 @@ struct Ast_Unary: Ast_Expr{ struct Ast_Cast: Ast_Expr{ Ast_Expr *expr; - Ast_Typespec *typespec; + Ast_Expr *typespec; }; struct Ast_Index: Ast_Expr{ @@ -206,24 +205,12 @@ struct Ast_Array: Ast_Expr{ Ast_Expr *expr; }; -struct Ast_Typespec:Ast{ - union{ - Ast_Typespec *base; - Intern_String name; - struct{ - Ast_Typespec *base; - Ast_Expr *expr; - }arr; - Ast_Lambda *lambda; - }; -}; - struct Ast_Named:Ast{ Intern_String name; }; struct Ast_Var: Ast_Named{ - Ast_Typespec *typespec; + Ast_Expr *typespec; Ast_Expr *expr; }; @@ -237,7 +224,6 @@ struct Ast_Package:Ast{ Array ordered; }; -function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name); //----------------------------------------------------------------------------- // AST Constructors beginning with expressions //----------------------------------------------------------------------------- @@ -248,21 +234,21 @@ function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name); result->id = ++pctx->unique_ids function Ast_Atom * -ast_expr_string(Token *pos, Intern_String string){ +ast_str(Token *pos, Intern_String string){ AST_NEW(Atom, STR, pos); result->intern_val = string; return result; } function Ast_Atom * -ast_expr_identifier(Token *pos, Intern_String string){ +ast_ident(Token *pos, Intern_String string){ AST_NEW(Atom, IDENT, pos); result->intern_val = string; return result; } function Ast_Atom * -ast_expr_integer(Token *pos, S64 integer){ +ast_int(Token *pos, S64 integer){ AST_NEW(Atom, INT, pos); result->int_val = integer; return result; @@ -278,7 +264,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ } function Ast_Compound * -ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array exprs){ +ast_expr_compound(Token *pos, Ast_Expr *typespec, Array exprs){ AST_NEW(Compound, COMPOUND, pos); result->typespec = typespec; result->exprs = exprs.tight_copy(pctx->perm); @@ -295,7 +281,7 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *it } function Ast_Expr * -ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){ +ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){ AST_NEW(Cast, CAST, pos); result->expr = expr; result->typespec = typespec; @@ -319,13 +305,13 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ } function Ast_Lambda * -ast_lambda(Token *pos, Array params, Ast_Typespec *ret, Ast_Block *block){ +ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Block *block){ AST_NEW(Lambda, LAMBDA, pos); result->args = params.tight_copy(pctx->perm); result->ret = ret; result->block = block; if(!ret){ - result->ret = ast_typespec_name(0, intern_void); + result->ret = ast_ident(0, intern_void); } return result; } @@ -383,44 +369,11 @@ ast_array(Token *pos, Ast_Expr *base){ return result; } -//----------------------------------------------------------------------------- -// Typespecs -//----------------------------------------------------------------------------- -function Ast_Typespec * -ast_typespec_name(Token *pos, Intern_String name){ - AST_NEW(Typespec, TYPESPEC_IDENT, pos); - result->name = name; - return result; -} - -function Ast_Typespec * -ast_typespec_pointer(Token *pos, Ast_Typespec *base){ - AST_NEW(Typespec, TYPESPEC_POINTER, pos); - result->base = base; - return result; -} - -function Ast_Typespec * -ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){ - AST_NEW(Typespec, TYPESPEC_ARRAY, pos); - result->arr.base = base; - result->arr.expr = expr; - return result; -} - -function Ast_Typespec * -ast_typespec_lambda(Token *pos, Ast_Lambda *lambda){ - AST_NEW(Typespec, TYPESPEC_LAMBDA, pos); - result->lambda = lambda; - return result; -} - //----------------------------------------------------------------------------- // Declarations //----------------------------------------------------------------------------- - function Ast_Var * -ast_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){ +ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){ AST_NEW(Var, VAR, pos); result->expr = expr; result->typespec = typespec; diff --git a/new_parse.cpp b/new_parse.cpp index c140db6..f5db362 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -151,7 +151,7 @@ parse_expr_compound(){ } else if(token_is(TK_Identifier)){ token = token_next(); - name = ast_expr_identifier(token, token->intern_val); + name = ast_ident(token, token->intern_val); token_expect(TK_Assign); } @@ -271,7 +271,7 @@ parse_lambda(Token *token, B32 is_typespec = false){ } token_expect(TK_CloseParen); - Ast_Typespec *ret = parse_optional_type(); + Ast_Expr *ret = parse_optional_type(); Ast_Block *block = is_typespec ? 0 : parse_block(); Ast_Lambda *result = ast_lambda(token, params, ret, block); return result; @@ -280,9 +280,9 @@ parse_lambda(Token *token, B32 is_typespec = false){ function Ast_Expr * null_denotation(Token *token){ switch(token->kind){ - case TK_StringLit : return ast_expr_string(token, token->intern_val); - case TK_Identifier : return ast_expr_identifier(token, token->intern_val); - case TK_Integer : return ast_expr_integer(token, token->int_val); + case TK_StringLit : return ast_str(token, token->intern_val); + case TK_Identifier : return ast_ident(token, token->intern_val); + case TK_Integer : return ast_int(token, token->int_val); case TK_Pointer : return ast_expr_unary(token, TK_Pointer, parse_expr()); case TK_Dereference: return ast_expr_unary(token, TK_Dereference, parse_expr()); case TK_OpenBracket: { @@ -295,7 +295,7 @@ null_denotation(Token *token){ token_expect(TK_OpenParen); Ast_Expr *expr = parse_expr(); token_expect(TK_Colon); - Ast_Typespec *typespec = parse_typespec(); + Ast_Expr *typespec = parse_expr(); token_expect(TK_CloseParen); return ast_expr_cast(token, expr, typespec); } @@ -435,9 +435,9 @@ parse_named(B32 is_global){ result = ast_const(name, name->intern_val, expr); } else if(token_match(TK_Colon)){ - Ast_Typespec *typespec = 0; - Ast_Expr *expr = 0; - if(!token_is(TK_Assign)) typespec = parse_typespec(); + Ast_Expr *typespec = 0; + Ast_Expr *expr = 0; + if(!token_is(TK_Assign)) typespec = parse_expr(); if(token_match(TK_Assign)) expr = parse_expr(); if(!expr && !typespec) parsing_error(name, "invalid declaration, no type or value"); diff --git a/new_resolve.cpp b/new_resolve.cpp index b5603eb..1c502d4 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -3,7 +3,6 @@ enum Sym_Kind{ SYM_NONE, - SYM_TYPESPEC, SYM_TYPE, SYM_CONST, SYM_VAR, @@ -34,6 +33,7 @@ struct Operand{ union { S64 int_val; Intern_String intern_val; + Ast_Resolved_Type *type_type; }; }; @@ -105,9 +105,9 @@ resolved_get(Ast *ast){ } function Ast_Resolved_Type * -resolved_typespec_get(Ast_Typespec *ast){ +resolved_type_get(Ast_Expr *ast){ Sym *result = resolved_get(ast); - assert(result->kind == SYM_TYPESPEC); + assert(result->kind == SYM_TYPE); assert(result->type); return result->type; } @@ -147,61 +147,62 @@ 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_Typespec *ast){ - if(!ast) return 0; - switch(ast->kind){ - Ast_Begin(AST_TYPESPEC_IDENT, Ast_Typespec){ - Sym *type_sym = sym_get(node->name); - 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"); - } +// function Ast_Resolved_Type * +// eval_typespec(Ast_Expr *ast){ +// if(!ast) return 0; - sym_new_resolved(SYM_TYPESPEC, {}, type_sym->type, node); - return type_sym->type; - Ast_End(); - } +// 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"); +// } - Ast_Begin(AST_TYPESPEC_LAMBDA, Ast_Typespec){ - 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)); +// sym_new_resolved(SYM_TYPESPEC, {}, type_sym->type, node); +// return type_sym->type; +// Ast_End(); +// } - 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_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_Begin(AST_TYPESPEC_POINTER, Ast_Typespec){ - Ast_Resolved_Type *type = eval_typespec(node->base); - Ast_Resolved_Type *resolved_type = type_pointer(type); +// Ast_Resolved_Type *resolved_type = type_lambda(ret, args); +// sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); +// return resolved_type; +// Ast_End(); +// } - 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); - 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]); +// sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); +// return resolved_type; +// Ast_End(); +// } - 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; -} +// 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){ @@ -328,8 +329,14 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple node->kind = AST_STR; node->intern_val = result.intern_val; } - } + + else if(sym->kind == SYM_TYPE){ + result.type = type_type; + result.type_type = sym->type; + sym_new_resolved(SYM_TYPE, sym->name, sym->type, node); + } + else{ result.type = sym->type; result.is_const = sym->kind == SYM_CONST ? true : false; @@ -340,27 +347,51 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Ast_End(); } + Ast_Begin(AST_ARRAY, Ast_Array){ + Operand type = eval_expr(node->base); + if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types"); + Operand expr = eval_expr(node->expr); + 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); + return type; + Ast_End(); + } + Ast_Begin(AST_LAMBDA, Ast_Lambda){ - Ast_Resolved_Type *type = eval_typespec(ast_typespec_lambda(node->pos, node)); + // @note: first resolve type of lambda + Scratch scratch; + Ast_Resolved_Type *lambda_type = 0; + Operand ret_op = eval_expr(node->ret); + Array args = {scratch}; + if(ret_op.type != type_type) parsing_error(node->pos, "Return type of [Lambda] should be a [Type] not %s", ret_op.type); + 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); + } + lambda_type = type_lambda(ret_op.type_type, args); + assert(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){ S64 scope_index = scope_open(); For(node->args){ - Ast_Resolved_Type *type = eval_typespec(it[0]->typespec); + S64 i = node->args.get_index(it); + Ast_Resolved_Type *type = args[i]; + Sym *arg_sym = sym_new_resolved(SYM_VAR, it[0]->name, type, it[0]); sym_insert(arg_sym); } - - Sym *resolved_ret = resolved_get(node->ret); - assert(resolved_ret->kind == SYM_TYPESPEC); For(node->block->stmts){ - eval_stmt(it[0], resolved_ret->type); + eval_stmt(it[0], ret_op.type_type); } scope_close(scope_index); } - return {type, true}; + return {lambda_type, true}; Ast_End(); } @@ -375,42 +406,46 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple } Ast_Begin(AST_COMPOUND, Ast_Compound){ - 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; + 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; - 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; + // Operand result = {type, false}; + // return result; + not_implemented; Ast_End(); } Ast_Begin(AST_CAST, Ast_Cast){ Operand expr = eval_expr(node->expr); - Ast_Resolved_Type *type = eval_typespec(node->typespec); + 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; if(type == expr.type) return expr; @@ -486,9 +521,10 @@ eval_decl(Ast *ast, Sym *sym){ switch(ast->kind){ Ast_Begin(AST_VAR, Ast_Var){ - Ast_Resolved_Type *type = eval_typespec(node->typespec); - Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; - expr.type = resolve_type_pair(node->pos, type, expr.type); + 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); return expr; Ast_End(); } @@ -530,11 +566,11 @@ resolve_sym(Sym *sym){ // @note: lambda doesn't need body for it to be usable // quickly resolve the type so we can have recursive functions - Ast_Lambda *lambda = ast_get_lambda(sym->ast); - if(lambda){ - sym->type = eval_typespec(ast_typespec_lambda(lambda->pos, lambda)); - sym->state = SYM_RESOLVED; - } + // Ast_Lambda *lambda = ast_get_lambda(sym->ast); + // if(lambda){ + // sym->type = eval_typespec(ast_typespec_lambda(lambda->pos, lambda)); + // sym->state = SYM_RESOLVED; + // } Operand op = eval_decl(sym->ast, sym); sym->type = op.type; diff --git a/new_type.cpp b/new_type.cpp index dd23905..a38af7d 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -12,6 +12,7 @@ enum Ast_Resolved_Type_Kind{ TYPE_Struct, TYPE_Union, TYPE_Enum, + TYPE_Type, }; const char *type_names[] = { @@ -28,6 +29,7 @@ const char *type_names[] = { "[Struct]", "[Union]", "[Enum]", + "[Type]", }; struct Ast_Resolved_Type{ @@ -56,7 +58,9 @@ global Ast_Resolved_Type type__int = {TYPE_Int, sizeof(int), __alignof(int)}; global Ast_Resolved_Type type__unsigned = {TYPE_Int, sizeof(unsigned), __alignof(unsigned)}; 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_Resolved_Type *type_type = &type__type; global Ast_Resolved_Type *type_void = &type__void; global Ast_Resolved_Type *type_int = &type__int; global Ast_Resolved_Type *type_unsigned = &type__unsigned;