aboutsummaryrefslogtreecommitdiff
path: root/src/compile
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile')
-rw-r--r--src/compile/blocks.c59
-rw-r--r--src/compile/blocks.h8
-rw-r--r--src/compile/functions.c1
-rw-r--r--src/compile/statements.c25
-rw-r--r--src/compile/statements.h1
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);