From 31beca9f417c2c4fd32eaae01b3e855acf892220 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 24 Aug 2025 17:19:24 -0400 Subject: Split out blocks into their own file --- src/compile/blocks.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/compile/blocks.c (limited to 'src/compile/blocks.c') 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; +} -- cgit v1.2.3