1 // This file defines how to compile blocks
4 #include "../environment.h"
5 #include "../stdlib/datatypes.h"
6 #include "../stdlib/text.h"
7 #include "../stdlib/util.h"
8 #include "../typecheck.h"
9 #include "compilation.h"
12 Text_t compile_block(env_t *env, ast_t *ast) {
13 return Texts("{\n", compile_inline_block(env, ast), "}\n");
16 Text_t compile_block_expression(env_t *env, ast_t *ast) {
17 ast_list_t *stmts = Match(ast, Block)->statements;
18 if (stmts && !stmts->next) return compile(env, stmts->ast);
20 Text_t code = Text("({\n");
21 deferral_t *prev_deferred = env->deferred;
22 env = fresh_scope(env);
23 for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next)
24 prebind_statement(env, stmt->ast);
25 for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) {
27 code = Texts(code, compile_statement(env, stmt->ast), "\n");
29 // TODO: put defer after evaluating block expression
30 for (deferral_t *deferred = env->deferred; deferred && deferred != prev_deferred;
31 deferred = deferred->next) {
32 code = Texts(code, compile_statement(deferred->defer_env, deferred->block));
34 code = Texts(code, compile(env, stmt->ast), ";\n");
36 bind_statement(env, stmt->ast);
39 return Texts(code, "})");
43 Text_t compile_inline_block(env_t *env, ast_t *ast) {
44 if (ast->tag != Block) return compile_statement(env, ast);
46 Text_t code = EMPTY_TEXT;
47 ast_list_t *stmts = Match(ast, Block)->statements;
48 deferral_t *prev_deferred = env->deferred;
49 env = fresh_scope(env);
50 for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next)
51 prebind_statement(env, stmt->ast);
52 for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) {
53 code = Texts(code, compile_statement(env, stmt->ast), "\n");
54 bind_statement(env, stmt->ast);
56 for (deferral_t *deferred = env->deferred; deferred && deferred != prev_deferred; deferred = deferred->next) {
57 code = Texts(code, compile_statement(deferred->defer_env, deferred->block));