Added lambda expressions, lambda types, no body yet
This commit is contained in:
@@ -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<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);
|
||||
|
||||
Reference in New Issue
Block a user