about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/instruction.c4
-rw-r--r--src/instruction/add.c1
-rw-r--r--src/instruction/assign.c32
-rw-r--r--src/instruction/delete.c32
-rw-r--r--src/instruction/invalid.c8
-rw-r--r--src/main.c2
-rw-r--r--src/readchar.c2
-rw-r--r--src/readfile.c6
-rw-r--r--src/variable.c26
9 files changed, 105 insertions, 8 deletions
diff --git a/src/instruction.c b/src/instruction.c
index 72cca6c..4189dd1 100644
--- a/src/instruction.c
+++ b/src/instruction.c
@@ -2,6 +2,7 @@
 #include "instructions.h"
 
 #include <stdbool.h>
+#include <stdio.h>
 
 #include "readchar.h"
 #include "3cl.h"
@@ -30,7 +31,10 @@ struct CCLFrame *ccl_instruction(struct CCL *ccl, struct CCLFrame *frame)
     case '*' : ISSW(add);
     case '~' : ISSW(subtract);
     case '%' : ISSW(reverse);
+    case '=' : ISSW(assign);
+    default  : ISSW(invalid);
     }
 #undef INSW
     return instruction(ccl, frame);
+    puts("aboba");
 }
diff --git a/src/instruction/add.c b/src/instruction/add.c
index 81bef71..23d4f8c 100644
--- a/src/instruction/add.c
+++ b/src/instruction/add.c
@@ -1,6 +1,5 @@
 #include "3cl.h"
 
-#include "readchar.h"
 #include "stack.h"
 #include "utils.h"
 
diff --git a/src/instruction/assign.c b/src/instruction/assign.c
new file mode 100644
index 0000000..81e70f9
--- /dev/null
+++ b/src/instruction/assign.c
@@ -0,0 +1,32 @@
+#include "3cl.h"
+
+#include <stdio.h>
+
+#include "readchar.h"
+#include "stack.h"
+#include "utils.h"
+#include "variable.h"
+
+
+struct CCLFrame *ccl_instruction_assign(struct CCL *ccl, struct CCLFrame *frame)
+{
+    if (ccl->stack.cur < 1)
+        die(1, "stack size is %d (%d required)", ccl->stack.cur, 1);
+
+    CCLNum value = ccl_stack_pop(&ccl->stack);
+
+    char name = ccl_readchar(ccl, frame, CCL_RC_CCL_VARUS);
+    if (name == '\0')
+        die(1, "Unexpected EOF");
+
+    if (name == '_')
+        return frame;
+
+    struct CCLVariable *var = ccl_variable_getany(ccl, frame, name);
+    if (var == NULL)
+        ccl_variable_set(&ccl->rootframe.vars, name, value);
+    else
+        var->value = value;
+
+    return frame;
+}
diff --git a/src/instruction/delete.c b/src/instruction/delete.c
new file mode 100644
index 0000000..81e70f9
--- /dev/null
+++ b/src/instruction/delete.c
@@ -0,0 +1,32 @@
+#include "3cl.h"
+
+#include <stdio.h>
+
+#include "readchar.h"
+#include "stack.h"
+#include "utils.h"
+#include "variable.h"
+
+
+struct CCLFrame *ccl_instruction_assign(struct CCL *ccl, struct CCLFrame *frame)
+{
+    if (ccl->stack.cur < 1)
+        die(1, "stack size is %d (%d required)", ccl->stack.cur, 1);
+
+    CCLNum value = ccl_stack_pop(&ccl->stack);
+
+    char name = ccl_readchar(ccl, frame, CCL_RC_CCL_VARUS);
+    if (name == '\0')
+        die(1, "Unexpected EOF");
+
+    if (name == '_')
+        return frame;
+
+    struct CCLVariable *var = ccl_variable_getany(ccl, frame, name);
+    if (var == NULL)
+        ccl_variable_set(&ccl->rootframe.vars, name, value);
+    else
+        var->value = value;
+
+    return frame;
+}
diff --git a/src/instruction/invalid.c b/src/instruction/invalid.c
new file mode 100644
index 0000000..7110bb9
--- /dev/null
+++ b/src/instruction/invalid.c
@@ -0,0 +1,8 @@
+#include "3cl.h"
+
+#include "utils.h"
+
+struct CCLFrame *ccl_instruction_invalid(struct CCL *ccl, struct CCLFrame *frame)
+{
+    die(1, "Invalid instruction at %d", frame->ep - 1);
+}
diff --git a/src/main.c b/src/main.c
index 2df5779..3ab2608 100644
--- a/src/main.c
+++ b/src/main.c
@@ -59,6 +59,8 @@ int main(int argc, char **argv)
     char *code = readfile(argv[optind]);
     struct CCL ccl;
     ccl_init(&ccl, code, getch, (void(*)(int))putchar);
+    ccl_exec(&ccl);
     free(code);
     ccl_free(&ccl);
+    return 0;
 }
diff --git a/src/readchar.c b/src/readchar.c
index 51e1784..428b8fd 100644
--- a/src/readchar.c
+++ b/src/readchar.c
@@ -17,7 +17,7 @@ char ccl_readchar(struct CCL *ccl, struct CCLFrame *frame, enum CCLRCFlags flags
     bool iscomment;
 
     char chr;
-    for (;(chr = ccl->code[frame->ep]) != '\0'; ++frame->ep)
+    while ((chr = ccl->code[frame->ep++]) != '\0')
     {
         if (iscomment && chr == '\n')
             iscomment = false;
diff --git a/src/readfile.c b/src/readfile.c
index 8a0ff2e..fb756de 100644
--- a/src/readfile.c
+++ b/src/readfile.c
@@ -21,18 +21,12 @@ char *readfile(const char *name)
             if ((chr = fgetc(file)) == EOF)
             {
                 if (errno)
-                {
-                    fclose(file);
                     die(1, strerror(errno));
-                }
                 else
-                {
                     break;
-                }
             }
             code[i] = chr;
         }
-        code[size - 1] = '\0';
     fclose(file);
 
     return code;
diff --git a/src/variable.c b/src/variable.c
index 38ea2e3..b764c28 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -30,3 +30,29 @@ struct CCLVariable *ccl_variable_getany(struct CCL *ccl, struct CCLFrame *frame,
 
     return NULL;
 }
+
+struct CCLVariable *ccl_variable_set(struct CCLVariable *vars, char name, CCLNum value)
+{
+    struct CCLVariable *toset;
+    struct CCLVariable var = (struct CCLVariable)
+    {
+        .next = NULL,
+        .name = name,
+        .value = value,
+    };
+
+    if (vars->name == '_')
+    {
+        toset = vars;
+        var.prev = NULL;
+    } else
+    {
+        for (toset = vars; toset->next != NULL; toset = toset->next);
+        toset->next = (struct CCLVariable *)malloc(sizeof(*toset->next));
+        var.prev = toset;
+        toset = toset->next;
+    }
+
+    *toset = var;
+    return toset;
+}