diff --git a/new_ast.cpp b/new_ast.cpp index 90e3a05..7374847 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -20,21 +20,14 @@ struct Parse_Ctx:Lexer{ Allocator *perm; // Stores: AST, tokens, interns Allocator *heap; + U64 unique_ids; Map global_syms; Map type_map; Token empty_token; S64 indent; - S64 pt[256]; // precedence table void init(Allocator *perm_allocator, Allocator *heap_allocator){ - const S64 addp = 1; - const S64 mulp = 2; - pt[TK_Add] = addp; - pt[TK_Sub] = addp; - pt[TK_Div] = mulp; - pt[TK_Mul] = mulp; - perm = perm_allocator; heap = heap_allocator; @@ -61,30 +54,33 @@ thread_local Parse_Ctx *pctx; // AST //----------------------------------------------------------------------------- enum Ast_Kind{ - AK_None, + AST_NONE, - AK_Package, + AST_PACKAGE, - AK_Expr_Str, - AK_Expr_Int, - AK_Expr_Cast, - AK_Expr_Ident, - AK_Expr_Binary, - AK_Expr_CompoundItem, - AK_Expr_Compound, + AST_STR, + AST_INT, + AST_CAST, + AST_IDENT, + AST_INDEX, + AST_UNARY, + AST_BINARY, + AST_COMPOUND_ITEM, + AST_COMPOUND, - AK_Decl_Func, - AK_Decl_Func_Arg, - AK_Decl_Const, - AK_Decl_Var, + AST_LAMBDA, + AST_LAMBDA_PARAM, + AST_CONST, + AST_VAR, - AK_Typespec_Ident, - AK_Typespec_Pointer, - AK_Typespec_Array, - AK_Typespec_Func + AST_TYPESPEC_IDENT, + AST_TYPESPEC_POINTER, + AST_TYPESPEC_ARRAY, + AST_TYPESPEC_LAMBDA }; struct Ast{ + U64 id; Ast_Kind kind; Token *pos; }; @@ -94,6 +90,11 @@ struct Ast_Expr:Ast{ union{ Intern_String intern_val; U64 int_val; + struct{ + Token_Kind op; + Ast_Expr *expr; + }unary; + struct{ Token_Kind op; Ast_Expr *left; @@ -112,21 +113,31 @@ struct Ast_Expr:Ast{ Ast_Expr *expr; Ast_Typespec *typespec; }cast; + struct{ + Ast_Expr *expr; + Ast_Expr *index; + }index; + struct{ + Intern_String name; + Ast_Typespec *typespec; + }lambda_param; }; }; +struct Ast_Lambda : Ast_Expr { + Array params; + Ast_Typespec *ret; +}; + struct Ast_Typespec:Ast{ union{ - Ast_Typespec *base; - Intern_String name; + Ast_Typespec *base; + Intern_String name; struct{ Ast_Typespec *base; Ast_Expr *expr; }arr; - struct{ - Ast_Typespec *ret; - Array args; - }func; + Ast_Lambda *lambda; }; }; @@ -153,34 +164,35 @@ struct Ast_Package:Ast{ // AST Constructors beginning with expressions //----------------------------------------------------------------------------- #define AST_NEW(T,ikind,ipos) \ -Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T); \ +Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T); \ result->kind = ikind; \ -result->pos = ipos +result->pos = ipos; \ +result->id = ++pctx->unique_ids function Ast_Expr * ast_expr_string(Token *pos, Intern_String string){ - AST_NEW(Expr, AK_Expr_Str, pos); + AST_NEW(Expr, AST_STR, pos); result->intern_val = string; return result; } function Ast_Expr * ast_expr_identifier(Token *pos, Intern_String string){ - AST_NEW(Expr, AK_Expr_Ident, pos); + AST_NEW(Expr, AST_IDENT, pos); result->intern_val = string; return result; } function Ast_Expr * ast_expr_integer(Token *pos, S64 integer){ - AST_NEW(Expr, AK_Expr_Int, pos); + AST_NEW(Expr, AST_INT, pos); result->int_val = integer; return result; } function Ast_Expr * ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ - AST_NEW(Expr, AK_Expr_Binary, op); + AST_NEW(Expr, AST_BINARY, op); result->binary.op = op->kind; result->binary.left = left; result->binary.right = right; @@ -189,7 +201,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ function Ast_Expr * ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array exprs){ - AST_NEW(Expr, AK_Expr_Compound, pos); + AST_NEW(Expr, AST_COMPOUND, pos); result->compound.typespec = typespec; result->compound.exprs = exprs.tight_copy(pctx->perm); return result; @@ -197,7 +209,7 @@ ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array exprs){ function Ast_Expr * ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *item){ - AST_NEW(Expr, AK_Expr_CompoundItem, pos); + AST_NEW(Expr, AST_COMPOUND_ITEM, pos); result->compound_item.name = name; result->compound_item.index = index; result->compound_item.item = item; @@ -206,42 +218,80 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *it function Ast_Expr * ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){ - AST_NEW(Expr, AK_Expr_Cast, pos); + AST_NEW(Expr, AST_CAST, pos); result->cast.expr = expr; result->cast.typespec = typespec; return result; } +function Ast_Expr * +ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){ + AST_NEW(Expr, AST_UNARY, pos); + result->unary.expr = expr; + result->unary.op = op; + return result; +} + +function Ast_Expr * +ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ + AST_NEW(Expr, AST_INDEX, pos); + result->index.expr = expr; + result->index.index = index; + return result; +} + + +function Ast_Lambda * +ast_lambda(Token *pos, Array params, Ast_Typespec *ret){ + AST_NEW(Lambda, AST_LAMBDA, pos); + result->params = params.tight_copy(pctx->perm); + result->ret = ret; + return result; +} + +function Ast_Expr * +ast_expr_lambda_empty(Token *pos){ + AST_NEW(Expr, AST_LAMBDA, pos); + return result; +} + +function Ast_Expr * +ast_expr_lambda_param(Token *pos, Intern_String name, Ast_Typespec *typespec){ + AST_NEW(Expr, AST_LAMBDA_PARAM, pos); + result->lambda_param.name = name; + result->lambda_param.typespec = typespec; + return result; +} + //----------------------------------------------------------------------------- // Typespecs //----------------------------------------------------------------------------- function Ast_Typespec * ast_typespec_name(Token *pos, Intern_String name){ - AST_NEW(Typespec, AK_Typespec_Ident, pos); + AST_NEW(Typespec, AST_TYPESPEC_IDENT, pos); result->name = name; return result; } function Ast_Typespec * ast_typespec_pointer(Token *pos, Ast_Typespec *base){ - AST_NEW(Typespec, AK_Typespec_Pointer, pos); + AST_NEW(Typespec, AST_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, AK_Typespec_Array, pos); + AST_NEW(Typespec, AST_TYPESPEC_ARRAY, pos); result->arr.base = base; result->arr.expr = expr; return result; } function Ast_Typespec * -ast_typespec_func(Token *pos, Ast_Typespec *ret, Array args){ - AST_NEW(Typespec, AK_Typespec_Func, pos); - result->func.ret = ret; - result->func.args = args.tight_copy(pctx->perm); +ast_typespec_lambda(Token *pos, Ast_Lambda *lambda){ + AST_NEW(Typespec, AST_TYPESPEC_LAMBDA, pos); + result->lambda = lambda; return result; } @@ -250,14 +300,14 @@ ast_typespec_func(Token *pos, Ast_Typespec *ret, Array args){ //----------------------------------------------------------------------------- function Ast_Decl * ast_decl_func(Token *pos, Intern_String name){ - AST_NEW(Decl, AK_Decl_Func, pos); + AST_NEW(Decl, AST_LAMBDA, pos); result->name = name; return result; } function Ast_Decl * ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){ - AST_NEW(Decl, AK_Decl_Var, pos); + AST_NEW(Decl, AST_VAR, pos); result->var.expr = expr; result->var.typespec = typespec; result->name = name; @@ -267,13 +317,13 @@ ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *e function Ast_Decl * ast_decl_const(Token *pos, Intern_String name, Ast_Expr *expr){ Ast_Decl *result = ast_decl_var(pos, 0, name, expr); - result->kind = AK_Decl_Const; + result->kind = AST_CONST; return result; } function Ast_Package * ast_package(Token *pos, String name, Array decls){ - AST_NEW(Package, AK_Package, pos); + AST_NEW(Package, AST_PACKAGE, pos); result->decls = decls.tight_copy(pctx->perm); result->name = intern_string(&pctx->interns, name); return result; diff --git a/new_lex.cpp b/new_lex.cpp index 8a90cef..2b7337b 100644 --- a/new_lex.cpp +++ b/new_lex.cpp @@ -82,6 +82,9 @@ enum Token_Kind{ TK_Float, TK_Integer, TK_Keyword, + + TK_Pointer = TK_BitXor, + TK_Dereference, }; struct Token{ diff --git a/new_parse.cpp b/new_parse.cpp index 63813a1..335853a 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -21,8 +21,8 @@ token_next(){ } function Token * -token_is(Token_Kind kind){ - Token *token = token_get(); +token_is(Token_Kind kind, S64 lookahead = 0){ + Token *token = token_get(lookahead); if(token->kind == kind){ return token; } @@ -158,12 +158,45 @@ parse_expr_compound(){ return result; } +function Ast_Typespec * +parse_optional_type(){ + Ast_Typespec *result = 0; + if(token_match(TK_Colon)) result = parse_typespec(); + return result; +} + +function Ast_Lambda * +parse_lambda(Token *token, B32 is_typespec = false){ // @Todo(Krzosa): is_typespec is not used currently + // @Todo(Krzosa): Combine this with typespec function parsing + Scratch scratch; + Array params = {scratch}; + // @Note(Krzosa): No need to guard against "()" + // We needed to lookahead to verify it's a function + // and this routine only fires when we have situation + // with at least one parameter + for(;;){ + Token *name = token_expect(TK_Identifier); + token_expect(TK_Colon); + Ast_Typespec *typespec = parse_typespec(); + Ast_Expr *param = ast_expr_lambda_param(name, name->intern_val, typespec); + params.add(param); + + if(!token_match(TK_Comma)){ + break; + } + } + token_expect(TK_CloseParen); + Ast_Lambda *result = ast_lambda(token, params, parse_optional_type()); + return result; +} + function Ast_Expr * -parse_expr_nud(Token *token){ +null_denotation(Token *token){ switch(token->kind){ - case TK_StringLit: return ast_expr_string(token, token->intern_val); + 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_Integer : return ast_expr_integer(token, token->int_val); + case TK_BitXor : return ast_expr_unary(token, TK_Dereference, parse_expr()); case TK_Keyword: { if(token->intern_val == keyword_cast){ token_expect(TK_OpenParen); @@ -179,22 +212,41 @@ parse_expr_nud(Token *token){ } }break; case TK_OpenBrace: return parse_expr_compound(); - case TK_OpenParen: {Ast_Expr *result = parse_expr(); token_expect(TK_CloseParen); return result;} + case TK_OpenParen: { + if(token_match(TK_CloseParen)) return ast_expr_lambda_empty(token); + else if(token_is(TK_Identifier) && token_is(TK_Colon, 1)) return parse_lambda(token); + else{ + Ast_Expr *result = parse_expr(); + token_expect(TK_CloseParen); + return result; + } + } default: parsing_error(token, "Unexpected token of kind: [%s] in expression", token_kind_string(token->kind).str); return 0; } } function S64 -op_precedence(Token_Kind kind){ - S64 result = pctx->pt[kind]; - return result; +left_binding_power(Token_Kind kind){ + switch(kind){ + case TK_Sub: case TK_Add: return 1; + case TK_Mul: case TK_Div: return 2; + default: return 0; + } +} + +function S64 +postfix_binding_power(Token_Kind kind){ + switch(kind){ + case TK_Increment: case TK_Decrement: case TK_BitXor: case TK_OpenBracket: return 1; + default: return 0; + } } function Ast_Expr * -parse_expr_led(Token *op, Ast_Expr *left){ +left_denotation(Token *op, Ast_Expr *left){ enum{ Left_Associative, Right_Associative }; S64 assoc = Left_Associative; - Ast_Expr *right = parse_expr(op_precedence(op->kind) - assoc); + Ast_Expr *right = parse_expr(left_binding_power(op->kind) - assoc); switch(op->kind){ case TK_Add: case TK_Mul: case TK_Sub: case TK_Div: return ast_expr_binary(left, right, op); default: parsing_error(op, "Unexpected token of kind: [%s] in expression", token_kind_string(op->kind).str); return 0; @@ -204,10 +256,30 @@ parse_expr_led(Token *op, Ast_Expr *left){ function Ast_Expr * parse_expr(S64 rbp){ Token *token = token_next(); - Ast_Expr *left = parse_expr_nud(token); - while(rbp < op_precedence(token_get()->kind)){ - token = token_next(); - left = parse_expr_led(token, left); + Ast_Expr *left = null_denotation(token); + for(;;){ + token = token_get(); + + if((rbp == 0) && (token->kind == TK_Increment || token->kind == TK_Decrement || token->kind == TK_BitXor || token->kind == TK_OpenBracket)){ + token_next(); + if(token->kind == TK_OpenBracket){ + Ast_Expr *index = parse_expr(); + left = ast_expr_index(token, left, index); + token_expect(TK_CloseBracket); + } + else{ + if(token->kind == TK_Increment) token->kind = TK_PostIncrement; + else if(token->kind == TK_Decrement) token->kind = TK_PostDecrement; + left = ast_expr_unary(token, token->kind, left); + } + } + + else if(rbp < left_binding_power(token->kind)){ + token = token_next(); + left = left_denotation(token, left); + } + else break; + } return left; } @@ -215,8 +287,16 @@ parse_expr(S64 rbp){ function S64 expr_eval(Ast_Expr *expr){ switch(expr->kind){ - case AK_Expr_Int: return expr->int_val; - case AK_Expr_Binary : { + case AST_INT: return expr->int_val; + case AST_UNARY:{ + S64 value = expr_eval(expr->unary.expr); + switch(expr->unary.op){ + case TK_PostDecrement: return value - 1; + case TK_PostIncrement: return value + 1; + default: invalid_codepath; + } + }break; + case AST_BINARY : { S64 left = expr_eval(expr->binary.left); S64 right = expr_eval(expr->binary.right); switch(expr->binary.op){ @@ -243,6 +323,8 @@ test_parse_expr(){ TEST_PARSER(); struct Test{String str;S64 val;}; Array exprs = {scratch}; + //exprs.add({"thing[1][2][3]"_s, 0}); + exprs.add({"4++++--"_s, 5}); exprs.add({"(4+5)*2"_s, (4+5)*2}); exprs.add({"4+5*2"_s, 4+5*2}); exprs.add({"4*5+5"_s, 4*5+5}); @@ -259,36 +341,12 @@ test_parse_expr(){ //----------------------------------------------------------------------------- // Parsing declarations //----------------------------------------------------------------------------- -function Ast_Typespec * -parse_optional_type(){ - Ast_Typespec *result = 0; - if(token_match(TK_Colon)) result = parse_typespec(); - return result; -} - -function Ast_Typespec * -parse_typespec_function(Token *token){ - Scratch scratch; - Array args = {scratch}; - if(!token_is(TK_CloseParen)) { - for(;;) { - args.add(parse_typespec()); - if(!token_match(TK_Comma)){ - break; - } - } - } - token_expect(TK_CloseParen); - Ast_Typespec *ret = parse_optional_type(); - Ast_Typespec *result = ast_typespec_func(token, ret, args); - return result; -} // [10]*int - Array of 10 pointers to ints function Ast_Typespec * parse_typespec_recurse(){ Token *token = token_get(); - if(token_match(TK_Mul)){ + if(token_match(TK_BitXor)){ Ast_Typespec *result = parse_typespec_recurse(); result = ast_typespec_pointer(token, result); return result; @@ -301,8 +359,8 @@ parse_typespec_recurse(){ return result; } else if(token_match(TK_OpenParen)){ - Ast_Typespec *result = parse_typespec_function(token); - return result; + Ast_Lambda *result = parse_lambda(token, true); + return ast_typespec_lambda(token, result); } else if(token_match(TK_Identifier)){ Ast_Typespec *result = ast_typespec_name(token, token->intern_val); diff --git a/new_resolve.cpp b/new_resolve.cpp index 64a85e4..4e7590c 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -1,4 +1,4 @@ -#define Ast_Begin(kind,type) case kind: { type *node = (type *)ast; +#define Ast_Begin(kind,type) case kind: { type *node = (type *)ast; #define Ast_End() } break enum Sym_Kind{ @@ -97,7 +97,7 @@ eval_typespec(Ast_Typespec *ast){ if(!ast) return 0; switch(ast->kind){ - Ast_Begin(AK_Typespec_Ident, Ast_Typespec){ + 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"); @@ -109,14 +109,24 @@ eval_typespec(Ast_Typespec *ast){ Ast_End(); } - Ast_Begin(AK_Typespec_Pointer, Ast_Typespec){ + Ast_Begin(AST_TYPESPEC_LAMBDA, Ast_Typespec){ + Scratch scratch; + Type *ret = eval_typespec(node->lambda->ret); + Array params = {scratch}; + For(node->lambda->params) params.add(eval_typespec(it[0]->lambda_param.typespec)); + Type *result = type_lambda(ret, params); + return result; + Ast_End(); + } + + Ast_Begin(AST_TYPESPEC_POINTER, Ast_Typespec){ Type *type = eval_typespec(node->base); Type *result = type_pointer(type); return result; Ast_End(); } - Ast_Begin(AK_Typespec_Array, Ast_Typespec){ + Ast_Begin(AST_TYPESPEC_ARRAY, Ast_Typespec){ 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"); @@ -149,19 +159,35 @@ resolve_type_pair(Token *pos, Type *a, Type *b){ function Operand eval_expr(Ast_Expr *ast, Type *exp_compound_type){ switch(ast->kind){ - Ast_Begin(AK_Expr_Int, Ast_Expr){ + Ast_Begin(AST_INT, Ast_Expr){ Operand result = {type_int, true, {.int_val=(S64)node->int_val}}; return result; Ast_End(); } - Ast_Begin(AK_Expr_Str, Ast_Expr){ + Ast_Begin(AST_STR, Ast_Expr){ Operand result = {type_string, true, {.intern_val = node->intern_val}}; return result; Ast_End(); } - Ast_Begin(AK_Expr_Compound, Ast_Expr){ + Ast_Begin(AST_LAMBDA, Ast_Lambda){ + Type *type = eval_typespec(ast_typespec_lambda(0, node)); + return {type, true}; + Ast_End(); + } + + Ast_Begin(AST_INDEX, Ast_Expr){ + Operand left = eval_expr(node->index.expr); + Operand index = eval_expr(node->index.index); + if(left.type->kind != TYPE_Array) parsing_error(node->pos, "Indexing variable that is not an array"); + if(index.type != type_int) parsing_error(node->pos, "Trying to index the array with invalid type, expected int"); + Operand result = {left.type->arr.base}; + return result; + Ast_End(); + } + + Ast_Begin(AST_COMPOUND, Ast_Expr){ Type *type = eval_typespec(node->compound.typespec); Type *variable_type = exp_compound_type; if(!type && variable_type) type = variable_type; @@ -173,16 +199,18 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){ Type *item_type = type->arr.base; For(node->compound.exprs){ - assert(it[0]->kind == AK_Expr_CompoundItem); - if(it[0]->compound_item.name) parsing_error(it[0]->pos, "Invalid array indexing in compound expression"); - if(it[0]->compound_item.index){ - Operand index_op = eval_expr(it[0]->compound_item.index); - if(!index_op.is_const) parsing_error(it[0]->pos, "Index in a compound expression is not a constant"); - if(index_op.type != type_int) parsing_error(it[0]->pos, "Index should be of type int"); - if(index_op.int_val > (type->arr.size - 1)) parsing_error(it[0]->pos, "Invalid index in compound expression, larger then type can store"); + assert(it[0]->kind == AST_COMPOUND_ITEM); + Ast_Expr *i = (Ast_Expr *)it[0]; + assert(i->kind == AST_COMPOUND_ITEM); + if(i->compound_item.name) parsing_error(i->pos, "Invalid array indexing in compound expression"); + if(i->compound_item.index){ + Operand index_op = eval_expr(i->compound_item.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(it[0]->compound_item.item); - if(expr.type != item_type) parsing_error(it[0]->pos, "Invalid type of item in compound expression"); + Operand expr = eval_expr(i->compound_item.item); + resolve_type_pair(i->pos, expr.type, item_type); } } else parsing_error(node->pos, "Invalid compound expression type"); @@ -192,7 +220,7 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){ Ast_End(); } - Ast_Begin(AK_Expr_Ident, Ast_Expr){ + Ast_Begin(AST_IDENT, Ast_Expr){ Sym *sym = sym_get(node->intern_val); if(!sym){ parsing_error(node->pos, "Identifier is undefined"); @@ -203,7 +231,7 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){ Ast_End(); } - Ast_Begin(AK_Expr_Cast, Ast_Expr){ + Ast_Begin(AST_CAST, Ast_Expr){ Operand expr = eval_expr(node->cast.expr); Type *type = eval_typespec(node->cast.typespec); @@ -229,7 +257,25 @@ eval_expr(Ast_Expr *ast, Type *exp_compound_type){ Ast_End(); } - Ast_Begin(AK_Expr_Binary, Ast_Expr){ + Ast_Begin(AST_UNARY, Ast_Expr){ + Operand value = eval_expr(node->unary.expr); + switch(node->unary.op){ + case TK_BitXor:{ + 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; + }break; + case TK_Dereference:{ + Operand result = {type_pointer(value.type)}; + return result; + }break; + invalid_default_case; return {}; + } + + Ast_End(); + } + + Ast_Begin(AST_BINARY, Ast_Expr){ Operand left = eval_expr(ast->binary.left); Operand right = eval_expr(ast->binary.right); Operand result = {}; @@ -262,14 +308,14 @@ function void eval_decl(Ast *ast){ switch(ast->kind){ - Ast_Begin(AK_Package, Ast_Package){ + Ast_Begin(AST_PACKAGE, Ast_Package){ For(node->decls) eval_decl(*it); Ast_End(); } - Ast_Begin(AK_Decl_Var, Ast_Decl){ + Ast_Begin(AST_VAR, Ast_Decl){ Type *type = eval_typespec(node->var.typespec); - Operand expr = eval_expr(node->var.expr, type); + Operand expr = node->var.expr ? eval_expr(node->var.expr, type) : Operand{}; Type *resolved_type = resolve_type_pair(node->pos, type, expr.type); Sym *sym = sym_new(SYM_Var, node->name, resolved_type, node); @@ -277,7 +323,7 @@ eval_decl(Ast *ast){ Ast_End(); } - Ast_Begin(AK_Decl_Const, Ast_Decl){ + Ast_Begin(AST_CONST, Ast_Decl){ Type *type = eval_typespec(node->var.typespec); if(type && type->kind == TYPE_Pointer) parsing_error(node->pos, "Const cant be a pointer"); Operand expr = eval_expr(node->var.expr); diff --git a/new_type.cpp b/new_type.cpp index d3f9716..06c1323 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -111,7 +111,7 @@ type_array(Type *base, SizeU size){ } function Type * -type_function(Type *ret, Array args){ +type_lambda(Type *ret, Array args){ U64 hash = hash_ptr(ret); For(args) hash = hash_mix(hash, hash_ptr(*it)); Type *result = (Type *)map_get_u64(&pctx->type_map, hash); @@ -153,8 +153,8 @@ test_types(){ Array types = {scratch}; types.add(type_array(type_int, 32)); - Type *func_type1 = type_function(types[0], types); - Type *func_type2 = type_function(types[0], types); + Type *func_type1 = type_lambda(types[0], types); + Type *func_type2 = type_lambda(types[0], types); assert(func_type1 == func_type2); Array types2 = {scratch}; @@ -163,8 +163,8 @@ test_types(){ types2.add(type_int); } types.add(type_int); - Type *func_type3 = type_function(types[0], types); - Type *func_type4 = type_function(types[0], types2); + Type *func_type3 = type_lambda(types[0], types); + Type *func_type4 = type_lambda(types[0], types2); assert(func_type1 != func_type3); assert(func_type3 == func_type4); } diff --git a/print.c b/print.c index 058f9b4..83b2af2 100644 --- a/print.c +++ b/print.c @@ -4,9 +4,6 @@ function void typespec_print(Typespec *spec); global S64 indent; #define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0) -#define AST_CAST(item, T) T *item = (T *)item -#define AST_IterT(parent, name, T) for(T *name = (T *)(parent)->first; name; name=(T *)name->next) // , assert(name->kind == AST_##type -#define AST_Iter(parent,name) AST_IterT(parent,name,AST) function void diff --git a/test3.kl b/test3.kl index 8ddbde6..6a7551a 100644 --- a/test3.kl +++ b/test3.kl @@ -1,35 +1,57 @@ +/* + +Player :: struct + id : int + name: String + +compound_of_struct: Player = { + id = 10, + name = "Guy", +} + +second_compound_syntax := :Player{...} + +max :: (a: int, b: int) { if a > b then return a; return b; } + +max :: (a: int, b: int) + if a > b then return a + return b + +; - treated as new line +{ and } - treated as new line scope and end of new line scope +*/ + +test_function :: (thing: int): ^int + +//----------------------------------------------------------------------------- +// Booleans +//----------------------------------------------------------------------------- boolean: bool = true value_of_bool: int = cast(boolean: int) base := null +//----------------------------------------------------------------------------- +// Compound expressions +//----------------------------------------------------------------------------- array1: [4]int = {1,2,3,4} array2: [32]int = {1,2,3,4} array3: [32]int = { [0] = 0, + [1] = 1, [31] = 31, } +array_item := array1[0] +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: *int -variable: int = *pointer -pointer_from_var := ^variable - -pointer := &base -base_from_pointer := *pointer - -structure: Data = {} - -array2: [4]int = { - [0] = 0, - [1] = 1 -} -array_to_pointer: *[4]int = &array1 -array_to_pointer_imp : = &array1 - - -*/ //----------------------------------------------------------------------------- // Implicit type //----------------------------------------------------------------------------- @@ -39,9 +61,9 @@ implicit_str :: "Hello world" //----------------------------------------------------------------------------- // Pointers //----------------------------------------------------------------------------- -pointer: *int = cast(null: *int) -pointer2: *int = null -pointer3: **int = null +pointer: ^int = cast(null: ^int) +pointer2: ^int = null +pointer3: ^^int = null //----------------------------------------------------------------------------- // String types diff --git a/type.c b/type.c index 41e6ef1..e745605 100644 --- a/type.c +++ b/type.c @@ -99,7 +99,7 @@ type_array(Arena *arena, Type *base, SizeU size){ } function Type * -type_function(Arena *arena, Type *ret, Type **params, S32 count){ +type_lambda(Arena *arena, Type *ret, Type **params, S32 count){ U64 hash = hash_ptr(ret); for(S32 i = 0; i < count; i++) hash = hash_mix(hash, hash_ptr(params[i])); @@ -138,8 +138,8 @@ test_types(){ Type **types = 0; array_push(types, type_array(arena, type_int, 32)); - Type *func_type1 = type_function(arena, types[0], types, array_len(types)); - Type *func_type2 = type_function(arena, types[0], types, array_len(types)); + Type *func_type1 = type_lambda(arena, types[0], types, array_len(types)); + Type *func_type2 = type_lambda(arena, types[0], types, array_len(types)); assert(func_type1 == func_type2); Type **types2 = 0; @@ -148,8 +148,8 @@ test_types(){ array_push(types2, type_int); } array_push(types, type_int); - Type *func_type3 = type_function(arena, types[0], types, array_len(types)); - Type *func_type4 = type_function(arena, types[0], types2, array_len(types)); + Type *func_type3 = type_lambda(arena, types[0], types, array_len(types)); + Type *func_type4 = type_lambda(arena, types[0], types2, array_len(types)); assert(func_type1 != func_type3); assert(func_type3 == func_type4);