summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/instructions.h2
-rw-r--r--include/variable.h9
-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
12 files changed, 116 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3d53ea..ec49475 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,8 @@ add_executable(
     src/instruction/add.c
     src/instruction/subtract.c
     src/instruction/reverse.c
+    src/instruction/assign.c
+    src/instruction/invalid.c
     src/main.c
     src/platform/getch.c
     src/readchar.c
diff --git a/include/instructions.h b/include/instructions.h
index adada87..04509e9 100644
--- a/include/instructions.h
+++ b/include/instructions.h
@@ -14,6 +14,8 @@ INST(decrement);
 INST(add);
 INST(subtract);
 INST(reverse);
+INST(assign);
+INST(invalid);
 
 #undef INST
 #define INST(NAME) ccl_instruction_##NAME
diff --git a/include/variable.h b/include/variable.h
index 4480855..f392a33 100644
--- a/include/variable.h
+++ b/include/variable.h
@@ -5,7 +5,7 @@
 
 
 /**
- * Tries to find variable in list, NULL if not found.
+ * Try to find variable in list, NULL if not found.
  * @see ccl_variable_getany
  * @param vars Variable list
  * @param name Variable name
@@ -13,7 +13,7 @@
 struct CCLVariable *ccl_variable_get(struct CCLVariable *vars, char name);
 
 /**
- * Tries to find variable in current frame, then in root, NULL if not found.
+ * Try to find variable in current frame, then in root, NULL if not found.
  * @see ccl_variable_get
  * @param ccl CCL instance
  * @param frame Current frame
@@ -21,4 +21,9 @@ struct CCLVariable *ccl_variable_get(struct CCLVariable *vars, char name);
  */
 struct CCLVariable *ccl_variable_getany(struct CCL *ccl, struct CCLFrame *frame, char name);
 
+/**
+ * Create new variable in list
+ */
+struct CCLVariable *ccl_variable_set(struct CCLVariable *vars, char name, CCLNum value);
+
 #endif /* __CCL_VARIABLE_H__ */
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;
+}