More work on packages

This commit is contained in:
Krzosa Karol
2022-06-10 11:05:08 +02:00
parent b0077fe9df
commit d5d9911f3e
8 changed files with 158 additions and 185 deletions

View File

@@ -111,6 +111,8 @@ struct Ast_Binary: Ast_Expr{
Token_Kind op;
Ast_Expr *left;
Ast_Expr *right;
Ast_Resolved_Type *type;
};
// Problem: We are parsing out of order, in the middle of parsing a function

View File

@@ -4,6 +4,8 @@
global S32 global_indent;
global S32 is_inside_struct;
function void gen_ast(Ast *ast);
function void
gen_indent(){
for(S32 i = 0; i < global_indent; i++) gen(" ");
@@ -172,57 +174,13 @@ gen_expr(Ast_Expr *ast){
// BREAK();
// }
CASE(VAR, Decl){
gen_ast(node);
BREAK();
}
CASE(CALL, Call){
// @todo: Reach into map instead of direct lookup
if(is_struct(node->type) || is_array(node->type)){
if(is_array(node->type)){
gen("(Slice){%d, ", node->exprs.len);
}
gen("(");
gen_simple_decl(node->type, {});
gen(")");
gen("{");
For(node->exprs){
auto comp = it;
if(comp->name){
gen(".");
gen_expr(comp->name);
gen(" = ");
}
if(comp->index){
gen("[");
gen_expr(comp->index);
gen("] = ");
}
assert(comp->item);
gen_expr(comp->item);
if(!node->exprs.is_last(&it)) gen(", ");
}
gen("}");
if(is_array(node->type)){
gen("}");
}
}
else{
gen_expr(node->name);
gen("(");
auto name_for_printf = (Ast_Atom *)node->name;
For(node->exprs){
// @special_case @todo in the future this should be replaced
// with []Any
if(intern_printf == name_for_printf->intern_val && &it == node->exprs.data){
Ast_Atom *atom = (Ast_Atom *)it->item;
assert(atom->kind == AST_VALUE);
assert(atom->type == untyped_string);
gen("\"%s\"", atom->intern_val.str);
}
else gen_expr(it->item);
if(!node->exprs.is_last(&it)) gen(", ");
}
gen(")");
}
unused(node);
BREAK();
}
@@ -237,8 +195,6 @@ gen_line(Ast *node){
genln("#line %d", node->pos->line+1);
}
function void
gen_ast(Ast *ast);
function void
gen_stmt_scope(Ast_Scope *scope){
gen("{");
@@ -368,8 +324,7 @@ gen_ast(Ast *ast){
gen(")");
if(lambda->scope) {
// gen_stmt_scope(lambda->scope);
// @todo stmts
gen_stmt_scope(lambda->scope);
}
else gen(";");
}

View File

@@ -176,7 +176,7 @@ struct Parse_Ctx:Lexer{
U64 unique_ids;
Map type_map;
Ast_Scope *current_scope;
Array<Ast_Scope *> scopes;
Ast_Package *resolving_package;
Array<Ast_Decl *> ordered_decls;
@@ -221,6 +221,7 @@ parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator)
ctx->perm = perm_allocator;
ctx->heap = heap_allocator;
ctx->gen = {ctx->perm};
ctx->scopes = {ctx->heap};
ctx->ordered_decls = {ctx->heap};
ctx->type_map = {ctx->heap};
bigint_allocator = ctx->perm;

View File

@@ -28,16 +28,16 @@ add_10 :: (size: S64): S64
constant :: 20; result := constant + 10
v3 := add(1,2)
v2 := add(a = 1, b = 2)
v1 := add(a = 1)
// v_err := add([0] = 1)
v4 := add(b = 1, a = 2)
// v_err := add([0] = 1, [1] = 2)
// v_err := add([0] = 1, 10) // illegal
// v_err := add([1] = 1) // illegal
// v_err := add() // illegal
// v3 := add(1,2)
// v2 := add(a = 1, b = 2)
// v1 := add(a = 1)
// // v_err := add([0] = 1)
// v4 := add(b = 1, a = 2)
// // v_err := add([0] = 1, [1] = 2)
// // v_err := add([0] = 1, 10) // illegal
// // v_err := add([1] = 1) // illegal
// // v_err := add() // illegal
v4 := constant
return v4
return_constant :: (): S64
@@ -45,8 +45,8 @@ return_constant :: (): S64
return constant
returning_void :: (insert: S64)
val1: S64 = return_constant()
val2: S64 = add_10(val1)
// val1: S64 = return_constant()
// val2: S64 = add_10(val1)
return

View File

@@ -542,9 +542,6 @@ lex_restream(Lexer *lexer, String istream, String file){
lexer->stream.line_begin = istream.str;
lexer->stream.file = lexer->intern(file);
lexer->tokens.clear();
lexer->token_iter = 0;
Scratch scratch;
lexer->stream.indent_stack.allocator = scratch;
lexer->stream.indent_stack.add(&token_null);

View File

@@ -15,4 +15,5 @@ val := CONSTANT_VAL
DEPENDENCE :: CONSTANT_VAL
CONSTANT_VAL :: 10
thing: a_type = 10

View File

@@ -122,8 +122,6 @@ parse_init_stmt(Ast_Expr *expr){
if(token->kind == TK_ColonAssign && expr->kind != AST_IDENT)
compiler_error(expr->pos, "Binding with [:=] to something that is not an identifier");
else if(token_is_assign(token)){
token_next();
Ast_Expr *value = parse_expr();
@@ -131,10 +129,11 @@ parse_init_stmt(Ast_Expr *expr){
if(token->kind == TK_ColonAssign){
Ast_Atom *name = (Ast_Atom *)expr;
result = (Ast_Expr *)ast_var(token, 0, name->intern_val, value);
set_flag(result->flags, AST_EXPR);
} else{
result = ast_expr_binary((Ast_Atom *)expr, value, token);
}
result->flags = set_flag(result->flags, AST_STMT);
set_flag(result->flags, AST_STMT);
return result;
}

View File

@@ -330,98 +330,6 @@ require_const_int(Ast_Expr *expr, B32 ast_can_be_null){
return op;
}
function Operand
resolve_and_require_bool(const char *error, Ast_Expr *expr, B32 ast_can_be_null = AST_CANT_BE_NULL){
if(!expr){
if(ast_can_be_null)
return {};
else compiler_error(0, "Compiler error: Null expression");
}
Operand op = resolve_expr(expr);
if(!is_bool(op.type)){
compiler_error(expr->pos, "Expected type [Bool] got instead type %s :: %s", docname(op.type), error);
}
return op;
}
// @note: Ret is return value of function passed down the stack
// to check if type matches
function void
resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
if(!ast) return;
switch(ast->kind){
CASE(RETURN, Return){ // @todo: need to check if all paths return a value
Operand op = resolve_expr(node->expr);
if(!op.type && ret != type_void) compiler_error(node->pos, "Function expects a void return value but the returned value is %s", docname(op.type));
op.value = convert_untyped_to_typed(node->pos, op.value, ret);
if(op.type && op.type != ret) compiler_error(node->pos, "Return statement has different type then returned value, expecting: %s got instead %s", docname(ret), docname(op.type));
BREAK();
}
CASE(VAR, Var){
Operand op = resolve_binding(node);
sym_var(node->name, op, node, INSERT_INTO_SCOPE);
BREAK();
}
CASE(CONST, Const){
Operand op = resolve_binding(node);
sym_const(node->name, op, node, INSERT_INTO_SCOPE);
BREAK();
}
CASE(PASS, Pass){
unused(node);
BREAK();
}
CASE(FOR, For){
if(node->init && node->cond == 0 && node->iter == 0){
if(!is_flag_set(node->init->flags, AST_STMT)){
node->cond = node->init;
node->init = 0;
}
}
S64 scope = scope_open();
{
resolve_expr(node->init, ret);
resolve_and_require_bool("Conditional in a for loop condition", node->cond, AST_CAN_BE_NULL);
resolve_expr(node->iter, ret);
For(node->block->stmts)
resolve_stmt(it, ret);
}
scope_close(scope);
BREAK();
}
CASE(IF, If){
For(node->ifs){
resolve_stmt(it->init, ret);
S64 scope = scope_open();
{
// @todo: maybe add else kind ?? and then make sure other then else are AST_CANT_BE_NULL
resolve_and_require_bool("Conditional in a if condition", it->expr, AST_CAN_BE_NULL);
For_It(it->block->stmts, jt)
resolve_stmt(jt, ret);
}
scope_close(scope);
}
BREAK();
}
default:{
if(is_flag_set(ast->flags, AST_EXPR)){
assert(is_flag_set(ast->flags, AST_STMT));
resolve_expr((Ast_Expr *)ast);
}
else invalid_codepath;
}
}
}
function Operand
resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
@@ -924,18 +832,19 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
#define Enter_Scope(x) Enter_Scope_Defer package_scope(x)
struct Enter_Scope_Defer{
Ast_Scope *scope;
Ast_Package *package;
Ast_Scope *scope = 0;
Ast_Package *package = 0;
Enter_Scope_Defer(Ast_Scope *new_p){
scope = pctx->current_scope;
pctx->current_scope = new_p;
pctx->scopes.add(new_p);
scope = new_p;
if(new_p->kind == AST_PACKAGE){
package = pctx->resolving_package;
pctx->resolving_package = (Ast_Package *)new_p;
}
}
~Enter_Scope_Defer(){
pctx->current_scope = scope;
Ast_Scope *poped = pctx->scopes.pop();
assert(poped == scope);
if(package){
pctx->resolving_package = package;
}
@@ -954,9 +863,15 @@ search_for_decl(Ast_Scope *scope, Intern_String name){
function Ast_Decl *
search_for_decl_in_current_context(Intern_String name){
Ast_Decl *result = search_for_decl(pctx->current_scope, name);
Ast_Decl *result = 0;
for(S64 i = pctx->scopes.len - 1; i >= 0; i--){
result = search_for_decl(pctx->scopes[i], name);
if(result) break;
}
if(!result)
result = search_for_decl(pctx->resolving_package, name);
return result;
}
@@ -967,7 +882,7 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
function void
insert_into_current_scope(Ast_Decl *decl){
insert_into_scope(pctx->current_scope, decl);
insert_into_scope(*pctx->scopes.last(), decl);
}
function void
@@ -1006,6 +921,22 @@ resolve_typespec(Ast_Expr *ast, B32 flags){
return resolved.type_val;
}
function Operand
resolve_and_require_bool(const char *error, Ast_Expr *expr, B32 flags){
if(!expr){
if(flags == AST_CAN_BE_NULL)
return {};
else compiler_error(0, "Compiler error: Null expression");
}
Operand op = resolve_expr(expr, flags);
if(!is_bool(op.type)){
compiler_error(expr->pos, "Expected type [Bool] got instead type %s :: %s", docname(op.type), error);
}
return op;
}
function Operand
require_const_int(Ast_Expr *expr, B32 flags){
Operand op = resolve_expr(expr, flags);
@@ -1023,6 +954,15 @@ require_const_int(Ast_Expr *expr, B32 flags){
return op;
}
function void
resolve_const(Ast_Decl *node){
Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL);
if(!op.is_const){
compiler_error(node->pos, "Assigning a value that is not constant to a constant declaration");
}
node->value = op.value;
}
function void
resolve_var(Ast_Decl *node){
Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL);
@@ -1033,6 +973,83 @@ resolve_var(Ast_Decl *node){
node->value = op.value;
}
// @note: Ret is return value of function passed down the stack
// to check if type matches
function void
resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){
if(!ast) return;
switch(ast->kind){
CASE(RETURN, Return){ // @todo: need to check if all paths return a value
Operand op = resolve_expr(node->expr, AST_CAN_BE_NULL);
if(!op.type && ret != type_void) compiler_error(node->pos, "Function expects a void return value but the returned value is %s", docname(op.type));
op.value = convert_untyped_to_typed(node->pos, op.value, ret);
if(op.type && op.type != ret) compiler_error(node->pos, "Return statement has different type then returned value, expecting: %s got instead %s", docname(ret), docname(op.type));
BREAK();
}
// CASE(VAR, Decl){
// resolve_decl(node);
// insert_into_current_scope(node);
// BREAK();
// }
case AST_LAMBDA:
case AST_VAR:
CASE(CONST, Decl){
resolve_decl(node);
insert_into_current_scope(node);
BREAK();
}
CASE(PASS, Pass){
unused(node);
BREAK();
}
CASE(FOR, For){
if(node->init && node->cond == 0 && node->iter == 0){
if(!is_flag_set(node->init->flags, AST_STMT)){
node->cond = node->init;
node->init = 0;
}
}
{
Enter_Scope(node->scope);
resolve_expr(node->init, AST_CAN_BE_NULL);
resolve_and_require_bool("Conditional in a for loop condition", node->cond, AST_CAN_BE_NULL);
resolve_expr(node->iter, AST_CAN_BE_NULL);
For(node->scope->stmts)
resolve_stmt(it, ret);
}
BREAK();
}
CASE(IF, If){
For(node->ifs){
resolve_stmt(it->init, ret);
{
Enter_Scope(it->scope);
// @todo: maybe add else kind ?? and then make sure other then else are AST_CANT_BE_NULL
resolve_and_require_bool("Conditional in a if condition", it->expr, AST_CAN_BE_NULL);
For_It(it->scope->stmts, jt)
resolve_stmt(jt, ret);
}
}
BREAK();
}
default:{
if(is_flag_set(ast->flags, AST_EXPR)){
assert(is_flag_set(ast->flags, AST_STMT));
resolve_expr((Ast_Expr *)ast, AST_CANT_BE_NULL);
}
else invalid_codepath;
}
}
}
function Operand
resolve_expr(Ast_Expr *ast, B32 flags){
if(!ast && flags == AST_CAN_BE_NULL) return {};
@@ -1046,6 +1063,12 @@ resolve_expr(Ast_Expr *ast, B32 flags){
BREAK();
}
CASE(CALL, Call){
unused(node);
// return {};
BREAK();
}
CASE(IDENT, Atom){
Ast_Decl *decl = resolve_name(node->pos, node->intern_val);
@@ -1065,12 +1088,6 @@ resolve_expr(Ast_Expr *ast, B32 flags){
BREAK();
}
CASE(VAR, Decl){
resolve_var(node);
insert_into_current_scope(node);
BREAK();
}
CASE(BINARY, Binary){
if(token_is_assign(node->op)){
assert(is_flag_set(node->flags, AST_STMT));
@@ -1097,6 +1114,12 @@ resolve_expr(Ast_Expr *ast, B32 flags){
BREAK();
}
CASE(VAR, Decl){
resolve_stmt(node, 0);
return {};
BREAK();
}
CASE(UNARY, Unary){
Operand value = resolve_expr(node->expr, AST_CANT_BE_NULL);
if(node->op == TK_Pointer){
@@ -1177,8 +1200,7 @@ resolve_decl(Ast_Decl *ast){
insert_into_current_scope(it);
}
For(lambda->scope->stmts){
unused(it);
// resolve_stmt(it, ret_type);
resolve_stmt(it, ret_type);
}
result = operand_lambda(lambda_type);
@@ -1190,11 +1212,7 @@ resolve_decl(Ast_Decl *ast){
}
CASE(CONST, Decl){
Operand op = resolve_expr(node->expr, AST_CANT_BE_NULL);
if(!op.is_const){
compiler_error(node->pos, "Assigning a value that is not constant to a constant declaration");
}
node->value = op.value;
resolve_const(node);
BREAK();
}