diff options
37 files changed, 44 insertions, 1000 deletions
diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index f1bc949..0000000 --- a/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true - -[*.{c,h}] -indent_size = 4 -indent_style = space -trim_trailing_whitespace = true diff --git a/.gitignore b/.gitignore index f8e273e..64f02dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ 3cl -compile_commands.json -.cache -build +*.o diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index ec49475..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(3cl VERSION 0.1 LANGUAGES C) - -if (PROJECT_SOURCE_DIR STREQUAL PORJECT_BINARY_DIR) - message(FATAL_ERROR "In-source builds are not allowed") -endif() - -add_executable( - "${PROJECT_NAME}" - src/3cl.c - src/instruction.c - src/instruction/nop.c - src/instruction/pushzero.c - src/instruction/increment.c - src/instruction/decrement.c - 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 - src/readfile.c - src/stack.c - src/utils.c - src/variable.c -) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") - -set_target_properties("${PROJECT_NAME}" PROPERTIES C_STANDARD 11) -set_target_properties("${PROJECT_NAME}" PROPERTIES C_EXTENSIONS FALSE) - -target_include_directories("${PROJECT_NAME}" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") diff --git a/LICENSE b/LICENSE index 7977ab2..7ae8865 100644 --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,10 @@ -Copyright 2024 Nakidai - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE +FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..23ba51d --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +README: README.7 + mandoc -Tascii README.7 | col -b > README diff --git a/README b/README new file mode 100644 index 0000000..fbec6a5 --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +README(7) Miscellaneous Information Manual README(7) + +NAME + 3cl - c cool char lang interpreter + +DESCRIPTION + 3cl is an interpreter of cool char lang which is a brainfuck-like + langauge, but different and with more features. + +SEE ALSO + Original implementation: https://github.com/holy-8/cool_char_lang + +3cl 3cl diff --git a/README.7 b/README.7 new file mode 100644 index 0000000..08dde10 --- /dev/null +++ b/README.7 @@ -0,0 +1,18 @@ +.Dd +.Dt README 7 +.Os 3cl +. +.Sh NAME +.Nm 3cl +.Nd c cool char lang interpreter +. +.Sh DESCRIPTION +.Nm +is an interpreter +of cool char lang +which is a brainfuck-like langauge, +but different +and with more features. +. +.Sh SEE ALSO +.Lk https://github.com/holy-8/cool_char_lang Original implementation diff --git a/README.md b/README.md deleted file mode 100644 index 6982998..0000000 --- a/README.md +++ /dev/null @@ -1,26 +0,0 @@ -3CL --- -CCCL is an implementation of [cool\_char\_lang](https://github.com/holy-8/cool_char_lang), -which is a brainfuck-inspired language - -Documentation --- -To write code for it, follow [this documentation](https://github.com/holy-8/cool_char_lang/blob/main/reference/documentation.md) - -Also there're [examples](https://github.com/holy-8/cool_char_lang/tree/main/programs) - -How to build --- -If you don't know how to build cmake projects, then you should google a little -about it, but in short you need to install (obviously) cmake, some working c -compiler and run these commands in the root of the project: -``` -cmake -B build -cmake --build build -``` - -And `3cl` (or `3cl.exe` ig if you're on windows) will appear in the `build` -directory - -Also I think you can use some wrapper of the cmake with gui (or iirc cmake has -its own gui app) diff --git a/include/3cl.h b/include/3cl.h deleted file mode 100644 index 4466490..0000000 --- a/include/3cl.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef __3CL_H__ -#define __3CL_H__ - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - - -#ifndef CCL_STACKSIZE -#define CCL_STACKSIZE 8192 -#endif - -typedef int16_t CCLNum; /**< Abstract type for numbers in ccl */ -typedef size_t CCLAddr; /**< Abstract type for address in ccl */ - -/** - * Type of CCLFrame - */ -enum CCLFrameType -{ - CCL_ROOT, /**< Root frame, stores global variables */ - CCL_PROC, /**< Function frame, stores local variables */ - CCL_INFLOOP, /**< Infinity loop, stores start and repeat */ - CCL_REPLOOP, /**< Repeat loop, stores start and repeat */ -}; - -/** - * Pair which contains variable's name and value - */ -struct CCLVariable -{ - struct CCLVariable *prev, *next; - char name; - CCLNum value; -}; - -/** - * Pair which contains procedure's name and address - */ -struct CCLProcedure -{ - struct CCLProcedure *prev, *next; - char name; - CCLAddr address; -}; - -/** - * Pair with length of stack and stack itself - */ -struct CCLStack -{ - size_t length; - size_t cur; - CCLNum *stack; -}; - -/** - * Linked list that stores current state and allows to do recursion with local variables. - */ -struct CCLFrame -{ - struct CCLFrame *prev, *next; /**< Frames are connected as linked list */ - enum CCLFrameType type; /**< Type of the frame */ - CCLAddr ep; /**< Execution point */ - union - { - /* Frame stores either variables (for procedures)... */ - struct - { - struct CCLVariable vars; /**< For root frame variables are global */ - }; - /* ...or start address and repeats left (for loops) */ - struct - { - CCLAddr start; /**< Used by CCL_*LOOP */ - int repeats; /**< Used by CCL_REPLOOP */ - }; - }; -}; - -/** - * Main structure for 3cl. It contains root frame, stack and code it's executing. - */ -struct CCL -{ - struct CCLStack stack; - struct CCLFrame rootframe; - const char *code; - bool stopped; - int (*in)(); - void (*out)(int); -}; - -/** - * Inits CCL. - * @see ccl_free - * @see ccl_exec - * @param ccl The structure to init - * @param code The code to execute - * @param in Function to get input - * @param out Function to show output - * @return 0 on success, any other number otherwise - */ -int ccl_init(struct CCL *ccl, const char *code, int (*in)(), void (*out)(int)); - -/** - * Frees all things that ware allocated in ccl_init. - * @see ccl_init - * @param ccl The structure to free - */ -void ccl_free(struct CCL *ccl); - -/** - * Executes inited CCL instance - * @see ccl_init - * @param ccl The strcture to execute - */ -void ccl_exec(struct CCL *ccl); - -#endif /* __3CL_H__ */ diff --git a/include/instruction.h b/include/instruction.h deleted file mode 100644 index 63f28b2..0000000 --- a/include/instruction.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __CCL_INSTRUCTION_H__ -#define __CCL_INSTRUCTION_H__ - -#include "3cl.h" - -/**< Type for every instruction in 3cl */ -typedef struct CCLFrame *(*CCLInstruction)(struct CCL *ccl, struct CCLFrame *frame); - -/** - * Execute next instruction - * @param ccl CCL instance - * @param frame Current frame - * @return Updated frame - */ -struct CCLFrame *ccl_instruction(struct CCL *ccl, struct CCLFrame *frame); - -#endif /* __CCL_INSTRUCTION_H__ */ diff --git a/include/instructions.h b/include/instructions.h deleted file mode 100644 index 04509e9..0000000 --- a/include/instructions.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __CCL_INSTRUCTIONS_H__ -#define __CCL_INSTRUCTIONS_H__ - -#include "3cl.h" - - -#define INST(NAME) \ - struct CCLFrame *ccl_instruction_##NAME(struct CCL *ccl, struct CCLFrame *frame) - -INST(nop); -INST(pushzero); -INST(increment); -INST(decrement); -INST(add); -INST(subtract); -INST(reverse); -INST(assign); -INST(invalid); - -#undef INST -#define INST(NAME) ccl_instruction_##NAME - -#endif /* __CCL_INSTRUCTIONS_H__ */ diff --git a/include/main.h b/include/main.h deleted file mode 100644 index 64abb24..0000000 --- a/include/main.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __MAIN_H__ -#define __MAIN_H__ - -extern const char *program_name; /**< argv[0] */ - -#endif /* __MAIN_H__ */ diff --git a/include/platform/getch.h b/include/platform/getch.h deleted file mode 100644 index 490b536..0000000 --- a/include/platform/getch.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __GETCH_H__ -#define __GETCH_H__ - -#ifdef _WIN32 -#include <conio.h> -#define getch _getche -#else -int getch(void); -#endif /* _WIN32 */ - -void getch_init(void); - -#endif /* __GETCH_H__ */ diff --git a/include/readchar.h b/include/readchar.h deleted file mode 100644 index e881dcb..0000000 --- a/include/readchar.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __CCL_READCHAR_H__ -#define __CCL_READCHAR_H__ - -#include "3cl.h" - - -/** - * Flags to tell ccl_readchar how to read next character - * - * Bits - * 4 Die if char is not whitelisted - * 3 Brackets - * 2 Instruction symbols - * 1 English alphabet - * 0 Underscore - * - * @see ccl_readchar - */ -enum CCLRCFlags -{ - CCL_RC_DIE = 0b10000, /**< Die if char is not whitelisted */ - CCL_RC_BRACK = 0b01000, /**< Brackes */ - CCL_RC_IS = 0b00100, /**< Instruction symbols */ - CCL_RC_ALP = 0b00010, /**< English alphabet */ - CCL_RC_US = 0b00001, /**< Underscore */ - CCL_RC_VAR = 0b11010, /**< (Used by 3CL) Variable names */ - CCL_RC_CCL_VARUS = 0b11011, /**< (Used by 3CL) Variable names including underscore */ - CCL_RC_CCL_BRACK = 0b01000, /**< (Used by 3CL) Brackets */ - CCL_RC_CCL_INSTR = 0b11111, /**< (Used by 3CL) Instruction */ -}; - -/** - * Function to read next character - * Skips whitespace and comments, returns '\0' if reaches EOF - * ccl_readchar will die on invalid symbol (e.g. cyrillic one) even if CCL_RC_DIE is set - * @see CCLRCFlags - * @param ccl CCL instance - * @param frame Current frame - * @param flags CCLRCFlags - * @return Next character - */ -char ccl_readchar(struct CCL *ccl, struct CCLFrame *frame, enum CCLRCFlags flags); - -#endif /* __CCL_READCHAR_H__ */ diff --git a/include/readfile.h b/include/readfile.h deleted file mode 100644 index dcb47eb..0000000 --- a/include/readfile.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __READFILE_H__ -#define __READFILE_H__ - -/** - * Read file by filename, die on error - * @param name Path to file - * @return Contents of file with additional '\0' at the end - */ -char *readfile(const char *name); - -#endif /* __READFILE_H__ */ diff --git a/include/stack.h b/include/stack.h deleted file mode 100644 index ac17ed3..0000000 --- a/include/stack.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __CCL_STACK_H__ -#define __CCL_STACK_H__ - -#include "3cl.h" - - -/** - * Push num to the stack - * @param stack Stack where to push - * @param num Number to push - */ -void ccl_stack_push(struct CCLStack *stack, CCLNum num); - -/** - * Pop number from the stack - * @param stack Stack from where to pop - * @return Popped number - */ -CCLNum ccl_stack_pop(struct CCLStack *stack); - -#endif /* __CCL_STACK_H__ */ diff --git a/include/utils.h b/include/utils.h deleted file mode 100644 index f415abc..0000000 --- a/include/utils.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __UTILS_H__ -#define __UTILS_H__ - -#include <stdnoreturn.h> - - -/** - * Show message: - * program_name: <formattedstring>\n - * and exit with code - * @param code Code to exit - * @param fmt Format string - */ -noreturn void die(int code, char *fmt, ...); - -#endif /* __UTILS_H__ */ diff --git a/include/variable.h b/include/variable.h deleted file mode 100644 index f392a33..0000000 --- a/include/variable.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __CCL_VARIABLE_H__ -#define __CCL_VARIABLE_H__ - -#include "3cl.h" - - -/** - * Try to find variable in list, NULL if not found. - * @see ccl_variable_getany - * @param vars Variable list - * @param name Variable name - */ -struct CCLVariable *ccl_variable_get(struct CCLVariable *vars, char name); - -/** - * 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 - * @param name Variable 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/3cl.c b/src/3cl.c deleted file mode 100644 index bcadf4d..0000000 --- a/src/3cl.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "3cl.h" - -#include <errno.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> - -#include "instruction.h" - - -int ccl_init(struct CCL *ccl, const char *code, int (*in)(), void (*out)(int)) -{ - *ccl = (struct CCL) - { - .code = code, - .stopped = false, - .in = in, - .out = out, - .rootframe = (struct CCLFrame) - { - .prev = NULL, .next = NULL, - .type = CCL_ROOT, - .ep = 0, - .vars = (struct CCLVariable) - { - .prev = NULL, - .next = NULL, - .name = '_', - .value = 0 - }, - }, - .stack = (struct CCLStack) - { - .length = CCL_STACKSIZE, - .stack = (CCLNum *)malloc(CCL_STACKSIZE) - }, - }; - - return errno; -} - -void ccl_free(struct CCL *ccl) -{ - free(ccl->stack.stack); - if (ccl->rootframe.next != NULL) - { - for (struct CCLFrame *frame = ccl->rootframe.next, *new;;) - { - if (frame->vars.next != NULL) - { - for (struct CCLVariable *var = frame->vars.next, *new;;) - { - if (var->next == NULL) - break; - new = var->next; - free(var); - var = new; - } - } - - if (frame->next == NULL) - break; - new = frame->next; - free(frame); - frame = new; - } - } -} - -void ccl_exec(struct CCL *ccl) -{ - struct CCLFrame *curframe = &ccl->rootframe; - - for (;;) - { - curframe = ccl_instruction(ccl, curframe); - if (ccl->stopped) - break; - } -} diff --git a/src/instruction.c b/src/instruction.c deleted file mode 100644 index 4189dd1..0000000 --- a/src/instruction.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "instruction.h" -#include "instructions.h" - -#include <stdbool.h> -#include <stdio.h> - -#include "readchar.h" -#include "3cl.h" - - -struct CCLFrame *ccl_instruction(struct CCL *ccl, struct CCLFrame *frame) -{ - CCLInstruction instruction; - char chr = ccl_readchar(ccl, frame, CCL_RC_CCL_INSTR); - - if (chr == '\0') - { - ccl->stopped = true; - return INST(nop)(ccl, frame); - } - -#define ISSW(NAME) instruction = INST(NAME); break - switch (chr) - { - case '\n': /* FALLTHROUGH */ - case ' ' : /* FALLTHROUGH */ - case '\t': ISSW(nop); - case '^' : ISSW(pushzero); - case '+' : ISSW(increment); - case '-' : ISSW(decrement); - 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 deleted file mode 100644 index 23d4f8c..0000000 --- a/src/instruction/add.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "3cl.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/assign.c b/src/instruction/assign.c deleted file mode 100644 index 81e70f9..0000000 --- a/src/instruction/assign.c +++ /dev/null @@ -1,32 +0,0 @@ -#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/decrement.c b/src/instruction/decrement.c deleted file mode 100644 index ce3af87..0000000 --- a/src/instruction/decrement.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "3cl.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/delete.c b/src/instruction/delete.c deleted file mode 100644 index 81e70f9..0000000 --- a/src/instruction/delete.c +++ /dev/null @@ -1,32 +0,0 @@ -#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/increment.c b/src/instruction/increment.c deleted file mode 100644 index d2d51a5..0000000 --- a/src/instruction/increment.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "3cl.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/invalid.c b/src/instruction/invalid.c deleted file mode 100644 index 7110bb9..0000000 --- a/src/instruction/invalid.c +++ /dev/null @@ -1,8 +0,0 @@ -#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/instruction/nop.c b/src/instruction/nop.c deleted file mode 100644 index 778b8ed..0000000 --- a/src/instruction/nop.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "3cl.h" - -struct CCLFrame *ccl_instruction_nop(struct CCL *ccl, struct CCLFrame *frame) -{ - return frame; -} diff --git a/src/instruction/pushzero.c b/src/instruction/pushzero.c deleted file mode 100644 index cd0a023..0000000 --- a/src/instruction/pushzero.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "3cl.h" - -#include "stack.h" - -struct CCLFrame *ccl_instruction_pushzero(struct CCL *ccl, struct CCLFrame *frame) -{ - ccl_stack_push(&ccl->stack, 0); - return frame; -} diff --git a/src/instruction/reverse.c b/src/instruction/reverse.c deleted file mode 100644 index bd863ae..0000000 --- a/src/instruction/reverse.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "3cl.h" - -#include <errno.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#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 deleted file mode 100644 index f140cfb..0000000 --- a/src/instruction/subtract.c +++ /dev/null @@ -1,12 +0,0 @@ -#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; -} diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 3ab2608..0000000 --- a/src/main.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "main.h" - -#include <getopt.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdnoreturn.h> - -#include "platform/getch.h" -#include "3cl.h" -#include "readfile.h" - - -const char *program_name; - -static const char *const usage_message = - "usage: %s [-h] file\n"; -static const char *const usage_description = - "ccl language interpreter\n" - "Arguments:\n" - " file file to execute\n" - "Options\n" - " -h, --help show this help message and quit\n"; - -static struct option long_options[] = -{ - {"help", no_argument, NULL, 'b'}, - {0} -}; - -noreturn void usage(bool full) -{ - printf(usage_message, program_name); - if (full) printf(usage_description); - exit(full ? 0 : 1); -} - -int main(int argc, char **argv) -{ - program_name = argv[0]; - getch_init(); - - int ch; - while ((ch = getopt_long(argc, argv, "h", long_options, NULL)) != EOF) - { - switch (ch) - { - case 'h': - usage(true); - break; - default: - usage(false); - break; - } - } - if (argv[optind] == NULL) - usage(false); - - 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/platform/getch.c b/src/platform/getch.c deleted file mode 100644 index 48c846e..0000000 --- a/src/platform/getch.c +++ /dev/null @@ -1,53 +0,0 @@ -#ifdef _WIN32 -void getch_init(void) {} -#else -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdnoreturn.h> -#include <termios.h> -#include <unistd.h> - -static struct termios default_state = {0}; - -int getch(void) -{ - int ch = 0; - struct termios old = {0}; - fflush(stdout); - - tcgetattr(0, &old); - old.c_lflag &= ~ICANON; - - tcsetattr(0, TCSANOW, &old); - ch = getchar(); - tcsetattr(0, TCSADRAIN, &default_state); - - return ch; -} - -static void get_reset_terminal_state(void) -{ - tcsetattr(0, TCSANOW, &default_state); -} - -static noreturn void get_reset_terminal_state_handler(int sig) -{ - get_reset_terminal_state(); - _Exit(sig); -} - -void getch_init(void) -{ - tcgetattr(0, &default_state); - - atexit(get_reset_terminal_state); - - signal(SIGINT, get_reset_terminal_state_handler); - signal(SIGABRT, get_reset_terminal_state_handler); - signal(SIGFPE, get_reset_terminal_state_handler); - signal(SIGILL, get_reset_terminal_state_handler); - signal(SIGSEGV, get_reset_terminal_state_handler); - signal(SIGTERM, get_reset_terminal_state_handler); -} -#endif /* _WIN32 */ diff --git a/src/readchar.c b/src/readchar.c deleted file mode 100644 index 428b8fd..0000000 --- a/src/readchar.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "3cl.h" -#include "readchar.h" - -#include <stdbool.h> -#include <string.h> - -#include "utils.h" - - -static const char *const space = " \n\t"; -static const char *const brackets = "{[(?;)]}"; -static const char *const instr = "^+-*~%=!$&<>@#:"; -static const char *const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -char ccl_readchar(struct CCL *ccl, struct CCLFrame *frame, enum CCLRCFlags flags) -{ - bool iscomment; - - char chr; - while ((chr = ccl->code[frame->ep++]) != '\0') - { - if (iscomment && chr == '\n') - iscomment = false; - if (iscomment) - continue; - if (chr == '/') - iscomment = true; - - if (strchr(space, chr)) - continue; - - if (strchr(brackets, chr)) - if (!(flags & CCL_RC_BRACK) && flags & CCL_RC_DIE) - goto invalid; - else - goto ok; - else if (strchr(instr, chr)) - if (!(flags & CCL_RC_IS) && flags & CCL_RC_DIE) - goto invalid; - else - goto ok; - else if (strchr(alphabet, chr)) - if (!(flags & CCL_RC_ALP) && flags & CCL_RC_DIE) - goto invalid; - else - goto ok; - else if (chr == '_') - if (!(flags & CCL_RC_US) && flags & CCL_RC_DIE) - goto invalid; - else - goto ok; - else - goto invalid; - } -ok: - return chr; -invalid: - die(1, "Invalid symbol at %d", frame->ep); -} diff --git a/src/readfile.c b/src/readfile.c deleted file mode 100644 index fb756de..0000000 --- a/src/readfile.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "utils.h" - - -char *readfile(const char *name) -{ - char *code, chr; - FILE *file = fopen(name, "r"); - if (errno) die(1, strerror(errno)); - fseek(file, 0, SEEK_END); - size_t size = ftell(file); - fseek(file, 0, SEEK_SET); - code = calloc(size + 1, sizeof(*code)); - - for (int i = 0; i < size; ++i) - { - if ((chr = fgetc(file)) == EOF) - { - if (errno) - die(1, strerror(errno)); - else - break; - } - code[i] = chr; - } - fclose(file); - - return code; -} diff --git a/src/stack.c b/src/stack.c deleted file mode 100644 index 3a1f697..0000000 --- a/src/stack.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "3cl.h" - -#include <stdlib.h> - - -static inline void resize(struct CCLStack *stack) -{ - stack->length *= 2; - stack->stack = realloc(stack->stack, stack->length * sizeof(*stack->stack)); -} - -void ccl_stack_push(struct CCLStack *stack, CCLNum num) -{ - if (stack->cur + 1 == stack->length) - resize(stack); - stack->stack[++stack->cur] = num; -} - -CCLNum ccl_stack_pop(struct CCLStack *stack, CCLNum num) -{ - return stack->stack[stack->cur--]; -} diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index ba5638f..0000000 --- a/src/utils.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdnoreturn.h> - -#include "main.h" - - -noreturn void die(int code, char *fmt, ...) -{ - va_list args; - - fprintf(stderr, "%s: ", program_name); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - putc('\n', stderr); - - exit(code); -} diff --git a/src/variable.c b/src/variable.c deleted file mode 100644 index b764c28..0000000 --- a/src/variable.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "3cl.h" -#include "variable.h" - -#include <stdbool.h> -#include <stdlib.h> - - -struct CCLVariable *ccl_variable_get(struct CCLVariable *vars, char name) -{ - for (struct CCLVariable *var = vars;;var = var->next) - if (var->name == name) - return var; - else if (var->name == '_' || var->next == NULL) - return NULL; -} - -struct CCLVariable *ccl_variable_getany(struct CCL *ccl, struct CCLFrame *frame, char name) -{ - bool root = false; - struct CCLFrame *curframe; - struct CCLVariable *found; - - for (curframe = frame; curframe->type != CCL_PROC && curframe->type != CCL_ROOT; curframe = curframe->prev); - if (curframe->type == CCL_ROOT) - root = true; - - found = ccl_variable_get(&curframe->vars, name); - if (!found && !root) - return ccl_variable_get(&ccl->rootframe.vars, name); - - 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; -} |