about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--cccl.c2
-rw-r--r--cccl.h3
-rw-r--r--executor.c53
-rw-r--r--main.c16
4 files changed, 65 insertions, 9 deletions
diff --git a/cccl.c b/cccl.c
index 234fa7e..cd952d1 100644
--- a/cccl.c
+++ b/cccl.c
@@ -16,4 +16,6 @@ void cccl(struct cccl_File file)
 
     struct cccl_Variables scope = {0};
     cccl_execute(parsed, &scope, 0);
+    if (dump)
+        cccl_dump();
 }
diff --git a/cccl.h b/cccl.h
index 5452b26..8bf3d0c 100644
--- a/cccl.h
+++ b/cccl.h
@@ -89,6 +89,8 @@ struct cccl_Stack
 };
 
 extern int verbose;
+extern int interactive;
+extern int dump;
 
 int cccl_allocfile(const char *path, struct cccl_File *file);
 
@@ -96,6 +98,7 @@ void cccl(struct cccl_File file);
 size_t cccl_tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length);
 struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, enum cccl_NodeType type, char value);
 enum cccl_ExecutorStatus cccl_execute(struct cccl_Node *code, struct cccl_Variables *scope, size_t depth);
+void cccl_dump(void);
 
 const char *strtoken(enum cccl_TokenType type);
 const char *strnode(enum cccl_NodeType type);
diff --git a/executor.c b/executor.c
index e39df2c..ae92315 100644
--- a/executor.c
+++ b/executor.c
@@ -6,6 +6,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 
 static struct cccl_Variables globals = {0};
@@ -31,6 +32,11 @@ static size_t geti(char name)
     return islower(name) ? name - 'a' : name - 'A' + 26;
 }
 
+static char getnamebyi(size_t i)
+{
+    return i < 26 ? i + 'a' : i - 26 + 'A';
+}
+
 static short *get_variable(char name, struct cccl_Variables *scope)
 {
     size_t i = geti(name);
@@ -41,6 +47,21 @@ static short *get_variable(char name, struct cccl_Variables *scope)
     return NULL;
 }
 
+void cccl_dump(void)
+{
+    fputs("Globals:\n", stderr);
+    for (size_t i = 0; i < 52; ++i)
+        if (globals.used[i])
+            fprintf(stderr, "  %c=%d\n", getnamebyi(i), globals.buffer[i]);
+    fputs("Functions:\n", stderr);
+    for (size_t i = 0; i < 52; ++i)
+        if (functions[i].body)
+            fprintf(stderr, "  %c, %lu nodes\n", getnamebyi(i), functions[i].length);
+    fputs("Stack:\n", stderr);
+    for (size_t i = 0; i < stack.length; ++i)
+        fprintf(stderr, "  %d\n", stack.buffer[i]);
+}
+
 enum cccl_ExecutorStatus cccl_execute(struct cccl_Node *code, struct cccl_Variables *scope, size_t depth)
 {
     if (verbose)
@@ -48,6 +69,22 @@ enum cccl_ExecutorStatus cccl_execute(struct cccl_Node *code, struct cccl_Variab
             fprintf(stderr, "Executing %s with %d [%c], %lu nodes, depth %lu\n", strnode(code->type), code->value, code->value, code->in_length, depth);
         else
             fprintf(stderr, "Executing %s, %lu nodes, depth %lu\n", strnode(code->type), code->in_length, depth);
+    if (interactive)
+    {
+        char *line = NULL;
+        size_t lsize = 0;
+        ssize_t length = getline(&line, &lsize, stdin);
+        if (length == -1 && ferror(stdin))
+            err(1, "getline()");
+        if (!strcmp(line, "d\n"))
+        {
+            fputs("Locals:\n", stderr);
+            for (size_t i = 0; i < 52; ++i)
+                if (scope->used[i])
+                    fprintf(stderr, "  %c=%d\n", getnamebyi(i), scope->buffer[i]);
+            cccl_dump();
+        }
+    }
     switch (code->type)
     {
     case cccl_Node_CODE:
@@ -266,12 +303,16 @@ enum cccl_ExecutorStatus cccl_execute(struct cccl_Node *code, struct cccl_Variab
         enum cccl_ExecutorStatus res;
         if (stack.buffer[stack.length - 1] == *p)
             for (size_t i = 0; i < code->in_length; ++i)
-                switch ((res = cccl_execute(code->in[i], scope, depth + 1)))
-                {
-                case cccl_Executor_ERROR: return res;
-                case cccl_Executor_CONTINUE: return res;
-                case cccl_Executor_END: goto end;
-                }
+                if ((res = cccl_execute(code->in[i], scope, depth + 1)) != 0)
+                    return res;
+    } break;
+    case cccl_Node_END:
+    {
+        return cccl_Executor_END;
+    } break;
+    case cccl_Node_CONTINUE:
+    {
+        return cccl_Executor_CONTINUE;
     } break;
     }
 
diff --git a/main.c b/main.c
index b2d96ca..da9d64e 100644
--- a/main.c
+++ b/main.c
@@ -9,13 +9,15 @@
 
 
 int verbose = 0;
+int interactive = 0;
+int dump = 0;
 
 int main(int argc, char **argv)
 {
     const char *name = *argv;
 
     int ch;
-    while ((ch = getopt(argc, argv, "v")) >= 0)
+    while ((ch = getopt(argc, argv, "vid")) >= 0)
     {
         switch (ch)
         {
@@ -23,9 +25,17 @@ int main(int argc, char **argv)
             {
                 verbose = 1;
             } break;
+            case 'i':
+            {
+                interactive = 1;
+            } break;
+            case 'd':
+            {
+                dump = 1;
+            } break;
             default:
             {
-                fprintf(stderr, "usage: %s [-v] file\n", name);
+                fprintf(stderr, "usage: %s [-vid] file\n", name);
                 exit(1);
             } break;
         }
@@ -35,7 +45,7 @@ int main(int argc, char **argv)
 
     if (!*argv)
     {
-        fprintf(stderr, "usage: %s [-v] file\n", name);
+        fprintf(stderr, "usage: %s [-vid] file\n", name);
         exit(1);
     }