diff options
| -rw-r--r-- | ast.h | 2 | ||||
| -rw-r--r-- | compile.c | 35 | ||||
| -rw-r--r-- | parse.c | 6 | ||||
| -rw-r--r-- | typecheck.c | 3 |
4 files changed, 28 insertions, 18 deletions
@@ -186,7 +186,7 @@ struct ast_s { type_ast_t *ret_type; ast_t *body; ast_t *cache; - bool is_inline, is_private; + bool is_inline; } FunctionDef; struct { arg_ast_t *args; @@ -414,7 +414,8 @@ CORD compile_statement(env_t *env, ast_t *ast) } case FunctionDef: { auto fndef = Match(ast, FunctionDef); - CORD name = compile(env, fndef->name); + bool is_private = Match(fndef->name, Var)->name[0] == '_'; + CORD name = is_private ? CORD_cat("$", Match(fndef->name, Var)->name) : compile(env, fndef->name); type_t *ret_t = fndef->ret_type ? parse_type_ast(env, fndef->ret_type) : Type(VoidType); CORD arg_signature = "("; @@ -427,7 +428,7 @@ CORD compile_statement(env_t *env, ast_t *ast) CORD ret_type_code = compile_type(env, ret_t); - if (fndef->is_private) + if (is_private) env->code->staticdefs = CORD_all(env->code->staticdefs, "static ", ret_type_code, " ", name, arg_signature, ";\n"); else env->code->fndefs = CORD_all(env->code->fndefs, ret_type_code, " ", name, arg_signature, ";\n"); @@ -439,7 +440,7 @@ CORD compile_statement(env_t *env, ast_t *ast) code = CORD_all(ret_type_code, " ", name, arg_signature); if (fndef->is_inline) code = CORD_cat("inline ", code); - if (!fndef->is_private) + if (!is_private) code = CORD_cat("public ", code); } @@ -480,7 +481,7 @@ CORD compile_statement(env_t *env, ast_t *ast) } CORD wrapper = CORD_all( - fndef->is_private ? CORD_EMPTY : "public ", ret_type_code, " ", name, arg_signature, "{\n" + is_private ? CORD_EMPTY : "public ", ret_type_code, " ", name, arg_signature, "{\n" "static table_t cache = {};\n", compile_type(env, args_t), " args = {", all_args, "};\n" "static const TypeInfo *table_type = $TableInfo(", compile_type_info(env, args_t), ", ", compile_type_info(env, ret_t), ");\n", @@ -2055,7 +2056,7 @@ module_code_t compile_file(ast_t *ast) for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { // Hack: make sure global is bound as foo$var: - if (stmt->ast->tag == Declare) + if (stmt->ast->tag == Declare && Match(Match(stmt->ast, Declare)->var, Var)->name[0] != '_') env->scope_prefix = heap_strf("%s$", name); bind_statement(env, stmt->ast); env->scope_prefix = NULL; @@ -2063,18 +2064,28 @@ module_code_t compile_file(ast_t *ast) for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { if (stmt->ast->tag == Declare) { auto decl = Match(stmt->ast, Declare); + const char *decl_name = Match(decl->var, Var)->name; + bool is_private = (decl_name[0] == '_'); type_t *t = get_type(env, decl->value); if (t->tag == AbortType || t->tag == VoidType) code_err(stmt->ast, "You can't declare a variable with a %T value", t); if (!is_constant(decl->value)) code_err(decl->value, "This value is not a valid constant initializer."); - env->code->fndefs = CORD_all( - env->code->fndefs, - compile_declaration(env, t, CORD_cat(env->file_prefix, Match(decl->var, Var)->name)), ";\n"); - env->code->staticdefs = CORD_all( - env->code->staticdefs, - "extern ", compile_type(env, t), " ", env->file_prefix, Match(decl->var, Var)->name, " = ", - compile(env, decl->value), ";\n"); + + if (is_private) { + env->code->staticdefs = CORD_all( + env->code->staticdefs, + "static ", compile_type(env, t), " $", decl_name, " = ", + compile(env, decl->value), ";\n"); + } else { + env->code->fndefs = CORD_all( + env->code->fndefs, + compile_declaration(env, t, CORD_cat(env->file_prefix, decl_name)), ";\n"); + env->code->staticdefs = CORD_all( + env->code->staticdefs, + "extern ", compile_type(env, t), " ", env->file_prefix, decl_name, " = ", + compile(env, decl->value), ";\n"); + } } else { CORD code = compile_statement(env, stmt->ast); assert(!code); @@ -1824,7 +1824,7 @@ PARSER(parse_func_def) { arg_ast_t *args = parse_args(ctx, &pos, false); whitespace(&pos); - bool is_inline = false, is_private = false; + bool is_inline = false; ast_t *cache_ast = NULL; for (bool specials = match(&pos, ";"); specials; specials = match_separator(&pos)) { const char *flag_start = pos; @@ -1837,8 +1837,6 @@ PARSER(parse_func_def) { parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'"); whitespace(&pos); cache_ast = expect(ctx, start, &pos, parse_expr, "I expected a maximum size for the cache"); - } else if (match_word(&pos, "private")) { - is_private = true; } } expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this function definition"); @@ -1852,7 +1850,7 @@ PARSER(parse_func_def) { "This function needs a body block"); return NewAST(ctx->file, start, pos, FunctionDef, .name=name, .args=args, .ret_type=ret_type, .body=body, .cache=cache_ast, - .is_inline=is_inline, .is_private=is_private); + .is_inline=is_inline); } PARSER(parse_extern) { diff --git a/typecheck.c b/typecheck.c index 518b7ce4..efc105af 100644 --- a/typecheck.c +++ b/typecheck.c @@ -109,7 +109,8 @@ void bind_statement(env_t *env, ast_t *statement) auto def = Match(statement, FunctionDef); type_t *type = get_function_def_type(env, statement); const char *name = Match(def->name, Var)->name; - CORD code = CORD_all(env->file_prefix, env->scope_prefix, name); + bool is_private = (name[0] == '_'); + CORD code = is_private ? CORD_cat("$", name) : CORD_all(env->file_prefix, env->scope_prefix, name); set_binding(env, name, new(binding_t, .type=type, .code=code)); break; } |
