Added lambda expressions, lambda types, no body yet

This commit is contained in:
Krzosa Karol
2022-05-20 17:16:53 +02:00
parent 30736d37b6
commit 236ff0cd64
8 changed files with 329 additions and 153 deletions

View File

@@ -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,9 +113,22 @@ 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<Ast_Expr *> params;
Ast_Typespec *ret;
};
struct Ast_Typespec:Ast{
union{
Ast_Typespec *base;
@@ -123,10 +137,7 @@ struct Ast_Typespec:Ast{
Ast_Typespec *base;
Ast_Expr *expr;
}arr;
struct{
Ast_Typespec *ret;
Array<Ast_Typespec*> args;
}func;
Ast_Lambda *lambda;
};
};
@@ -155,32 +166,33 @@ struct Ast_Package:Ast{
#define AST_NEW(T,ikind,ipos) \
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<Ast_Expr *> 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<Ast_Expr *> 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<Ast_Expr *> 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<Ast_Typespec*> 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<Ast_Typespec*> 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<Ast_Decl *> 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;

View File

@@ -82,6 +82,9 @@ enum Token_Kind{
TK_Float,
TK_Integer,
TK_Keyword,
TK_Pointer = TK_BitXor,
TK_Dereference,
};
struct Token{

View File

@@ -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<Ast_Expr *> 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_Identifier: return ast_expr_identifier(token, token->intern_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)){
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 = parse_expr_led(token, left);
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<Test> 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<Ast_Typespec *> 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);

View File

@@ -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<Type *> 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);

View File

@@ -111,7 +111,7 @@ type_array(Type *base, SizeU size){
}
function Type *
type_function(Type *ret, Array<Type *> args){
type_lambda(Type *ret, Array<Type *> 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<Type*> 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<Type*> 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);
}

View File

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

View File

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

10
type.c
View File

@@ -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);