diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | include/instructions.h | 2 | ||||
| -rw-r--r-- | include/variable.h | 9 | ||||
| -rw-r--r-- | src/instruction.c | 4 | ||||
| -rw-r--r-- | src/instruction/add.c | 1 | ||||
| -rw-r--r-- | src/instruction/assign.c | 32 | ||||
| -rw-r--r-- | src/instruction/delete.c | 32 | ||||
| -rw-r--r-- | src/instruction/invalid.c | 8 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/readchar.c | 2 | ||||
| -rw-r--r-- | src/readfile.c | 6 | ||||
| -rw-r--r-- | src/variable.c | 26 |
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; +} |