From e98f6854f5995c42d16641cee0281dacde4cc25c Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 17 Apr 2024 13:44:01 -0400 Subject: [PATCH] Use leading underscore for file-local variables and functions instead of "private" keyword --- ast.h | 2 +- compile.c | 35 +++++++++++++++++++++++------------ parse.c | 6 ++---- typecheck.c | 3 ++- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/ast.h b/ast.h index 1f0eb5a..34c3ffa 100644 --- a/ast.h +++ b/ast.h @@ -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; diff --git a/compile.c b/compile.c index 27b4a44..7ad4599 100644 --- a/compile.c +++ b/compile.c @@ -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); diff --git a/parse.c b/parse.c index fd071a0..48ddf98 100644 --- a/parse.c +++ b/parse.c @@ -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 518b7ce..efc105a 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; }