Initial working version of types as expressions

This commit is contained in:
Krzosa Karol
2022-05-27 13:46:27 +02:00
parent d8a9b318b7
commit 46abf8c1a6
6 changed files with 159 additions and 171 deletions

View File

@@ -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<Ast_Resolved_Type *> 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<Ast_Resolved_Type *> 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<Ast_Resolved_Type *> 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;