From c74aea420c662039072f606b2d5ef1c73426e481 Mon Sep 17 00:00:00 2001 From: Nakidai Date: Sat, 24 Aug 2024 14:29:55 +0300 Subject: Add more code Add some funcitons to work with variables, add more instructions and add ability to stop the code from `ccl_instruction` --- src/instruction/add.c | 14 +++++++++++++ src/instruction/decrement.c | 5 ++++- src/instruction/increment.c | 5 ++++- src/instruction/nop.c | 1 - src/instruction/pushzero.c | 1 - src/instruction/reverse.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/instruction/subtract.c | 12 +++++++++++ 7 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/instruction/add.c create mode 100644 src/instruction/reverse.c create mode 100644 src/instruction/subtract.c (limited to 'src/instruction') diff --git a/src/instruction/add.c b/src/instruction/add.c new file mode 100644 index 0000000..81bef71 --- /dev/null +++ b/src/instruction/add.c @@ -0,0 +1,14 @@ +#include "3cl.h" + +#include "readchar.h" +#include "stack.h" +#include "utils.h" + +struct CCLFrame *ccl_instruction_add(struct CCL *ccl, struct CCLFrame *frame) +{ + if (ccl->stack.cur < 2) + die(1, "stack size is %d (%d required)", ccl->stack.cur, 2); + ccl_stack_push(&ccl->stack, ccl_stack_pop(&ccl->stack) + ccl_stack_pop(&ccl->stack)); + + return frame; +} diff --git a/src/instruction/decrement.c b/src/instruction/decrement.c index f7f54dd..ce3af87 100644 --- a/src/instruction/decrement.c +++ b/src/instruction/decrement.c @@ -1,8 +1,11 @@ #include "3cl.h" -#include "instruction.h" + +#include "utils.h" struct CCLFrame *ccl_instruction_decrement(struct CCL *ccl, struct CCLFrame *frame) { + if (ccl->stack.cur < 1) + die(1, "stack size is %d (%d required)", ccl->stack.cur, 1); --ccl->stack.stack[ccl->stack.cur]; return frame; } diff --git a/src/instruction/increment.c b/src/instruction/increment.c index 51697f1..d2d51a5 100644 --- a/src/instruction/increment.c +++ b/src/instruction/increment.c @@ -1,8 +1,11 @@ #include "3cl.h" -#include "instruction.h" + +#include "utils.h" struct CCLFrame *ccl_instruction_increment(struct CCL *ccl, struct CCLFrame *frame) { + if (ccl->stack.cur < 1) + die(1, "stack size is %d (%d required)", ccl->stack.cur, 1); ++ccl->stack.stack[ccl->stack.cur]; return frame; } diff --git a/src/instruction/nop.c b/src/instruction/nop.c index 8e05396..778b8ed 100644 --- a/src/instruction/nop.c +++ b/src/instruction/nop.c @@ -1,5 +1,4 @@ #include "3cl.h" -#include "instruction.h" struct CCLFrame *ccl_instruction_nop(struct CCL *ccl, struct CCLFrame *frame) { diff --git a/src/instruction/pushzero.c b/src/instruction/pushzero.c index ef380cd..cd0a023 100644 --- a/src/instruction/pushzero.c +++ b/src/instruction/pushzero.c @@ -1,5 +1,4 @@ #include "3cl.h" -#include "instruction.h" #include "stack.h" diff --git a/src/instruction/reverse.c b/src/instruction/reverse.c new file mode 100644 index 0000000..bd863ae --- /dev/null +++ b/src/instruction/reverse.c @@ -0,0 +1,51 @@ +#include "3cl.h" + +#include +#include +#include +#include +#include + +#include "readchar.h" +#include "utils.h" +#include "variable.h" + + +struct CCLFrame *ccl_instruction_reverse(struct CCL *ccl, struct CCLFrame *frame) +{ + char varname; + size_t toreverse; + + varname = ccl_readchar(ccl, frame, CCL_RC_CCL_VARUS); + if (varname == '\0') + { + die(1, "Unexpected EOF"); + } else if (varname == '_') + { + toreverse = ccl->stack.cur; + } else + { + struct CCLVariable *var = ccl_variable_getany(ccl, frame, varname); + if (var == NULL) + die(1, "Unknown variable '%c' at %d", varname, frame->ep); + toreverse = var->value; + } + + if (ccl->stack.cur < toreverse) + die(1, "stack size is %d (%d required)", ccl->stack.cur, toreverse); + + CCLNum *temp = malloc(sizeof(*temp) * toreverse); + if (temp == NULL) + die(1, "malloc(): %s", strerror(errno)); + + size_t start; + for (start = 0; start < toreverse; ++start) + temp[start] = ccl->stack.stack[ccl->stack.cur - start]; + start = ccl->stack.cur - start; + for (int i = 0; i < toreverse; ++i) + ccl->stack.stack[start + i] = temp[i]; + + free(temp); + + return frame; +} diff --git a/src/instruction/subtract.c b/src/instruction/subtract.c new file mode 100644 index 0000000..f140cfb --- /dev/null +++ b/src/instruction/subtract.c @@ -0,0 +1,12 @@ +#include "3cl.h" + +#include "stack.h" +#include "utils.h" + +struct CCLFrame *ccl_instruction_subtract(struct CCL *ccl, struct CCLFrame *frame) +{ + if (ccl->stack.cur < 2) + die(1, "stack size is %d (%d required)", ccl->stack.cur, 2); + ccl_stack_push(&ccl->stack, -ccl_stack_pop(&ccl->stack) + ccl_stack_pop(&ccl->stack)); + return frame; +} -- cgit 1.4.1