txlyre 21 hours ago
parent
commit
64e28991ab
1 changed files with 41 additions and 16 deletions
  1. 41 16
      qic.c

+ 41 - 16
qic.c

@@ -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();