diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 17:19:24 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-24 17:19:24 -0400 |
| commit | 31beca9f417c2c4fd32eaae01b3e855acf892220 (patch) | |
| tree | a1d3e656b908d6da6cf8887201f2fa89a82b1142 /src/compile | |
| parent | 2245c883680ccfbe545f230d6b68c38ce54bceb6 (diff) | |
Split out blocks into their own file
Diffstat (limited to 'src/compile')
| -rw-r--r-- | src/compile/blocks.c | 59 | ||||
| -rw-r--r-- | src/compile/blocks.h | 8 | ||||
| -rw-r--r-- | src/compile/functions.c | 1 | ||||
| -rw-r--r-- | src/compile/statements.c | 25 | ||||
| -rw-r--r-- | src/compile/statements.h | 1 |
5 files changed, 72 insertions, 22 deletions
diff --git a/src/compile/blocks.c b/src/compile/blocks.c new file mode 100644 index 00000000..1aa25531 --- /dev/null +++ b/src/compile/blocks.c @@ -0,0 +1,59 @@ + +#include "blocks.h" +#include "../ast.h" +#include "../compile.h" +#include "../environment.h" +#include "../stdlib/datatypes.h" +#include "../stdlib/text.h" +#include "../stdlib/util.h" +#include "../typecheck.h" +#include "statements.h" + +public +Text_t compile_block(env_t *env, ast_t *ast) { return Texts("{\n", compile_inline_block(env, ast), "}\n"); } + +Text_t compile_block_expression(env_t *env, ast_t *ast) { + ast_list_t *stmts = Match(ast, Block)->statements; + if (stmts && !stmts->next) return compile(env, stmts->ast); + + Text_t code = Text("({\n"); + deferral_t *prev_deferred = env->deferred; + env = fresh_scope(env); + for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) + prebind_statement(env, stmt->ast); + for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) { + if (stmt->next) { + code = Texts(code, compile_statement(env, stmt->ast), "\n"); + } else { + // TODO: put defer after evaluating block expression + for (deferral_t *deferred = env->deferred; deferred && deferred != prev_deferred; + deferred = deferred->next) { + code = Texts(code, compile_statement(deferred->defer_env, deferred->block)); + } + code = Texts(code, compile(env, stmt->ast), ";\n"); + } + bind_statement(env, stmt->ast); + } + + return Texts(code, "})"); +} + +public +Text_t compile_inline_block(env_t *env, ast_t *ast) { + if (ast->tag != Block) return compile_statement(env, ast); + + Text_t code = EMPTY_TEXT; + ast_list_t *stmts = Match(ast, Block)->statements; + deferral_t *prev_deferred = env->deferred; + env = fresh_scope(env); + for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) + prebind_statement(env, stmt->ast); + for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) { + code = Texts(code, compile_statement(env, stmt->ast), "\n"); + bind_statement(env, stmt->ast); + } + for (deferral_t *deferred = env->deferred; deferred && deferred != prev_deferred; deferred = deferred->next) { + code = Texts(code, compile_statement(deferred->defer_env, deferred->block)); + } + return code; +} diff --git a/src/compile/blocks.h b/src/compile/blocks.h new file mode 100644 index 00000000..a964bcf0 --- /dev/null +++ b/src/compile/blocks.h @@ -0,0 +1,8 @@ + +#include "../ast.h" +#include "../environment.h" +#include "../stdlib/datatypes.h" + +Text_t compile_block(env_t *env, ast_t *ast); +Text_t compile_block_expression(env_t *env, ast_t *ast); +Text_t compile_inline_block(env_t *env, ast_t *ast); diff --git a/src/compile/functions.c b/src/compile/functions.c index 5197b6f1..cc6aba87 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -12,6 +12,7 @@ #include "../typecheck.h" #include "../types.h" #include "assignments.h" +#include "blocks.h" #include "integers.h" #include "promotion.h" #include "statements.h" diff --git a/src/compile/statements.c b/src/compile/statements.c index ee70fdea..8dcac48c 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -2,16 +2,19 @@ #include "../ast.h" #include "../compile.h" +#include "../config.h" #include "../environment.h" #include "../modules.h" #include "../naming.h" #include "../stdlib/datatypes.h" #include "../stdlib/paths.h" +#include "../stdlib/print.h" #include "../stdlib/tables.h" #include "../stdlib/text.h" #include "../stdlib/util.h" #include "../typecheck.h" #include "assignments.h" +#include "blocks.h" #include "functions.h" #include "optionals.h" #include "pointers.h" @@ -30,26 +33,6 @@ Text_t with_source_info(env_t *env, ast_t *ast, Text_t code) { } public -Text_t compile_inline_block(env_t *env, ast_t *ast) { - if (ast->tag != Block) return compile_statement(env, ast); - - Text_t code = EMPTY_TEXT; - ast_list_t *stmts = Match(ast, Block)->statements; - deferral_t *prev_deferred = env->deferred; - env = fresh_scope(env); - for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) - prebind_statement(env, stmt->ast); - for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) { - code = Texts(code, compile_statement(env, stmt->ast), "\n"); - bind_statement(env, stmt->ast); - } - for (deferral_t *deferred = env->deferred; deferred && deferred != prev_deferred; deferred = deferred->next) { - code = Texts(code, compile_statement(deferred->defer_env, deferred->block)); - } - return code; -} - -public Text_t compile_condition(env_t *env, ast_t *ast) { type_t *t = get_type(env, ast); if (t->tag == BoolType) { @@ -1002,7 +985,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { } } case Block: { - return Texts("{\n", compile_inline_block(env, ast), "}\n"); + return compile_block(env, ast); } case Comprehension: { if (!env->comprehension_action) code_err(ast, "I don't know what to do with this comprehension!"); diff --git a/src/compile/statements.h b/src/compile/statements.h index 8c8956e7..ed0234a2 100644 --- a/src/compile/statements.h +++ b/src/compile/statements.h @@ -3,6 +3,5 @@ #include "../stdlib/datatypes.h" Text_t compile_condition(env_t *env, ast_t *ast); -Text_t compile_inline_block(env_t *env, ast_t *ast); Text_t compile_statement(env_t *env, ast_t *ast); Text_t with_source_info(env_t *env, ast_t *ast, Text_t code); |
