|
@@ -456,7 +456,7 @@ void format_error(char *filename, char *source, size_t pos, char *fmt, ...) {
|
|
|
fputc('\n', stderr);
|
|
|
fputc('\t', stderr);
|
|
|
|
|
|
- for (size_t i = 0; i < col && i < 64; i++)
|
|
|
+ for (size_t i = 1; i < col && i < 64; i++)
|
|
|
fputc(' ', stderr);
|
|
|
|
|
|
fputs("^\n", stderr);
|
|
@@ -2438,6 +2438,8 @@ size_t count_ctxs(list_t *ctx, char *s) {
|
|
|
return k;
|
|
|
}
|
|
|
|
|
|
+list_t *CONSTANTS;
|
|
|
+
|
|
|
#define INCTX(s) (in_context(ctx, (s)))
|
|
|
#define SCOPESK (count_ctxs(ctx, "scope"))
|
|
|
#define TRAPSK (count_ctxs(ctx, "trap"))
|
|
@@ -2463,6 +2465,7 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
LBPUSH();
|
|
|
CTXPUSH("gap");
|
|
|
CTXPUSH("func");
|
|
|
+ list_push(CONSTANTS, table_new());
|
|
|
|
|
|
size_t optargc = 0;
|
|
|
|
|
@@ -2487,6 +2490,7 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
|
|
|
compile_node(gbuf, tbuf, ctx, table_new(), stack_new(), stack_new(), lbl, node->a);
|
|
|
|
|
|
+ list_pop(CONSTANTS);
|
|
|
CTXPOP();
|
|
|
CTXPOP();
|
|
|
LBPOP();
|
|
@@ -2513,23 +2517,37 @@ void compile_func(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
EMIT(");");
|
|
|
}
|
|
|
|
|
|
-table_t *CONSTANTS;
|
|
|
+int const_set(char *name, node_t *val) {
|
|
|
+ table_t *table = list_index(CONSTANTS, -1);
|
|
|
+
|
|
|
+ if (table_get(table, name))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ table_set(table, name, val);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+node_t *const_get(char *name) {
|
|
|
+ node_t *val = NULL;
|
|
|
|
|
|
-void compile_block(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, list_t *block, int toplevel) {
|
|
|
+ for (ssize_t i = CONSTANTS->length-1; i >= 0; i--)
|
|
|
+ if ((val = table_get(CONSTANTS->data[i], name)))
|
|
|
+ break;
|
|
|
+
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
+void compile_block(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, list_t *block) {
|
|
|
for (size_t i = 0; i < block->length; i++) {
|
|
|
node_t *node = block->data[i];
|
|
|
|
|
|
if (node->tag == N_CONST) {
|
|
|
- if (!toplevel)
|
|
|
- COMPILE_ERROR("const is not on top-level")
|
|
|
-
|
|
|
table_iterate(node->h, {
|
|
|
char *name = entry.key;
|
|
|
|
|
|
- if (table_get(CONSTANTS, name))
|
|
|
+ if (!const_set(name, entry.value))
|
|
|
COMPILE_ERROR("redeclaration of compile-time constant: '%s'", name);
|
|
|
-
|
|
|
- table_set(CONSTANTS, name, entry.value);
|
|
|
});
|
|
|
} else if (node->tag == N_FUNCDEF) {
|
|
|
compile_func(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node, NULL);
|
|
@@ -2601,7 +2619,7 @@ void compile_block(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, st
|
|
|
|
|
|
for (size_t i = 0; i < block->length; i++) {
|
|
|
node_t *n = block->data[i];
|
|
|
- if (n->tag == N_FUNCDEF)
|
|
|
+ if (n->tag == N_CONST || n->tag == N_FUNCDEF || n->tag == N_CLASS || n->tag == N_PASS)
|
|
|
continue;
|
|
|
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, n);
|
|
@@ -3512,7 +3530,7 @@ buffer_t *HBUF;
|
|
|
void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, stack_t *lstk, stack_t *sstk, list_t *lbl, node_t *node) {
|
|
|
switch (node->tag) {
|
|
|
case N_TOPLEVEL: case N_PROGRAM:
|
|
|
- compile_block(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l, node->tag == N_TOPLEVEL);
|
|
|
+ compile_block(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
|
|
|
break;
|
|
|
|
|
|
case N_EXPRSTMT:
|
|
@@ -3524,9 +3542,11 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
case N_BLOCK:
|
|
|
LBPUSH();
|
|
|
CTXPUSH("scope");
|
|
|
+ list_push(CONSTANTS, table_new());
|
|
|
EMIT("qi_new_scope(state);\n");
|
|
|
- compile_block(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l, 0);
|
|
|
+ compile_block(gbuf, buf, ctx, ltab, lstk, sstk, lbl, node->l);
|
|
|
EMIT("qi_old_scope(state);");
|
|
|
+ list_pop(CONSTANTS);
|
|
|
CTXPOP();
|
|
|
LBPOP();
|
|
|
break;
|
|
@@ -3614,9 +3634,9 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
|
|
|
buffer_t *fname = buffer_new();
|
|
|
size_t line, col;
|
|
|
- (void)traverse(GETSRC(-1), node->pos, &line, &col);
|
|
|
+ (void)traverse(GETSRC(node->fi), node->pos, &line, &col);
|
|
|
|
|
|
- buffer_fmt(fname, "<fstring at %s:%zu:%zu>", GETFNAME(-1), line, col);
|
|
|
+ buffer_fmt(fname, "<fstring at %s:%zu:%zu>", GETFNAME(node->fi), line, col);
|
|
|
|
|
|
list_push(pair, buffer_read(fname));
|
|
|
list_push(pair, source);
|
|
@@ -3670,7 +3690,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
|
|
|
case T_NAME: {
|
|
|
char *name = node->t->text;
|
|
|
- node_t *n = table_get(CONSTANTS, name);
|
|
|
+ node_t *n = const_get(name);
|
|
|
|
|
|
if (n)
|
|
|
compile_node(gbuf, buf, ctx, ltab, lstk, sstk, lbl, n);
|
|
@@ -4163,7 +4183,9 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab, sta
|
|
|
|
|
|
LBPUSH();
|
|
|
CTXPUSH("gap");
|
|
|
+ list_push(CONSTANTS, table_new());
|
|
|
compile_node(gbuf, tbuf, ctx, table_new(), stack_new(), stack_new(), lbl, node->a);
|
|
|
+ list_pop(CONSTANTS);
|
|
|
CTXPOP();
|
|
|
LBPOP();
|
|
|
|
|
@@ -4492,7 +4514,10 @@ char *compile_file(char *filename, FILE *fd, list_t *required) {
|
|
|
int main(int argc, char **argv) {
|
|
|
FILES = list_new();
|
|
|
REQUIRED = list_new();
|
|
|
- CONSTANTS = table_new();
|
|
|
+
|
|
|
+ CONSTANTS = list_new();
|
|
|
+ list_push(CONSTANTS, table_new());
|
|
|
+
|
|
|
HBUF = buffer_new();
|
|
|
|
|
|
genmathlib();
|