From 9e4058194742794f7742f19cb1a0bb3451ce22ea Mon Sep 17 00:00:00 2001 From: Nakidai Date: Fri, 23 Aug 2024 16:48:01 +0300 Subject: add operation.h --- include/operation.h | 12 +++++ src/cccl.c | 2 + src/operation.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 include/operation.h create mode 100644 src/operation.c diff --git a/include/operation.h b/include/operation.h new file mode 100644 index 0000000..ce487da --- /dev/null +++ b/include/operation.h @@ -0,0 +1,12 @@ +#ifndef __OPERATION_H__ +#define __OPERATION_H__ + +#include "cccl.h" + + +typedef void (*cccl_operation)(void); + +void cccl_operation_init(cccl *pc); +cccl_operation cccl_select_operation(void); + +#endif /* __OPERATION_H__ */ diff --git a/src/cccl.c b/src/cccl.c index 680ead4..e2bb788 100644 --- a/src/cccl.c +++ b/src/cccl.c @@ -8,6 +8,7 @@ #include #include +#include "operation.h" #include "platform/getch.h" #include "utils.h" @@ -37,6 +38,7 @@ void cccl_init(s8 *filename) if (errno) die(1, strerror(errno)); pc.filename = filename; + cccl_operation_init(&pc); } void cccl_free() diff --git a/src/operation.c b/src/operation.c new file mode 100644 index 0000000..c56e381 --- /dev/null +++ b/src/operation.c @@ -0,0 +1,133 @@ +#include "operation.h" +#include "types.h" + +#include +#include +#include +#include + +#include "cccl.h" +#include "utils.h" + + +static cccl *pc; +static bool is_comment; +static i32 current; + +static const s8 *const name_allowed = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static const s8 *const all_allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}[]()?;@=!&$%<>^+-*~#:/ \n\t"; +static const s8 *const skippable = " \t\n"; +static const s8 *const open_brackets = "[({?"; +static const s8 *const close_brackets = "])};"; + +static void check_symbol(void) +{ + if (!strchr(all_allowed, pc->code[pc->ep])) + die(1, "illegal character (%u at %d)", pc->code[pc->ep], pc->ep); +} + +static s8 read_operand(bool allow_underscore) +{ + i32 start = pc->ep; + for (++pc->ep; pc->ep < pc->size; ++pc->ep) + { + check_symbol(); + if (strchr(skippable, pc->code[pc->ep])) + continue; + if (!strchr(allow_underscore ? name_allowed : name_allowed + 1, pc->code[pc->ep])) + die( + 1, "invalid operand name (%c at %d for %c at %d)", + pc->code[pc->ep], pc->ep, + pc->code[start], start + ); + return pc->code[pc->ep]; + } + die( + 1, "no operand (for %c at %d)", + pc->code[start], start + ); +} + +static void require_stack_size(u32 size) +{ + if (cvector_size(pc->stack) < size) + die(1, "stack size is %d, but %d is required (%c at %d)", cvector_size(pc->stack), size, pc->code[current], current); +} + +static void op_noth(void) {} + +static void op_comment(void) +{ + is_comment = !is_comment; +} + +static void op_pushzero(void) +{ + cvector_push_back(pc->stack, 0); +} + +static void op_increment(void) +{ + require_stack_size(1); + ++*cvector_back(pc->stack); +} + +static void op_decrement(void) +{ + require_stack_size(1); + --*cvector_back(pc->stack); +} + +static void op_add(void) +{ + require_stack_size(2); + *(cvector_back(pc->stack) - 1) += *cvector_back(pc->stack); + cvector_pop_back(pc->stack); +} + +static void op_sub(void) +{ + require_stack_size(2); + *(cvector_back(pc->stack) - 1) -= *cvector_back(pc->stack); + cvector_pop_back(pc->stack); +} + +static void op_reverse(void) +{ + s8 operand = read_operand(true); + i16 *to_reverse = NULL; + i32 size; + + if (operand == '_') + size = cvector_size(pc->stack); +} + +void cccl_operation_init(cccl *pcp) +{ + pc = pcp; + is_comment = false; + current = 0; +} + +cccl_operation cccl_select_operation(void) +{ + if (is_comment && pc->code[pc->ep] == '\n') + return op_comment; + if (is_comment) + return op_noth; + + current = pc->ep; + check_symbol(); + + switch (pc->code[pc->ep]) + { + case ' ': /* FALLTHROUGH */ + case '\t': /* FALLTHROUGH */ + case ';': return op_noth; + case '/': return op_comment; + case '^': return op_pushzero; + case '+': return op_increment; + case '-': return op_decrement; + default: die(1, "You shouldn't be there!"); + } +} -- cgit 1.4.1