├── AUTHORS ├── BENCHMARK ├── Makefile ├── README.md ├── TODO ├── bignum ├── examples ├── comments.gecho ├── comparisons ├── comparisons.gecho ├── comparisons.gecho.c ├── comparisons.gecho~ ├── constants.gecho ├── factorial.gecho ├── helloworld.gecho ├── multiple.gecho ├── powers.gecho ├── test.gecho ├── trig.gecho └── words.gecho ├── gecko.png ├── gmptest.c └── src ├── #gechoc.c# ├── bignum ├── functions.h ├── gecho.c ├── header.h ├── stack.h ├── structs.h └── usefunc.h ├── color.c ├── experimental ├── 20q.c ├── a.out ├── cmdops ├── cmdops.c ├── cmdops.c~ ├── difftypes.c ├── func.c ├── func_ptrs.c ├── hashtable.c ├── makel.py ├── makel.py~ ├── type2.c ├── type2.c~ ├── types.c └── types.c~ ├── functions.h ├── gecho.c ├── gechoc.c ├── header.h ├── objects.h ├── oo.h ├── stack.h ├── structdef.h ├── structs.h └── usefunc.h /AUTHORS: -------------------------------------------------------------------------------- 1 | Maxwell Bernstein 2 | -------------------------------------------------------------------------------- /BENCHMARK: -------------------------------------------------------------------------------- 1 | 20! took: 2 | .009s in gecho, interpreted 3 | .005s in gecho, compiled 4 | .826s in Python 5 | .002s in C 6 | 7 | MEANING: 8 | Interpreted: 92x faster than Python 9 | Compiled: 165x faster than Python (interpreted) 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(CC) src/gecho.c -o gecho -lm -Wall 3 | clean: 4 | -rm -f gecho *~ gechoc 5 | install: 6 | mv gecho /usr/bin/$(INAME) 7 | make clean 8 | go: 9 | make clean 10 | make 11 | sudo make install INAME=$(INAME) 12 | gechoc: 13 | $(CC) src/gechoc.c -o gechoc -lm -Wall 14 | rm -rf /usr/include/gecho/ 15 | mkdir /usr/include/gecho/ 16 | cp src/*.h /usr/include/gecho/ 17 | install-gechoc: 18 | mv gechoc /usr/bin/$(CNAME) 19 | make clean 20 | do-all: 21 | sudo make go CC=$(CC) INAME=$(INAME) 22 | sudo make gechoc CC=$(CC) 23 | sudo make install-gechoc CNAME=$(CNAME) 24 | mac-intel: 25 | make CC=$(CC) 26 | sudo make gechoc CC=$(CC) 27 | mv gecho precompiled/mac_intel/ 28 | mv gechoc precompiled/mac_intel/ 29 | make clean 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gecho 2 | 3 | WARNING: `float` is imprecise, and shortly I will be moving everything over to bignum. Large numbers will come out incorrect! (ex. 170 factorial) 4 | 5 | gecho is somewhat similar to FORTH. It will probably become less so as it grows. 6 | 7 | ## Install 8 | 9 | ### IF ON A MAC 10 | 11 | 1. compile with `sudo make do-all CC= INAME= CNAME=` 12 | * CC defaults to `cc` and INAME/CNAME default to `gecho` and `gechoc`, respectively 13 | 14 | OR 15 | 16 | 1. `sudo make CC=` 17 | * Just compiles. 18 | 19 | ## Three Options... 20 | 21 | ### FIRST 22 | 23 | 1. `make CC=` 24 | * You can use whatever C compiler you want, defaults to `cc` 25 | 2. `sudo make install`. 26 | * Moves it to `/usr/bin/`. 27 | 28 | ### SECOND 29 | 30 | 1. `sudo make go CC=` 31 | * Just makes and cleans up and moves it to `/usr/bin/` for you. Compiler defaults to `cc`. 32 | 33 | ### THIRD 34 | 35 | 1. `sudo make do-all CC=` 36 | * Compiles and installs both interpreter and compiler. Compiler defaults to `cc`. 37 | 38 | ## Stack Theory 39 | 40 | Think of a stack of books. It starts off empty. 41 | 42 | `[ ]` 43 | 44 | However, when you put (or `push`) a book (number) onto the stack, it gets added to the top. 45 | 46 | `[ 12 ]` 47 | 48 | Keep adding numbers, and it will soon look like this. 49 | 50 | `[ 12, 4, 8, 3 ]` 51 | 52 | Note that `3` is at the top of the stack, and `12` is at the bottom. 53 | 54 | One can also take off (or `pop`) elements from the stack. 55 | 56 | `[ 12, 4, 8 ]` 57 | 58 | `3.00` 59 | 60 | The number gets returned as a result of popping it. 61 | 62 | Operands can pop numbers from the stack and interact with them. For example, 63 | 64 | `dels 1 2 +` 65 | 66 | would clear the stack, push `1`, then push `2`, then pop them both and add them. It will then push the result onto the stack. The stack now looks like this: 67 | 68 | `[ 3 ]` 69 | 70 | That's stack theory. 71 | 72 | ## The Interpreter 73 | 74 | #### If on a Mac, just replace `gecho` with `gecho-mac` and `gechoc` with `gechoc-mac` 75 | 76 | 1. SHELL 77 | * just run `gecho` (or `./gecho`) 78 | 79 | 2. FILE READ 80 | * run `gecho -f ` (or `./gecho -f `) 81 | 82 | 3. FILE READ THEN SHELL 83 | * run `gecho -sf ` (or `./gecho -sf `) 84 | 85 | 4. COMPILE GECHO 86 | * run `gechoc ` 87 | * run ` -o -lm` 88 | * run `` 89 | 90 | #### Whitespace does not matter! 91 | 92 | ## Commands 93 | 94 | 1. `+` 95 | * Pops two elements from the stack, adds them together, and pushes the result. 96 | 2. `++` 97 | * Pops all the elements from the stack and adds them together; pushes result. 98 | 3. `.` 99 | * Prints the top element in the stack. 100 | 4. `*` 101 | * Pops two elements from the stack, multiplies them, and pushes the result. 102 | 5. `dels` 103 | * Pops all elements from the stack. 104 | 6. `show` 105 | * Pretty prints the stack. 106 | 7. `dup` 107 | * Pushes a copy of the top element of the stack. 108 | 8. `swap` 109 | * Pops two elements from the stack, and pushes back in each other's places. 110 | 9. `-` 111 | * Pops two elements from the stack, subtracts the upper from the lower, and pushes the result. 112 | 10. `jump` 113 | * Pops an element from the stack (a) and prints stack[a] 114 | 11. `range` 115 | * Pops two elements from the stack (a, b) and prints range(b, a); starts at b, increments by one until a, pushes the array onto the stack. 116 | 12. `` 117 | * Pushes `` to the stack. 118 | 13. `**` 119 | * Pops all the elements from the stack and multiplies them; pushes result. 120 | 14. `!` 121 | * Pop element from stack; set `variables[]` to popped value. 122 | 15. `&` 123 | * Push `variables[]` to the stack. 124 | 15. `wover` 125 | * a = pop(); b = pop(); push(b); push(a); push(b); 126 | * ( a1 a2 -- a1 a2 a1) 127 | 16. `drop` || `pop` 128 | * Pop top element from stack, show value. 129 | 17. `top` 130 | * Push the index of the top of the stack to the stack. 131 | 18. `outascii` 132 | * Pop top element of stack and print ASCII character that corresponds to decimal. 133 | 19. `print` 134 | * Pop all elements of stack and prints ASCII characters that correspond to decimal. 135 | 20. `/` 136 | * Pop top two elements from stack; divide lower element by upper element. 137 | 21. `@` 138 | * Toggles ``. 139 | 22. `mode` 140 | * Prints a list of all enabled modes. 141 | 23. `modes` 142 | * Prints all modes, complete with 'enabled' flag. 143 | 24. `tot` 144 | * For use with `@tracker`. Prints number of commands so far. Does not count as a command. 145 | 25. `reset` 146 | * Resets the command count. For use with `@tracker`. Does not count as a command. 147 | 26. `tan` 148 | * Pops one element from the stack (degrees!) computes `tan(x)` 149 | 27. `sin` 150 | * Pops one element from the stack and computes `sin(x)` 151 | 28. `cos` 152 | * Pops one element from the stack and computes `cos(x)` 153 | 29. `pow` 154 | * a = pop(); b = pop(); push(b^a); 155 | 30. `mod` 156 | * a = pop(); b = pop(); push(b%a); 157 | 32. `read` 158 | * Reads user input. Only really useful with file reading/compiling. Pops one element from the stack and reads that number of numbers, and pushes them to the stack. 159 | 33. `<` 160 | * b = pop(); a = pop(); push(`a < b`); 161 | 34. `>` 162 | * `a > b` 163 | 35. `>=` 164 | * `a >= b` 165 | 36. `<=` 166 | * `a <= b` 167 | 37. `=` 168 | * `a == b` 169 | 38. `'` 170 | * Push each character of `` onto the stack. 171 | 39. `<>` 172 | * Push ' ' to the stack. 173 | 40. `and` 174 | * Push `a && b` to the stack. 175 | 41. `or` 176 | * Push `a || b` to the stack. 177 | 42. `nil` 178 | * Does absolutely nothing. 179 | 43. `next` 180 | * Moves to the next stack (out of 3). Starts at stack 0. 181 | 44. `back` 182 | * Moves one stack back (out of 3) in a cycle. If it goes past 0, it will cycle to stack 3. 183 | 45. `mv` 184 | * Moves the top element from the current stack to the next stack. To COPY, use `dup mv`. 185 | 186 | ## Modes 187 | 188 | 1. `transparent` 189 | * Shows the stack after every command. 190 | 2. `default` 191 | * Regular interpreter settings. 192 | 3. `tracker` 193 | * After being enabled, counts the commands entered. Can be viewed with `tot`. 194 | 195 | ## Constants 196 | 197 | 1. `#t` == `#true` 198 | * `1` 199 | 2. `#f` == `#false` 200 | * `0` 201 | 3. `#pi` 202 | * the value `pi` 203 | 4. `#e` 204 | * the value `e` 205 | 5. `#phi` 206 | * the value `phi` 207 | 208 | ## Command-line Flags 209 | 210 | 1. `-f` 211 | * Input file to compile/read. Must come after another flag. (e.g. `-fs` won't work but `-sf` will) 212 | 1. `-e` 213 | * Skip the version and "bye" message. If passing something to gecho, end it with "exit" so it doesn't evaluate endlessly. 214 | 2. `-v` 215 | * Just print the version information. 216 | 3. `-s` 217 | * Can enter shell mode after evaluating the file. Also suppresses the version and package name. 218 | 219 | 220 | ## Examples 221 | 222 | 1. `1 2 3 + .` == `5` 223 | 224 | 2. `1 2 3 ++ .` == `6` 225 | 226 | 3. `1 2 3 * .` == `6` 227 | 228 | 4. `1 2 3 4 dels show` == `[ ]` 229 | 230 | 5. `1 2 dup show` == `[ 1, 2, 2 ]` 231 | 232 | 6. `1 2 - .` == `-1` 233 | 234 | 7. `0 10 range 3 jump` == `4` 235 | 236 | 8. `1 5 range ** .` == `120` 237 | * Factorial :) 238 | 239 | 9. `3 4 5 ++ !1` == `None` 240 | * Doesn't return anything; sets `globals[1]` to the sum of `3, 4, 5` 241 | 242 | 10. `0 1 dup wover + dup wover + dup wover + show` == `[ 1, 1, 2, 3, 5 ]` 243 | * Fibonacci :) 244 | 245 | 11. `1 2 3 4 show drop show` == `[1, 2, 3, 4], [1, 2, 3]` 246 | 247 | 12. `1 2 3 top .` == `2` 248 | 249 | 15. `1 2 / .` == `0.5` 250 | 251 | 16. `@transparent` == shows stack after every command 252 | 253 | 17. `45 tan .` == `1.00` 254 | 255 | 18. `#pi 2 * cos .` == `0.99` (truncated, not rounded) 256 | 257 | 19. `3 read` == reads 3 numbers and pops them to the stack 258 | 259 | 20. `15 5 + 10 dup + = #t = .` == `((15+5) == (10+10)) == #t`? 260 | 261 | 21. `'Hello, <> 'world! print` == `Hello, world!` 262 | 263 | 22. `1 2 + show next 3 4 + show back mv + show` => Adds 1+2 on the first stack, shows it, adds 3+4 on the next stack, shows it, moves the top item on the first stack to the second stack, then adds 7 and 3 together to make 10. 264 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: 2 | - Comments 3 | - Lookahead words...needed for function definitions 4 | - { } braces 5 | - recursion 6 | - if statement 7 | - GMP bignum 8 | - words in separate stack/storage 9 | -------------------------------------------------------------------------------- /bignum: -------------------------------------------------------------------------------- 1 | src/bignum/ -------------------------------------------------------------------------------- /examples/comments.gecho: -------------------------------------------------------------------------------- 1 | ( this is a test comment... o.O ) 1 2 + . 2 | -------------------------------------------------------------------------------- /examples/comparisons: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekknolagi/gecho/3d2a051dd53d901c378549f21903e8bbe7377b22/examples/comparisons -------------------------------------------------------------------------------- /examples/comparisons.gecho: -------------------------------------------------------------------------------- 1 | @transparent 2 3 < . 2 | -------------------------------------------------------------------------------- /examples/comparisons.gecho.c: -------------------------------------------------------------------------------- 1 | #include 2 | printf("--@transparent ON--\n"); 3 | StackPush(&dataStack, 2.000000); 4 | printf("2 | ");StackShow(&dataStack); 5 | StackPush(&dataStack, 3.000000); 6 | printf("3 | ");StackShow(&dataStack); 7 | lt(&dataStack); 8 | printf("< | ");StackShow(&dataStack); 9 | showtop(&dataStack); 10 | } -------------------------------------------------------------------------------- /examples/comparisons.gecho~: -------------------------------------------------------------------------------- 1 | 2 3 < . end 2 | -------------------------------------------------------------------------------- /examples/constants.gecho: -------------------------------------------------------------------------------- 1 | @transparent #true #false and . 2 | -------------------------------------------------------------------------------- /examples/factorial.gecho: -------------------------------------------------------------------------------- 1 | 170 1 range ** . 2 | -------------------------------------------------------------------------------- /examples/helloworld.gecho: -------------------------------------------------------------------------------- 1 | 'Hello, <> 'world! print 2 | -------------------------------------------------------------------------------- /examples/multiple.gecho: -------------------------------------------------------------------------------- 1 | @transparent 1 2 + . next 3 4 + . back 2 | mv + -------------------------------------------------------------------------------- /examples/powers.gecho: -------------------------------------------------------------------------------- 1 | 2 3 pow . 2 | -------------------------------------------------------------------------------- /examples/test.gecho: -------------------------------------------------------------------------------- 1 | @transparent 2 | 3 | 4 | 5 | 1 2 6 | 7 | + 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/trig.gecho: -------------------------------------------------------------------------------- 1 | 45 tan . 2 | -------------------------------------------------------------------------------- /examples/words.gecho: -------------------------------------------------------------------------------- 1 | 'hello <> 'world! print 2 | -------------------------------------------------------------------------------- /gecko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekknolagi/gecho/3d2a051dd53d901c378549f21903e8bbe7377b22/gecko.png -------------------------------------------------------------------------------- /gmptest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | mpf_t factorial(int x) { 5 | mpf_t mul_res; 6 | mpf_init(mul_res); 7 | if (x < 1) return (mpf_t) 1; 8 | mpf_mul_ui(mul_res, factorial(x-1), x); 9 | else return mul_res; 10 | } 11 | 12 | int main() { 13 | mpf_t a, b;//, b, inter; 14 | //mpf_init_set_d(a, (double) 5); 15 | //mpf_init_set_d(b, (double) 5); 16 | //mpf_init(inter); 17 | //mpf_add(inter, a, b); 18 | mpf_init(a); 19 | mpf_init(b); 20 | //gmp_printf("%.2Ff+%.2Ff=%.2Ff\n", a, b, inter); 21 | mpf_set_d(a, (double) 5); 22 | mpf_set_mpf(b, factorial(a)); 23 | gmp_printf("%.0Ff! = %.0Ff\n", a, b); 24 | } 25 | -------------------------------------------------------------------------------- /src/#gechoc.c#: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | int var_index; 3 | #define PKGNAME "gecho" 4 | #define VERSION 0.5 5 | #include "functions.h" 6 | int cmds; 7 | int top; 8 | double variables[RES_SIZE]; 9 | 10 | int which = 0; 11 | 12 | void next() { 13 | if (which < NUM_STACKS) which++; 14 | else which = 0; 15 | } 16 | 17 | void back() { 18 | if (which > 0) which--; 19 | else which = NUM_STACKS-1; 20 | } 21 | 22 | //This is the eval function. 23 | void eval(stackT dataStack[], loopstack *loopStack, mode list[MODETOP], char cmd[], FILE *toc, const_list cons[CONSTOP]) { 24 | //Checks if the first digit is a number, and if so, pushes it. 25 | if ((cmd[0] == '-') && (isdigit(cmd[1]) || cmd[1] == '.')) { 26 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", atof(cmd)); 27 | } 28 | else if (isdigit(cmd[0]) || ((cmd[0] == '.') && isdigit(cmd[1]))) { 29 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", atof(cmd)); 30 | } 31 | else if (!strcmp(cmd, "<>")) { 32 | fprintf(toc, "StackPush(&charStack, (int) \' \');\n"); 33 | } 34 | else if ((cmd[0] == '\'') || (cmd[0] == '`')) { 35 | if (strlen(cmd) > 1) { 36 | for (a = 1; a < strlen(cmd); a++) { 37 | fprintf(toc, "StackPush(&charStack, (int) \'%c\');\n", cmd[(int) a]); 38 | } 39 | } 40 | else { 41 | fprintf(toc, "error(\"not a valid char/string!\");\n"); 42 | } 43 | } 44 | else { 45 | //Converts the command to all lowercase. 46 | for(c = 0; c < strlen(cmd); c++) { 47 | cmd[(int) c] = tolower(cmd[(int) c]); 48 | } 49 | 50 | if (!strcmp(cmd, "nil")); 51 | 52 | //If it's a mode change...toggle it. 53 | else if ((cmd[0] == '@') && (strlen(cmd) > 1)) { 54 | a = toggle(list, lookup(list, cmd)); 55 | if (a) { 56 | fprintf(toc, "printf(\"--%s %s--\\n\");\n", cmd, is_enabled(list,cmd)?"ON":"OFF"); 57 | } 58 | } 59 | 60 | else if (cmd[0] == '#') { 61 | if (strlen(cmd) > 1) { 62 | if (c_lookup(cons, cmd) != -1) { 63 | fprintf(toc, "StackPush(dataStack[which], cons[c_lookup(cons, cmd)].value);\n"); 64 | } 65 | } 66 | else { 67 | fprintf(toc, "error(\"not enough frames!\");\n"); 68 | } 69 | } 70 | 71 | else if (!strcmp(cmd, "and")) { 72 | fprintf(toc, "log_and(&dataStack[which]);\n"); 73 | } 74 | 75 | else if (!strcmp(cmd, "or")) { 76 | fprintf(toc, "log_or(&dataStack[which]);\n"); 77 | } 78 | 79 | else if (!strcmp(cmd, "next")) { 80 | fprintf(toc, "next();\n"); 81 | next(); 82 | } 83 | 84 | else if (!strcmp(cmd, "back")) { 85 | fprintf(toc, "back();\n"); 86 | back(); 87 | } 88 | 89 | else if ((cmd[0] == '!') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 90 | var_index = atoi(cmd+1); 91 | if (dataStack->top >= 0) { 92 | variables[var_index] = StackPop(&dataStack[which]); 93 | } 94 | else { 95 | fprintf(toc, "error(\"stack is empty!\")\n;"); 96 | } 97 | } 98 | 99 | else if ((cmd[0] == '&') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 100 | var_index = atoi(cmd+1); 101 | //printf("ind: %d\n", var_index); 102 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", variables[var_index]); 103 | } 104 | 105 | else if (!strcmp(cmd, "pow")) { 106 | fprintf(toc, "powers(&dataStack[which]);\n"); 107 | } 108 | 109 | else if (!strcmp(cmd, "mod")) { 110 | fprintf(toc, "modulus(&dataStack[which]);"); 111 | } 112 | 113 | else if (!strcmp(cmd, "pi")) { 114 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", M_PI); 115 | } 116 | 117 | else if (!strcmp(cmd, "tan")) { 118 | fprintf(toc, "tangent(&dataStack[which]);\n"); 119 | } 120 | 121 | else if (!strcmp(cmd, "sin")) { 122 | fprintf(toc, "sine(&dataStack[which]);\n"); 123 | } 124 | 125 | else if (!strcmp(cmd, "cos")) { 126 | fprintf(toc, "cosine(&dataStack[which]);\n"); 127 | } 128 | 129 | else if (!strcmp(cmd, "read")) { 130 | fprintf(toc, "userin(&dataStack[which]);\n"); 131 | } 132 | 133 | else if (!strcmp(cmd, ">")) { 134 | fprintf(toc, "gt(&dataStack[which]);\n"); 135 | } 136 | 137 | else if (!strcmp(cmd, "<")) { 138 | fprintf(toc, "lt(&dataStack[which]);\n"); 139 | } 140 | 141 | else if (!strcmp(cmd, "=")) { 142 | fprintf(toc, "eqeq(&dataStack[which]);\n"); 143 | } 144 | 145 | else if (!strcmp(cmd, "<=")) { 146 | fprintf(toc, "lteq(&dataStack[which]);\n"); 147 | } 148 | 149 | else if (!strcmp(cmd, ">=")) { 150 | fprintf(toc, "gteq(&dataStack[which]);\n"); 151 | } 152 | 153 | else if (!strcmp(cmd, "+")) { 154 | fprintf(toc, "plus(&dataStack[which]);\n"); 155 | } 156 | 157 | else if (!strcmp(cmd, "++")) { 158 | fprintf(toc, "plusplus(&dataStack[which]);\n"); 159 | } 160 | 161 | else if (!strcmp(cmd, "**")) { 162 | fprintf(toc, "mulmul(&dataStack[which]);\n"); 163 | } 164 | 165 | else if (!strcmp(cmd, ".")) { 166 | fprintf(toc, "showtop(&dataStack[which]);\n"); 167 | } 168 | 169 | else if (!strcmp(cmd, "*")) { 170 | fprintf(toc, "mul(&dataStack[which]);\n"); 171 | } 172 | 173 | else if (!strcmp(cmd, "dels")) { 174 | fprintf(toc, "delstack(&dataStack[which]);\n"); 175 | } 176 | 177 | else if (!strcmp(cmd, "show")) { 178 | fprintf(toc, "show(&dataStack[which]);\n"); 179 | } 180 | 181 | else if (!strcmp(cmd, "-")) { 182 | fprintf(toc, "sub(&dataStack[which]);\n"); 183 | } 184 | 185 | else if (!strcmp(cmd, "swap")) { 186 | fprintf(toc, "swap(&dataStack[which]);\n"); 187 | } 188 | 189 | else if (!strcmp(cmd, "dup")) { 190 | fprintf(toc, "duplicate(&dataStack[which], 0);\n"); 191 | } 192 | 193 | else if(!strcmp(cmd, "jump")) { 194 | fprintf(toc, "jump(&dataStack[which]);\n"); 195 | } 196 | 197 | else if (!strcmp(cmd, "range")) { 198 | fprintf(toc, "range(&dataStack[which]);\n"); 199 | } 200 | 201 | else if (!strcmp(cmd, "drop") || !strcmp(cmd, "pop")) { 202 | fprintf(toc, "drop(&dataStack[which], true);\n"); 203 | } 204 | 205 | else if (!strcmp(cmd, "over")) { 206 | fprintf(toc, "duplicate(&dataStack[which], 1);\n"); 207 | } 208 | 209 | else if (!strcmp(cmd, "wover")) { 210 | fprintf(toc, "duplicate(&dataStack[which], 2);\n"); 211 | } 212 | 213 | else if (!strcmp(cmd, "top")) { 214 | fprintf(toc, "StackPush(&dataStack[which], dataStack[which]->top);\n"); 215 | } 216 | 217 | else if (!strcmp(cmd, "outascii")) { 218 | fprintf(toc, "outascii(&charStack);\n"); 219 | } 220 | 221 | else if (!strcmp(cmd, "print")) { 222 | fprintf(toc, "allascii(&charStack);\n"); 223 | } 224 | 225 | 226 | 227 | else if (!strcmp(cmd, "/")) { 228 | fprintf(toc, "divide(&dataStack[which]);"); 229 | } 230 | 231 | //Prints total commands. Used with @tracker 232 | else if (!strcmp(cmd,"tot")) { 233 | fprintf(toc, "printf(\"tot: %d\n\");\n", cmds); 234 | } 235 | 236 | //Resets number of commands. Used with @tracker 237 | else if (!strcmp(cmd, "reset")) { 238 | fprintf(toc, "cmds = 0;\n"); 239 | } 240 | 241 | 242 | 243 | //Starting a loop. Interpreted as a word. Saves the index and control, starts saving words to evaluate later. 244 | else if (!strcmp(cmd, "[")) { 245 | if (dataStack->top < 1) { 246 | fprintf(toc, "error(\"not enough frames!\");\n"); 247 | } 248 | else { 249 | fprintf(toc, "loopStack->index = (int) StackPop(&dataStack[which]);\nloopStack->control = (int) StackPop(&dataStack[which]) + 1;\n"); 250 | } 251 | fprintf(toc, "loopStack->save = true;\n"); 252 | } 253 | 254 | //Pushes the index to the dataStack. 255 | else if (!strcmp(cmd, "i")) { 256 | fprintf(toc, "StackPush(&dataStack[which], loopStack->index);"); 257 | } 258 | 259 | //Increments the index, iterates over the commands if the index < control, otherwise resets the loopStack, and stops saving words. 260 | else if (strcmp(cmd, "]") == 0) { 261 | fprintf(toc, "loopStack->index += 1;\n"); 262 | //printf("ind %d\ncon %d\n", loopStack->index, loopStack->control); 263 | if (loopStack->index <= loopStack->control) { 264 | for (c = 0; c < loopStack->bufsize; c++) { 265 | //printf("%s\n", loopStack->buffer[c]); 266 | eval(dataStack, loopStack, list, loopStack->buffer[(int) c], toc, cons); 267 | } 268 | } 269 | else { 270 | fprintf(toc, "loopStack->index = 0;\nloopStack->control = 0;\nmemset(loopStack->buffer, '\\0', sizeof(loopStack->buffer) * RES_SIZE * DIM2);\nloopStack->bufsize = 0;\nloopStack->save = false;\n"); 271 | } 272 | } 273 | 274 | //If the command is unrecognized and not a mode setting. 275 | else { 276 | if ((cmd[0] != '@') && (cmd[0] != '#')) { 277 | fprintf(toc, "sprintf(msg, \"%s - unknown command!\");\n", cmd); 278 | fprintf(toc, "error(msg);\n"); 279 | } 280 | } 281 | 282 | //If in a loop, saves words. LOOK OUT. EVALUATES THE WORDS IN AN ENDLESS RECURSION. SAVES/EVALUATES THEN ADDS IT TO THE BUFFER. FIX! 283 | if (loopStack->save && strcmp(cmd, "[")) { 284 | fprintf(toc, "*loopStack->buffer[loopStack->bufsize++] = *cmd;\n"); 285 | } 286 | } 287 | 288 | //If not setting the mode, do whatever it is the modes do at the end of the eval() process. 289 | if (cmd[0] != '@') { 290 | if (is_enabled(list, "@transparent") && strcmp(cmd, "show") && strcmp(cmd, "tot") && strcmp(cmd, "reset") && strcmp(cmd, ".") && strcmp(cmd, "dels") && strcmp(cmd, "nil")) { 291 | fprintf(toc, "printf(\"%s | \");", cmd); 292 | fprintf(toc, "StackShow(&dataStack[which]);\n"); 293 | } 294 | if (is_enabled(list, "@tracker") && strcmp(cmd, "tot") && strcmp(cmd, "reset")) { 295 | fprintf(toc, "cmds++;\n"); 296 | } 297 | if (!is_enabled(list, "@tracker") && (cmds != 0)) { 298 | fprintf(toc, "cmds = 0;\n"); 299 | } 300 | } 301 | } 302 | 303 | //REPL 304 | int main(int argc, char *argv[]) { 305 | FILE *fp; 306 | FILE *toc; 307 | 308 | which = 0; 309 | 310 | //Initializing dataStack 311 | stackT dataStack[NUM_STACKS]; 312 | 313 | //Initializing loop stack 314 | loopstack loopStack; 315 | 316 | //Initializing modes list 317 | #include "structdef.h" 318 | loopStack.bufsize = 0; 319 | loopStack.save = false; 320 | 321 | for (a = 0; a < NUM_STACKS; a++) 322 | StackInit(&dataStack[(int) a], RES_SIZE); 323 | char cmd[DIM2] = "00"; 324 | char filepath[100]; 325 | cmds = 0; 326 | if (argc > 1) { 327 | if (str_in_arr(argc, argv, "-v") || str_in_arr(argc, argv, "--version")) { 328 | printf("%s %.1f on %s\n", PKGNAME, VERSION, OPSYS); 329 | exit(1); 330 | } 331 | fp = fopen(argv[1], "r"); 332 | sprintf(filepath, "%s.c", argv[1]); 333 | toc = fopen(filepath, "w+"); 334 | fprintf(toc, "#include \n"); 335 | if (fp != NULL) { 336 | while (fscanf(fp, "%s", cmd) != EOF) { 337 | eval(dataStack, &loopStack, list, cmd, toc, cons); 338 | } 339 | fclose(fp); 340 | fprintf(toc, "}"); 341 | fclose(toc); 342 | } 343 | else { 344 | printf("error: %s - no such file!\n", argv[1]); 345 | exit(1); 346 | } 347 | } 348 | return 0; 349 | } 350 | -------------------------------------------------------------------------------- /src/bignum/functions.h: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | 3 | bool str_in_arr(int argc, char *argv[], char *match) { 4 | int i; 5 | for (i = 0; i < argc; i++) 6 | if (!strcmp(match, argv[i])) 7 | return 1; 8 | return 0; 9 | } 10 | 11 | bool char_in_arr(char tosearch, char arr[]) { 12 | int i = 0; 13 | for(; i < strlen(arr); i++) { 14 | if (arr[i] == tosearch) { 15 | return true; 16 | } 17 | } 18 | return false; 19 | } 20 | 21 | //Easier error management. 22 | void error(char* msg) { 23 | printf("error: %s\n", msg); 24 | } 25 | 26 | //Easier return management. 27 | void ret(double msg) { 28 | printf("> %.2f\n", msg); 29 | } 30 | 31 | //Adds two numbers. If only one is on the stack, adds 0 to it. 32 | void plus(stackT *dataStack) { 33 | if (dataStack->top < 1) { 34 | StackPush(dataStack, 0); 35 | plus(dataStack); 36 | } 37 | else { 38 | b = StackPop(dataStack); 39 | a = StackPop(dataStack); 40 | StackPush(dataStack, a+b); 41 | } 42 | } 43 | 44 | //Adds all the numbers on the stack. If only one is on the stack, pushes a 0. 45 | void plusplus(stackT *dataStack) { 46 | if (dataStack->top < 1) { 47 | StackPush(dataStack, 0); 48 | plus(dataStack); 49 | } 50 | else { 51 | while (dataStack->top >= 1) { 52 | plus(dataStack); 53 | } 54 | } 55 | } 56 | 57 | //Multiplies two numbers. If only one is on the stack, multiplies it by 1. 58 | void mul(stackT *dataStack) { 59 | if (dataStack->top < 1) { 60 | StackPush(dataStack, 1); 61 | mul(dataStack); 62 | } 63 | else { 64 | b = StackPop(dataStack); 65 | a = StackPop(dataStack); 66 | StackPush(dataStack, a*b); 67 | //printf("%.0f * %.0f\n", a, b); 68 | } 69 | } 70 | 71 | //Multiplies all the numbers on the stack. If only one is on the stack, multiplies it by 1. 72 | void mulmul(stackT *dataStack) { 73 | if (dataStack->top < 1) { 74 | StackPush(dataStack, 1); 75 | mulmul(dataStack); 76 | } 77 | else { 78 | while (dataStack->top >= 1) { 79 | mul(dataStack); 80 | } 81 | } 82 | } 83 | 84 | //Prints the top number on the stack or outputs an error if there are no numbers on the stack. 85 | void showtop(stackT *dataStack) { 86 | if (StackIsEmpty(dataStack)) { 87 | error("stack is empty!"); 88 | } 89 | else { 90 | ret(dataStack->contents[dataStack->top]); 91 | } 92 | } 93 | 94 | //Pops the top number off the stack, or outputs an error if there are no numbers on the stack. 95 | void drop(stackT *dataStack, bool show) { 96 | if (StackIsEmpty(dataStack)) { 97 | error("stack is empty!"); 98 | } 99 | else { 100 | if(show) { 101 | ret(StackPop(dataStack)); 102 | } 103 | else { 104 | StackPop(dataStack); 105 | } 106 | } 107 | } 108 | 109 | //Pops all numbers off the stack. 110 | void delstack(stackT *dataStack) { 111 | if (!StackIsEmpty(dataStack)) { 112 | while (dataStack->top > -1) { 113 | drop(dataStack, false); 114 | } 115 | } 116 | } 117 | 118 | //Pretty-prints the stack. 119 | void show(stackT *dataStack) { 120 | printf("> "); 121 | StackShow(dataStack); 122 | } 123 | 124 | //Subtracts the top two numbers on the stack, or pushes 0 onto the stack and subtracts 0 from the number. 125 | void sub(stackT *dataStack) { 126 | if (dataStack->top < 1) { 127 | StackPush(dataStack, 0); 128 | sub(dataStack); 129 | } 130 | else { 131 | b = StackPop(dataStack); 132 | a = StackPop(dataStack); 133 | StackPush(dataStack, a-b); 134 | } 135 | } 136 | 137 | //Swaps the places of the top two numbers on the stack. 138 | void swap(stackT *dataStack) { 139 | if (dataStack->top < 1) { 140 | error("not enough frames!"); 141 | } 142 | else { 143 | b = StackPop(dataStack); 144 | a = StackPop(dataStack); 145 | StackPush(dataStack, b); 146 | StackPush(dataStack, a); 147 | } 148 | } 149 | 150 | //Pushes a copy of the top number onto the stack. 151 | void duplicate(stackT *dataStack, int num) { 152 | if (dataStack->top < num) { 153 | error("stack is empty!"); 154 | } 155 | else { 156 | StackPush(dataStack, dataStack->contents[dataStack->top - num]); 157 | } 158 | } 159 | 160 | //Prints the number at the index of the top number on the stack. 161 | void jump(stackT *dataStack) { 162 | if (StackIsEmpty(dataStack)) { 163 | error("stack is empty!"); 164 | } 165 | else { 166 | a = StackPop(dataStack)+1; 167 | if (a > dataStack->top) { 168 | error("not enough frames!"); 169 | } 170 | else { 171 | ret(dataStack->contents[(int) a]); 172 | } 173 | } 174 | } 175 | 176 | //Pushes a range of numbers to the stack in the order they are specified. If the stack is [ 0, 5 ] it will push [ 0,1, 2, 3, 4, 5 ]. If the stack is [ 5, 0] it will push [5, 4, 3, 2, 1, 0 ]. 177 | void range(stackT *dataStack) { 178 | if (dataStack->top < 1) { 179 | error("not enough frames!"); 180 | } 181 | else { 182 | b = StackPop(dataStack); 183 | a = StackPop(dataStack); 184 | if (a < b) { 185 | for (c = a; c <= b; c++) { 186 | StackPush(dataStack, c); 187 | } 188 | } 189 | else if (a > b) { 190 | for (c = a; c >= b; c--) { 191 | StackPush(dataStack, c); 192 | } 193 | } 194 | else if (a == b) { 195 | StackPush(dataStack, a); 196 | } 197 | } 198 | } 199 | 200 | //Outputs the ASCII representation of the top number on the stack. 201 | void outascii(stackT *dataStack) { 202 | if (dataStack->top < 0) { 203 | error("not enough frames!"); 204 | } 205 | else { 206 | printf("> %c\n", (unsigned char) StackPop(dataStack)); 207 | } 208 | } 209 | 210 | //Outputs all the numbers on the stack as ASCII in the order they appear. [ 87, 98, 99 ] will result in "abc". 211 | void allascii(stackT *dataStack) { 212 | if (dataStack->top < 0) { 213 | error("not enough frames!"); 214 | } 215 | else { 216 | printf("> "); 217 | for (a = 0; a < dataStack->top+1; a++) { 218 | printf("%c", (unsigned char) dataStack->contents[(int) a]); 219 | } 220 | printf("\n"); 221 | delstack(dataStack); 222 | } 223 | } 224 | 225 | //Divides the top two numbers on the stack. 226 | void divide(stackT *dataStack) { 227 | if (dataStack->top < 1) { 228 | error("not enough frames!"); 229 | } 230 | else { 231 | b = StackPop(dataStack); 232 | a = StackPop(dataStack); 233 | StackPush(dataStack, a/b); 234 | } 235 | } 236 | 237 | //Toggles a mode on/off. 238 | int toggle(mode *list, int index) { 239 | if (index < 0) { 240 | error("toggle error: no such mode!"); 241 | return 0; 242 | } 243 | else { 244 | list[index].enabled = !(list[index].enabled); 245 | return 1; 246 | } 247 | } 248 | 249 | //Finds the index of a particular mode. 250 | int lookup(mode *list, char *mode) { 251 | for (a = 0; a < MODETOP; a++) { 252 | if (!strcmp(list[ (int) a].mode, mode)) { 253 | return (int) a; 254 | } 255 | } 256 | return -1; 257 | } 258 | 259 | //Checks whether a mode is enabled or not. 260 | int is_enabled(mode *list, char *mode) { 261 | a = lookup(list, mode); 262 | if (a < 0) { 263 | printf("error: is_enabled error: %s - no such mode!", mode); 264 | return 0; 265 | } 266 | return list[lookup(list, mode)].enabled; 267 | } 268 | 269 | double dopow(double a, double b) { 270 | int i; 271 | for (i = 0; i < b; i++) { 272 | a *= a; 273 | } 274 | return a; 275 | } 276 | 277 | void powers(stackT *dataStack) { 278 | if (dataStack->top < 1) { 279 | StackPush(dataStack, 1.0); 280 | powers(dataStack); 281 | } 282 | else { 283 | b = StackPop(dataStack); 284 | a = StackPop(dataStack); 285 | StackPush(dataStack, pow(a, b)); 286 | } 287 | } 288 | 289 | void modulus(stackT *dataStack) { 290 | if (dataStack->top < 1) { 291 | StackPush(dataStack, 1.0); 292 | modulus(dataStack); 293 | } 294 | else { 295 | b = StackPop(dataStack); 296 | a = StackPop(dataStack); 297 | StackPush(dataStack, (int) a % (int)b); 298 | } 299 | } 300 | 301 | double deg2rad(double degrees) { 302 | return (M_PI/180)*degrees; 303 | } 304 | 305 | double rad2deg(double radians) { 306 | return (180/M_PI)*radians; 307 | } 308 | 309 | void tangent(stackT *dataStack) { 310 | if (dataStack->top < 0) { 311 | error("stack is empty!"); 312 | } 313 | else { 314 | StackPush(dataStack, tan(deg2rad(StackPop(dataStack)))); 315 | } 316 | } 317 | 318 | void sine(stackT *dataStack) { 319 | if (dataStack->top < 0) { 320 | error("stack is empty!"); 321 | } 322 | else { 323 | StackPush(dataStack, sin(deg2rad(StackPop(dataStack)))); 324 | } 325 | } 326 | 327 | void cosine(stackT *dataStack) { 328 | if (dataStack->top < 0) { 329 | error("stack is empty!"); 330 | } 331 | else { 332 | StackPush(dataStack, cos(deg2rad(StackPop(dataStack)))); 333 | } 334 | } 335 | 336 | void userin(stackT *dataStack) { 337 | char cmd[20]; 338 | if (dataStack->top < 0) { 339 | StackPush(dataStack, (double) 1); 340 | userin(dataStack); 341 | } 342 | else { 343 | a = StackPop(dataStack); 344 | while (a > 0) { 345 | printf("%d: ", (int) a); 346 | scanf("%s", cmd); 347 | StackPush(dataStack, atof(cmd)); 348 | a--; 349 | } 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /src/bignum/gecho.c: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | int var_index; 3 | #define MODETOP 3 4 | #define PKGNAME "gecho" 5 | #define VERSION 0.4 6 | #include "functions.h" 7 | int cmds; 8 | int top; 9 | double variables[RES_SIZE]; 10 | //bool incomment; 11 | 12 | //This is the eval function. 13 | int eval(stackT *dataStack, loopstack *loopStack, mode list[MODETOP], char cmd[]) { 14 | //Holds an error message. 15 | char msg[30]; 16 | //Checks if the first digit is a number, and if so, pushes it. 17 | if (dataStack->contents[dataStack->top] > DBL_MAX-10) { 18 | error("number too big!"); 19 | exit(1); 20 | } 21 | if ((cmd[0] == '-') && (isdigit(cmd[1]) || cmd[1] == '.')) { 22 | StackPush(dataStack, atof(cmd)); 23 | } 24 | else if (isdigit(cmd[0]) /*|| cmd[0] == '.'*/) { 25 | StackPush(dataStack, atof(cmd)); 26 | } 27 | else { 28 | //Converts the command to all lowercase. 29 | for(c = 0; c < strlen(cmd); c++) { 30 | cmd[(int) c] = tolower(cmd[(int) c]); 31 | } 32 | //If it's a mode change...toggle it. 33 | if ((cmd[0] == '@') && (strlen(cmd) > 1)) { 34 | a = toggle(list, lookup(list, cmd)); 35 | if (a) { 36 | printf("--%s %s--\n", cmd, is_enabled(list, cmd)?"ON":"OFF"); 37 | } 38 | } 39 | 40 | else if ((cmd[0] == '!') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 41 | var_index = atoi(cmd+1); 42 | printf("ind: %d\n", var_index); 43 | if (dataStack->top >= 0) { 44 | variables[var_index] = StackPop(dataStack); 45 | } 46 | else { 47 | error("stack is empty!"); 48 | } 49 | } 50 | 51 | else if (!strcmp(cmd, "pow")) { 52 | powers(dataStack); 53 | } 54 | 55 | else if (!strcmp(cmd, "mod")) { 56 | modulus(dataStack); 57 | } 58 | 59 | else if (!strcmp(cmd, "pi")) { 60 | StackPush(dataStack, M_PI); 61 | } 62 | 63 | else if (!strcmp(cmd, "tan")) { 64 | tangent(dataStack); 65 | } 66 | 67 | else if (!strcmp(cmd, "sin")) { 68 | sine(dataStack); 69 | } 70 | 71 | else if (!strcmp(cmd, "cos")) { 72 | cosine(dataStack); 73 | } 74 | 75 | else if (!strcmp(cmd, "read")) { 76 | userin(dataStack); 77 | } 78 | 79 | else if ((cmd[0] == '&') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 80 | var_index = atoi(cmd+1); 81 | printf("ind: %d\n", var_index); 82 | StackPush(dataStack, variables[var_index]); 83 | } 84 | 85 | //If the user wants to see the modes enabled. 86 | else if (!strcmp(cmd, "mode")) { 87 | for (a = 0; a < MODETOP; a++) { 88 | if (list[(int) a].enabled) { 89 | printf("%s ", list[(int) a].mode); 90 | } 91 | } 92 | printf("\n"); 93 | } 94 | 95 | //If the user wants to see all the modes, complete with if they are enabled. 96 | else if (!strcmp(cmd, "modes")) { 97 | for (a = 0; a < MODETOP; a++) { 98 | printf("%s:%d ", list[(int) a].mode, is_enabled(list, list[(int) a].mode)); 99 | } 100 | printf("\n"); 101 | } 102 | 103 | else if (!strcmp(cmd, "+")) { 104 | plus(dataStack); 105 | } 106 | 107 | else if (!strcmp(cmd, "++")) { 108 | plusplus(dataStack); 109 | } 110 | 111 | else if (!strcmp(cmd, "**")) { 112 | mulmul(dataStack); 113 | } 114 | 115 | else if (!strcmp(cmd, ".")) { 116 | showtop(dataStack); 117 | } 118 | 119 | else if (!strcmp(cmd, "*")) { 120 | mul(dataStack); 121 | } 122 | 123 | else if (!strcmp(cmd, "..")) { 124 | delstack(dataStack); 125 | } 126 | 127 | else if (!strcmp(cmd, "show")) { 128 | show(dataStack); 129 | } 130 | 131 | else if (!strcmp(cmd, "-")) { 132 | sub(dataStack); 133 | } 134 | 135 | else if (!strcmp(cmd, "swap")) { 136 | swap(dataStack); 137 | } 138 | 139 | else if (!strcmp(cmd, "dup")) { 140 | duplicate(dataStack, 0); 141 | } 142 | 143 | else if(!strcmp(cmd, "jump")) { 144 | jump(dataStack); 145 | } 146 | 147 | else if (!strcmp(cmd, "range")) { 148 | range(dataStack); 149 | } 150 | 151 | else if (!strcmp(cmd, "drop") || !strcmp(cmd, "pop")) { 152 | drop(dataStack, true); 153 | } 154 | 155 | else if (!strcmp(cmd, "over")) { 156 | duplicate(dataStack, 1); 157 | } 158 | 159 | else if (!strcmp(cmd, "wover")) { 160 | duplicate(dataStack, 2); 161 | } 162 | 163 | else if (!strcmp(cmd, "top")) { 164 | StackPush(dataStack, dataStack->top); 165 | } 166 | 167 | else if (!strcmp(cmd, "outascii")) { 168 | outascii(dataStack); 169 | } 170 | 171 | else if (!strcmp(cmd, "allascii")) { 172 | allascii(dataStack); 173 | } 174 | 175 | else if (!strcmp(cmd, "/")) { 176 | divide(dataStack); 177 | } 178 | 179 | //Prints total commands. Used with @tracker 180 | else if (!strcmp(cmd,"tot")) { 181 | printf("tot: %d\n", cmds); 182 | } 183 | 184 | //Resets number of commands. Used with @tracker 185 | else if (!strcmp(cmd, "reset")) { 186 | cmds = 0; 187 | } 188 | 189 | //Starting a loop. Interpreted as a word. Saves the index and control, starts saving words to evaluate later. 190 | else if (!strcmp(cmd, "[")) { 191 | if (dataStack->top < 1) { 192 | error("not enough frames!"); 193 | } 194 | else { 195 | loopStack->index = (int) StackPop(dataStack); 196 | loopStack->control = (int) StackPop(dataStack) + 1; 197 | } 198 | loopStack->save = true; 199 | } 200 | 201 | //Pushes the index to the dataStack. 202 | else if (!strcmp(cmd, "i")) { 203 | StackPush(dataStack, loopStack->index); 204 | } 205 | 206 | //Increments the index, iterates over the commands if the index < control, otherwise resets the loopStack, and stops saving words. 207 | else if (strcmp(cmd, "]") == 0) { 208 | loopStack->index += 1; 209 | //printf("ind %d\ncon %d\n", loopStack->index, loopStack->control); 210 | if (loopStack->index <= loopStack->control) { 211 | for (c = 0; c < loopStack->bufsize; c++) { 212 | //printf("%s\n", loopStack->buffer[c]); 213 | eval(dataStack, loopStack, list, loopStack->buffer[(int) c]); 214 | } 215 | } 216 | else { 217 | loopStack->index = 0; 218 | loopStack->control = 0; 219 | memset(loopStack->buffer, '\0', sizeof(loopStack->buffer) * RES_SIZE * DIM2); 220 | loopStack->bufsize = 0; 221 | loopStack->save = false; 222 | } 223 | } 224 | 225 | //If the command is unrecognized and not a mode setting. 226 | else { 227 | if ((cmd[0] != '@') && strcmp(cmd, "end")) { 228 | sprintf(msg, "%s - unknown command!", cmd); 229 | error(msg); 230 | } 231 | } 232 | 233 | //If in a loop, saves words. LOOK OUT. EVALUATES THE WORDS IN AN ENDLESS RECURSION. SAVES/EVALUATES THEN ADDS IT TO THE BUFFER. FIX! 234 | if (loopStack->save && strcmp(cmd, "[")) { 235 | *loopStack->buffer[loopStack->bufsize++] = *cmd; 236 | } 237 | } 238 | 239 | //If not setting the mode, do whatever it is the modes do at the end of the eval() process. 240 | if (cmd[0] != '@') { 241 | if (is_enabled(list, "@transparent") && strcmp(cmd, "show") && strcmp(cmd, "tot") && strcmp(cmd, "reset") && strcmp(cmd, "end")) { 242 | printf("%s | ", cmd); 243 | StackShow(dataStack); 244 | } 245 | if (is_enabled(list, "@tracker") && strcmp(cmd, "tot") && strcmp(cmd, "reset")) { 246 | cmds++; 247 | } 248 | if (!is_enabled(list, "@tracker") && (cmds != 0)) { 249 | cmds = 0; 250 | } 251 | } 252 | } 253 | 254 | //REPL 255 | int main(int argc, char *argv[]) { 256 | FILE *fp; 257 | FILE *tmp; 258 | 259 | //incomment = 0; 260 | 261 | //Initializing dataStack 262 | stackT dataStack; 263 | 264 | //Initializing loop stack 265 | loopstack loopStack; 266 | 267 | //Initializing modes list 268 | mode list[] = { 269 | {"@default", true}, 270 | {"@transparent", false}, 271 | {"@tracker", false}, 272 | }; 273 | loopStack.bufsize = 0; 274 | loopStack.save = false; 275 | //Variables. Will implement with a & prefix to access and a ! prefix to store. 276 | StackInit(&dataStack, RES_SIZE); 277 | char cmd[DIM2] = "00"; 278 | cmds = 0; 279 | if (argc > 1) { 280 | if (str_in_arr(argc, argv, "-v") || str_in_arr(argc, argv, "--version")) { 281 | printf("%s %.1f on %s\n", PKGNAME, VERSION, OPSYS); 282 | exit(1); 283 | } 284 | fp = fopen(argv[1], "r"); 285 | if (fp != NULL) { 286 | while (strcmp(cmd, "end")) { 287 | fscanf(fp, "%s", cmd); 288 | eval(&dataStack, &loopStack, list, cmd); 289 | } 290 | fclose(fp); 291 | if (!str_in_arr(argc, argv, "--shell")) { 292 | exit(1); 293 | } 294 | } 295 | else { 296 | printf("error: %s - no such file!\n", argv[1]); 297 | exit(1); 298 | } 299 | } 300 | 301 | printf("%s %.1f on %s\n\n", PKGNAME, VERSION, OPSYS); 302 | 303 | 304 | while(1) { 305 | scanf("%s", cmd); 306 | if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { 307 | printf("\nbye\n"); 308 | break; 309 | } 310 | eval(&dataStack, &loopStack, list, cmd); 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/bignum/header.h: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | #define MODETOP 3 3 | #define PKGNAME "gecho" 4 | #define VERSION 0.2 5 | #include "functions.h" 6 | int cmds; 7 | int main() { 8 | stackT dataStack; 9 | //loopstack loopStack; 10 | //loopStack.bufsize = 0; 11 | //loopStack.save = false; 12 | StackInit(&dataStack, RES_SIZE); 13 | char cmd[DIM2] = "00"; 14 | cmds = 0; 15 | 16 | -------------------------------------------------------------------------------- /src/bignum/stack.h: -------------------------------------------------------------------------------- 1 | #include "structs.h" 2 | 3 | //Stack struct. 4 | typedef struct { 5 | double *contents; 6 | int maxSize; 7 | int top; 8 | } stackT; 9 | 10 | //Initializes the stack, checking for enough memory. 11 | void StackInit(stackT *stackP, int maxSize) { 12 | double *newContents; 13 | newContents = (double *)malloc(sizeof(double)*maxSize); 14 | if (newContents == NULL) { 15 | fprintf(stderr, "Not enough memory.\n"); 16 | exit(1); 17 | } 18 | stackP->contents = newContents; 19 | stackP->maxSize = maxSize; 20 | stackP->top = -1; 21 | } 22 | 23 | //Destroys the stack and frees the allocated memory. 24 | void StackDestroy(stackT *stackP) { 25 | free(stackP->contents); 26 | stackP->contents = NULL; 27 | stackP->maxSize = 0; 28 | stackP->top = -1; 29 | } 30 | 31 | //Checks if the stack is empty. 32 | int StackIsEmpty(stackT *stackP) { 33 | return stackP->top < 0; 34 | } 35 | 36 | //Checks if the stack is full. 37 | int StackIsFull(stackT *stackP) { 38 | return stackP->top >= stackP->maxSize-1; 39 | } 40 | 41 | //Pushes a number onto the stack. 42 | void StackPush(stackT *stackP, double element) { 43 | if(StackIsFull(stackP)) { 44 | fprintf(stderr, "Can't push element: stack is full.\n"); 45 | exit(1); 46 | } 47 | stackP->contents[++stackP->top] = element; 48 | } 49 | 50 | //Pops a number from the stack. 51 | double StackPop(stackT *stackP) { 52 | if(StackIsEmpty(stackP)) { 53 | fprintf(stderr, "Can't pop element: stack is empty.\n"); 54 | exit(1); 55 | } 56 | return stackP->contents[stackP->top--]; 57 | } 58 | 59 | //Pretty-prints the stack. 60 | void StackShow(stackT *stackP) { 61 | if (stackP->top == -1) { 62 | printf("[ ]\n"); 63 | } 64 | else if (stackP->top == 0) { 65 | printf("[ %.0f ]\n", stackP->contents[0]); 66 | } 67 | else if (stackP->top > 0) { 68 | int i; 69 | printf("[ "); 70 | for (i = 0; i < stackP->top; i++) { 71 | printf("%.0f, ", stackP->contents[i]); 72 | } 73 | printf("%.0f ]\n", stackP->contents[stackP->top]); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/bignum/structs.h: -------------------------------------------------------------------------------- 1 | #include "usefunc.h" 2 | 3 | //Booleans are useful. 4 | typedef enum { 5 | false, true 6 | } bool; 7 | 8 | //Has an index, control, and can hold all the commands passed inside a loop. 9 | typedef struct { 10 | int index; 11 | int control; 12 | int bufsize; 13 | char buffer[RES_SIZE][DIM2]; 14 | bool save; 15 | } loopstack; 16 | 17 | //Mode string and an enabled flag. This language makes good use of a modes table. 18 | typedef struct { 19 | char mode[DIM2]; 20 | bool enabled; 21 | } mode; 22 | -------------------------------------------------------------------------------- /src/bignum/usefunc.h: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifndef M_PI 13 | #define M_PI 3.14159265358979323846264338327 14 | #endif 15 | 16 | #define DIM2 30 17 | #define RES_SIZE 100000 18 | #define VAR_SIZE 100 19 | 20 | #if defined _WIN32 || defined _WIN64 21 | #define OPSYS "Windows" 22 | #endif 23 | 24 | #ifdef __unix__ 25 | #define OPSYS "Unix" 26 | #endif 27 | 28 | #ifdef __APPLE__ 29 | #define OPSYS "Mac OS X" 30 | #endif 31 | 32 | #ifndef OPSYS 33 | #define OPSYS "unsupported system" 34 | #endif 35 | -------------------------------------------------------------------------------- /src/color.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define YELLOW "\e[1;33m" 10 | #define PURPLE "\e[1;35m" 11 | #define BLUE "\e[1;34m" 12 | #define RED "\e[1;31m" 13 | #define DEFAULT "\e[0m" 14 | 15 | int main() { 16 | printf(YELLOW "he" RED "llo, " BLUE "world" PURPLE "!" DEFAULT "\n"); 17 | } 18 | -------------------------------------------------------------------------------- /src/experimental/20q.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct tree_el { 5 | int val; 6 | struct tree_el * right, * left; 7 | }; 8 | 9 | typedef struct tree_el node; 10 | 11 | void insert(node ** tree, node * item) { 12 | if(!(*tree)) { 13 | *tree = item; 14 | return; 15 | } 16 | if(item->val<(*tree)->val) 17 | insert(&(*tree)->left, item); 18 | else if(item->val>(*tree)->val) 19 | insert(&(*tree)->right, item); 20 | } 21 | 22 | void printout(node * tree) { 23 | if(tree->left) printout(tree->left); 24 | printf("%d\n",tree->val); 25 | if(tree->right) printout(tree->right); 26 | } 27 | 28 | void main() { 29 | node * curr, * root; 30 | int i; 31 | 32 | 33 | root = NULL; 34 | 35 | for(i=1;i<=10;i++) { 36 | curr = (node *)malloc(sizeof(node)); 37 | curr->left = curr->right = NULL; 38 | curr->val = i; 39 | insert(&root, curr); 40 | } 41 | 42 | // printout(root); 43 | } 44 | -------------------------------------------------------------------------------- /src/experimental/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekknolagi/gecho/3d2a051dd53d901c378549f21903e8bbe7377b22/src/experimental/a.out -------------------------------------------------------------------------------- /src/experimental/cmdops: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tekknolagi/gecho/3d2a051dd53d901c378549f21903e8bbe7377b22/src/experimental/cmdops -------------------------------------------------------------------------------- /src/experimental/cmdops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct { 7 | int version; 8 | int eval; 9 | char *fn; 10 | } flags; 11 | 12 | flags flagl; 13 | 14 | int main(int argc, char **argv) { 15 | flagl.version = 0; 16 | flagl.eval = 0; 17 | flagl.fn = NULL; 18 | int index; 19 | char c; 20 | opterr = 0; 21 | 22 | while ((c = getopt(argc, argv, "vef:")) != -1) { 23 | switch(c) { 24 | case 'v': 25 | flagl.version = 1; 26 | break; 27 | case 'e': 28 | flagl.eval = 1; 29 | break; 30 | case 'f': 31 | flagl.fn = optarg; 32 | break; 33 | case '?': 34 | if (optopt == 'f') 35 | printf("Option `-%c\' requires argument!\n", optopt); 36 | else if (isprint(optopt)) 37 | printf("Unknown option `-%c\'.\n", optopt); 38 | else 39 | printf("Unknown option character `\\x%x\'.\n", optopt); 40 | return 1; 41 | default: 42 | abort(); 43 | } 44 | } 45 | 46 | printf("version = %d, eval = %d, file = %s\n", flagl.version, flagl.eval, flagl.fn); 47 | 48 | for (index = optind; index < argc; index++) { 49 | printf("Non-option argument %s\n", argv[index]); 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /src/experimental/cmdops.c~: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/experimental/difftypes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define INT(x) *((int*)x) 5 | #define STR(x) (char*)x 6 | 7 | void pprint(void *arr, int len) { 8 | //iterate over 9 | //check type 10 | //print accordingly 11 | //exit 12 | } 13 | 14 | int main(int argc, char **argv) { 15 | void *a[2]; 16 | 17 | if (argc <= 1) { 18 | char b[] = "hello"; 19 | a[1] = calloc(strlen(b), sizeof(char)); 20 | a[1] = strncpy(a[1], b, strlen(b)); 21 | } 22 | else { 23 | a[1] = calloc(strlen(argv[1]), sizeof(char)); 24 | a[1] = strncpy(a[1], argv[1], strlen(argv[1])); 25 | } 26 | 27 | a[0] = calloc(1, sizeof(int)); 28 | INT(a[0]) = strlen(a[1]); 29 | 30 | printf("%d\n", INT(a[0])); 31 | printf("%s\n", STR(a[1])); 32 | free(a[1]); 33 | free(a[0]); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /src/experimental/func.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void foobar() { 4 | printf("sex\n"); 5 | } 6 | 7 | void arr(void (*foo)()) { 8 | (* foo)(); 9 | } 10 | 11 | int main() { 12 | arr(foobar); 13 | } 14 | -------------------------------------------------------------------------------- /src/experimental/func_ptrs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define MAXLEN 5 5 | 6 | void hello_func(char name[]) { 7 | if (strlen(name) > MAXLEN-1) { 8 | name[MAXLEN-1] = '\0'; 9 | } 10 | printf("Hello, %s!\n", name); 11 | } 12 | 13 | void caps_func(char *word) { 14 | if ((word[0] >= 'a') && (word[0] <= 'z')) { 15 | word[0] -= 32; 16 | } 17 | } 18 | 19 | typedef struct { 20 | void (*hello)(char name[]); 21 | void (*caps)(char *word); 22 | } myclass; 23 | 24 | int main(int argc, char *argv[]) { 25 | myclass f = {hello_func, caps_func}; 26 | if (argc > 1) { 27 | int i; 28 | for (i = 1; i < argc; i++) { 29 | f.caps(argv[i]); 30 | f.hello(argv[i]); 31 | } 32 | } 33 | else { 34 | printf("Hello, world!\n"); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/experimental/hashtable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct { 5 | int key; 6 | char *tag; 7 | } 8 | 9 | int main() { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/experimental/makel.py: -------------------------------------------------------------------------------- 1 | def cons(l): 2 | for i in range(len(l)): 3 | if type(l[i]) != list: l[i] = [l[i]] 4 | return sum(l, []) 5 | 6 | l = [1, 2, 3, [4, 5, 6], "hello", ["hello"]] 7 | 8 | print cons(l) 9 | -------------------------------------------------------------------------------- /src/experimental/makel.py~: -------------------------------------------------------------------------------- 1 | def cons(l): 2 | for i in range(len(l)): 3 | if type(l[i]) != list: l[i] = [l[i]] 4 | return sum(l, []) 5 | 6 | l = [1, 2, 3, [4, 5, 6]] 7 | 8 | print cons(l) 9 | -------------------------------------------------------------------------------- /src/experimental/type2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define ptr(y, x) *((y *)(x)) 5 | #define ARRSIZE 3 6 | 7 | int main() { 8 | 9 | void **arr = malloc(ARRSIZE*sizeof(void *)); 10 | arr[0] = strdup("Some string!"); 11 | 12 | printf("%s\n", (char *) arr[0]); 13 | 14 | arr[1] = malloc(sizeof(int)); 15 | ptr(int, arr[1]) = 5; 16 | 17 | printf("%d\n", ptr(int, arr[1])); 18 | 19 | arr[2] = malloc(sizeof(double)); 20 | ptr(double, arr[2]) = 27.3; 21 | 22 | printf("%f\n", ptr(double, arr[2])); 23 | 24 | int i; 25 | 26 | for (i = 0; i < ARRSIZE; i++) 27 | free(arr[i]); 28 | 29 | free(arr); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/experimental/type2.c~: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define ptr(y, x) *((y *)(x)) 5 | #define ARRSIZE 3 6 | 7 | int main() { 8 | 9 | void **arr = malloc(ARRSIZE*sizeof(void *)); 10 | arr[0] = strdup("Some string!"); 11 | 12 | printf("%s\n", arr[0]); 13 | 14 | arr[1] = malloc(sizeof(int)); 15 | ptr(int, arr[1]) = 5; 16 | 17 | printf("%d\n", arr[1]); 18 | 19 | arr[2] = malloc(sizeof(double)); 20 | ptr(double, arr[2]) = 27.3; 21 | 22 | printf("%f\n", arr[2]); 23 | 24 | int i; 25 | 26 | for (i = 0; i < ARRSIZE; i++) 27 | free(arr[i]); 28 | 29 | free(arr); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/experimental/types.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | int a = 5; 6 | int b = typeof(a); 7 | printf("%i", b); 8 | } 9 | -------------------------------------------------------------------------------- /src/experimental/types.c~: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | int a = 5; 7 | int b = typeof(a); 8 | printf("%i", b); 9 | } 10 | -------------------------------------------------------------------------------- /src/functions.h: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #ifndef FUNCTIONS_H_ 3 | #define FUNCTIONS_H_ 4 | 5 | bool str_in_arr(int argc, char *argv[], char *match) { 6 | int i; 7 | for (i = 0; i < argc; i++) 8 | if (!strcmp(match, argv[i])) 9 | return 1; 10 | return 0; 11 | } 12 | 13 | bool char_in_arr(char tosearch, char arr[]) { 14 | int i = 0; 15 | for(; i < strlen(arr); i++) { 16 | if (arr[i] == tosearch) { 17 | return true; 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | //Easier error management. 24 | void error(char* msg) { 25 | printf(RED "error:" YELLOW " %s\n" DEFAULT, msg); 26 | } 27 | 28 | //Easier return management. 29 | void ret(double msg) { 30 | printf(PURPLE "%.2f\n" DEFAULT, msg); 31 | } 32 | 33 | //Adds two numbers. If only one is on the stack, adds 0 to it. 34 | void plus(stackT *dataStack) { 35 | if (dataStack->top < 1) { 36 | StackPush(dataStack, 0); 37 | plus(dataStack); 38 | } 39 | else { 40 | b = StackPop(dataStack); 41 | a = StackPop(dataStack); 42 | StackPush(dataStack, a+b); 43 | } 44 | } 45 | 46 | //Adds all the numbers on the stack. If only one is on the stack, pushes a 0. 47 | void plusplus(stackT *dataStack) { 48 | if (dataStack->top < 1) { 49 | StackPush(dataStack, 0); 50 | plus(dataStack); 51 | } 52 | else { 53 | while (dataStack->top >= 1) { 54 | plus(dataStack); 55 | } 56 | } 57 | } 58 | 59 | //Multiplies two numbers. If only one is on the stack, multiplies it by 1. 60 | void mul(stackT *dataStack) { 61 | if (dataStack->top < 1) { 62 | StackPush(dataStack, 1); 63 | mul(dataStack); 64 | } 65 | else { 66 | b = StackPop(dataStack); 67 | a = StackPop(dataStack); 68 | StackPush(dataStack, a*b); 69 | //printf("%.0f * %.0f\n", a, b); 70 | } 71 | } 72 | 73 | //Multiplies all the numbers on the stack. If only one is on the stack, multiplies it by 1. 74 | void mulmul(stackT *dataStack) { 75 | if (dataStack->top < 1) { 76 | StackPush(dataStack, 1); 77 | mulmul(dataStack); 78 | } 79 | else { 80 | while (dataStack->top >= 1) { 81 | mul(dataStack); 82 | } 83 | } 84 | } 85 | 86 | //Prints the top number on the stack or outputs an error if there are no numbers on the stack. 87 | void showtop(stackT *dataStack) { 88 | if (StackIsEmpty(dataStack)) { 89 | error("stack is empty!"); 90 | } 91 | else { 92 | printf(PURPLE "%.2f\n" DEFAULT, dataStack->contents[dataStack->top]); 93 | } 94 | } 95 | 96 | //Pops the top number off the stack, or outputs an error if there are no numbers on the stack. 97 | void drop(stackT *dataStack, bool show) { 98 | if (StackIsEmpty(dataStack)) { 99 | error("stack is empty!"); 100 | } 101 | else { 102 | if(show) { 103 | ret(StackPop(dataStack)); 104 | } 105 | else { 106 | StackPop(dataStack); 107 | } 108 | } 109 | } 110 | 111 | //Pops all numbers off the stack. 112 | void delstack(stackT *dataStack) { 113 | if (!StackIsEmpty(dataStack)) { 114 | while (dataStack->top > -1) { 115 | drop(dataStack, false); 116 | } 117 | } 118 | } 119 | 120 | //Pretty-prints the stack. 121 | void show(stackT *dataStack) { 122 | StackShow(dataStack); 123 | } 124 | 125 | //Subtracts the top two numbers on the stack, or pushes 0 onto the stack and subtracts 0 from the number. 126 | void sub(stackT *dataStack) { 127 | if (dataStack->top < 1) { 128 | StackPush(dataStack, 0); 129 | sub(dataStack); 130 | } 131 | else { 132 | b = StackPop(dataStack); 133 | a = StackPop(dataStack); 134 | StackPush(dataStack, a-b); 135 | } 136 | } 137 | 138 | //Swaps the places of the top two numbers on the stack. 139 | void swap(stackT *dataStack) { 140 | if (dataStack->top < 1) { 141 | error("not enough frames!"); 142 | } 143 | else { 144 | b = StackPop(dataStack); 145 | a = StackPop(dataStack); 146 | StackPush(dataStack, b); 147 | StackPush(dataStack, a); 148 | } 149 | } 150 | 151 | //Pushes a copy of the top number onto the stack. 152 | void duplicate(stackT *dataStack, int num) { 153 | if (dataStack->top < num) { 154 | error("stack is empty!"); 155 | } 156 | else { 157 | StackPush(dataStack, dataStack->contents[dataStack->top - num]); 158 | } 159 | } 160 | 161 | //Prints the number at the index of the top number on the stack. 162 | void jump(stackT *dataStack) { 163 | if (StackIsEmpty(dataStack)) { 164 | error("stack is empty!"); 165 | } 166 | else { 167 | a = StackPop(dataStack)+1; 168 | if (a > dataStack->top) { 169 | error("not enough frames!"); 170 | } 171 | else { 172 | ret(dataStack->contents[(int) a]); 173 | } 174 | } 175 | } 176 | 177 | //Pushes a range of numbers to the stack in the order they are specified. If the stack is [ 0, 5 ] it will push [ 0,1, 2, 3, 4, 5 ]. If the stack is [ 5, 0] it will push [5, 4, 3, 2, 1, 0 ]. 178 | void range(stackT *dataStack) { 179 | if (dataStack->top < 1) { 180 | error("not enough frames!"); 181 | } 182 | else { 183 | b = StackPop(dataStack); 184 | a = StackPop(dataStack); 185 | if (a < b) { 186 | for (c = a; c <= b; c++) { 187 | StackPush(dataStack, c); 188 | } 189 | } 190 | else if (a > b) { 191 | for (c = a; c >= b; c--) { 192 | StackPush(dataStack, c); 193 | } 194 | } 195 | else if (a == b) { 196 | StackPush(dataStack, a); 197 | } 198 | } 199 | } 200 | 201 | //Outputs the ASCII representation of the top number on the stack. 202 | void outascii(stackT *dataStack) { 203 | if (dataStack->top < 0) { 204 | error("not enough frames!"); 205 | } 206 | else { 207 | printf(PURPLE "%c\n" DEFAULT, (unsigned char) StackPop(dataStack)); 208 | } 209 | } 210 | 211 | //Outputs all the numbers on the stack as ASCII in the order they appear. [ 87, 98, 99 ] will result in "abc". 212 | void allascii(stackT *dataStack) { 213 | if (dataStack->top < 0) { 214 | error("not enough frames!"); 215 | } 216 | else { 217 | printf(PURPLE); 218 | for (a = 0; a < dataStack->top+1; a++) { 219 | printf("%c", (unsigned char) dataStack->contents[(int) a]); 220 | } 221 | printf("\n"); 222 | delstack(dataStack); 223 | printf(DEFAULT); 224 | } 225 | } 226 | 227 | //Divides the top two numbers on the stack. 228 | void divide(stackT *dataStack) { 229 | if (dataStack->top < 1) { 230 | error("not enough frames!"); 231 | } 232 | else { 233 | b = StackPop(dataStack); 234 | a = StackPop(dataStack); 235 | StackPush(dataStack, a/b); 236 | } 237 | } 238 | 239 | //Toggles a mode on/off. 240 | int toggle(mode *list, int index) { 241 | if (index < 0) { 242 | error("toggle error: no such mode!"); 243 | return 0; 244 | } 245 | else { 246 | list[index].enabled = !(list[index].enabled); 247 | return 1; 248 | } 249 | } 250 | 251 | //Finds the index of a particular mode. 252 | int lookup(mode *list, char *mode) { 253 | for (a = 0; a < MODETOP; a++) { 254 | if (!strcmp(list[(int) a].mode, mode)) { 255 | return (int) a; 256 | } 257 | } 258 | return -1; 259 | } 260 | 261 | int c_lookup(const_list *list, char *const_name) { 262 | for (a = 0; a < CONSTOP; a++) { 263 | if (!strcmp(list[ (int) a].name, const_name)) { 264 | return (int) a; 265 | } 266 | } 267 | return -1; 268 | } 269 | 270 | //Checks whether a mode is enabled or not. 271 | int is_enabled(mode *list, char *mode) { 272 | a = lookup(list, mode); 273 | if (a < 0) { 274 | printf(RED "error: " YELLOW "is_enabled error: %s - no such mode!" DEFAULT, mode); 275 | return 0; 276 | } 277 | return list[lookup(list, mode)].enabled; 278 | } 279 | 280 | double dopow(double a, double b) { 281 | int i; 282 | for (i = 0; i < b; i++) { 283 | a *= a; 284 | } 285 | return a; 286 | } 287 | 288 | void powers(stackT *dataStack) { 289 | if (dataStack->top < 1) { 290 | StackPush(dataStack, 1.0); 291 | powers(dataStack); 292 | } 293 | else { 294 | b = StackPop(dataStack); 295 | a = StackPop(dataStack); 296 | StackPush(dataStack, pow(a, b)); 297 | } 298 | } 299 | 300 | void modulus(stackT *dataStack) { 301 | if (dataStack->top < 1) { 302 | StackPush(dataStack, 1.0); 303 | modulus(dataStack); 304 | } 305 | else { 306 | b = StackPop(dataStack); 307 | a = StackPop(dataStack); 308 | StackPush(dataStack, (int) a % (int)b); 309 | } 310 | } 311 | 312 | double deg2rad(double degrees) { 313 | return (M_PI/180)*degrees; 314 | } 315 | 316 | double rad2deg(double radians) { 317 | return (180/M_PI)*radians; 318 | } 319 | 320 | void tangent(stackT *dataStack) { 321 | if (dataStack->top < 0) { 322 | error("stack is empty!"); 323 | } 324 | else { 325 | StackPush(dataStack, tan(deg2rad(StackPop(dataStack)))); 326 | } 327 | } 328 | 329 | void sine(stackT *dataStack) { 330 | if (dataStack->top < 0) { 331 | error("stack is empty!"); 332 | } 333 | else { 334 | StackPush(dataStack, sin(deg2rad(StackPop(dataStack)))); 335 | } 336 | } 337 | 338 | void cosine(stackT *dataStack) { 339 | if (dataStack->top < 0) { 340 | error("stack is empty!"); 341 | } 342 | else { 343 | StackPush(dataStack, cos(deg2rad(StackPop(dataStack)))); 344 | } 345 | } 346 | 347 | void userin(stackT *dataStack) { 348 | char cmd[20]; 349 | if (dataStack->top < 0) { 350 | StackPush(dataStack, (double) 1); 351 | userin(dataStack); 352 | } 353 | else { 354 | a = StackPop(dataStack); 355 | while (a > 0) { 356 | printf(PURPLE "%d: " DEFAULT, (int) a); 357 | scanf("%s", cmd); 358 | StackPush(dataStack, atof(cmd)); 359 | a--; 360 | } 361 | } 362 | } 363 | 364 | void gt(stackT *dataStack) { 365 | if (dataStack->top < 1) { 366 | error("not enough frames!"); 367 | } 368 | else { 369 | b = StackPop(dataStack); 370 | a = StackPop(dataStack); 371 | StackPush(dataStack, (double) a>b); 372 | } 373 | } 374 | 375 | void lt(stackT *dataStack) { 376 | if (dataStack->top < 1) { 377 | error("not enough frames!"); 378 | } 379 | else { 380 | b = StackPop(dataStack); 381 | a = StackPop(dataStack); 382 | StackPush(dataStack, (double) atop < 1) { 388 | error("not enough frames!"); 389 | } 390 | else { 391 | b = StackPop(dataStack); 392 | a = StackPop(dataStack); 393 | StackPush(dataStack, (double) a==b); 394 | } 395 | } 396 | 397 | void gteq(stackT *dataStack) { 398 | if (dataStack->top < 1) { 399 | error("not enough frames!"); 400 | } 401 | else { 402 | b = StackPop(dataStack); 403 | a = StackPop(dataStack); 404 | StackPush(dataStack, (double) a>=b); 405 | } 406 | } 407 | 408 | void lteq(stackT *dataStack) { 409 | if (dataStack->top < 1) { 410 | error("not enough frames!"); 411 | } 412 | else { 413 | b = StackPop(dataStack); 414 | a = StackPop(dataStack); 415 | StackPush(dataStack, (double) a<=b); 416 | } 417 | } 418 | 419 | void log_and(stackT *dataStack) { 420 | if (dataStack->top < 1) { 421 | error("not enough frames!"); 422 | } 423 | else { 424 | b = StackPop(dataStack); 425 | a = StackPop(dataStack); 426 | StackPush(dataStack, a && b); 427 | } 428 | } 429 | 430 | void log_or(stackT *dataStack) { 431 | if (dataStack->top < 1) { 432 | error("not enough frames!"); 433 | } 434 | else { 435 | b = StackPop(dataStack); 436 | a = StackPop(dataStack); 437 | StackPush(dataStack, a || b); 438 | } 439 | } 440 | #endif 441 | -------------------------------------------------------------------------------- /src/gecho.c: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | 3 | int var_index; 4 | #define PKGNAME "gecho [expanded]" 5 | #define VERSION 0.6 6 | #include "functions.h" 7 | int cmds; 8 | int top; 9 | double variables[RES_SIZE]; 10 | stackT charStack; 11 | char *WORD; 12 | 13 | void next() { 14 | if (which < NUM_STACKS-1) which++; 15 | else which = 0; 16 | } 17 | 18 | void back() { 19 | if (which >= 1) which--; 20 | else which = NUM_STACKS-1; 21 | } 22 | 23 | //This is the eval function. 24 | void eval(stackT dataStack[], loopstack *loopStack, mode list[MODETOP], char cmd[], const_list cons[CONSTOP]) { 25 | //Holds an error message. 26 | char msg[30]; 27 | //Checks if the first digit is a number, and if so, pushes it. 28 | if ((cmd[0] == '-') && (isdigit(cmd[1]) || cmd[1] == '.')) { 29 | StackPush(&dataStack[which], atof(cmd)); 30 | } 31 | else if (isdigit(cmd[0]) || ((cmd[0] == '.') && isdigit(cmd[1]))) { 32 | StackPush(&dataStack[which], atof(cmd)); 33 | } 34 | else if (!strcmp(cmd, "<>")) { 35 | StackPush(&charStack, (int) ' '); 36 | } 37 | else if ((cmd[0] == '\'') || (cmd[0] == '`')) { 38 | if (strlen(cmd) > 1) { 39 | for (a = 1; a < strlen(cmd); a++) { 40 | StackPush(&charStack, (int) cmd[(int) a]); 41 | } 42 | } 43 | else { 44 | error("not a valid char/string!"); 45 | } 46 | } 47 | 48 | else { 49 | //Converts the command to all lowercase. 50 | for(c = 0; c < strlen(cmd); c++) { 51 | cmd[(int) c] = tolower(cmd[(int) c]); 52 | } 53 | 54 | if (!strcmp(cmd, "nil")); 55 | 56 | //If it's a mode change...toggle it. 57 | else if ((cmd[0] == '@') && (strlen(cmd) > 1)) { 58 | a = toggle(list, lookup(list, cmd)); 59 | if (a) { 60 | printf(BLUE "--%s %s--\n" DEFAULT, cmd, is_enabled(list, cmd)?"ON":"OFF"); 61 | } 62 | } 63 | 64 | else if (cmd[0] == '#') { 65 | if (strlen(cmd) > 1) { 66 | if (c_lookup(cons, cmd) != -1) { 67 | StackPush(&dataStack[which], cons[c_lookup(cons, cmd)].value); 68 | } 69 | } 70 | else { 71 | error("not enough frames!"); 72 | } 73 | } 74 | 75 | else if (!strcmp(cmd, "and")) { 76 | log_and(&dataStack[which]); 77 | } 78 | 79 | else if (!strcmp(cmd, "or")) { 80 | log_or(&dataStack[which]); 81 | } 82 | 83 | else if ((cmd[0] == '!') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 84 | var_index = atoi(cmd+1); 85 | if (&dataStack[which].top >= 0) { 86 | variables[var_index] = StackPop(&dataStack[which]); 87 | } 88 | else { 89 | error("stack is empty!"); 90 | } 91 | } 92 | 93 | else if (!strcmp(cmd, "pow")) { 94 | powers(&dataStack[which]); 95 | } 96 | 97 | else if (!strcmp(cmd, "mod")) { 98 | modulus(&dataStack[which]); 99 | } 100 | 101 | else if (!strcmp(cmd, "tan")) { 102 | tangent(&dataStack[which]); 103 | } 104 | 105 | else if (!strcmp(cmd, "sin")) { 106 | sine(&dataStack[which]); 107 | } 108 | 109 | else if (!strcmp(cmd, "cos")) { 110 | cosine(&dataStack[which]); 111 | } 112 | 113 | else if (!strcmp(cmd, "read")) { 114 | userin(&dataStack[which]); 115 | } 116 | 117 | else if (!strcmp(cmd, ">")) { 118 | gt(&dataStack[which]); 119 | } 120 | 121 | else if (!strcmp(cmd, "<")) { 122 | lt(&dataStack[which]); 123 | } 124 | 125 | else if (!strcmp(cmd, "=")) { 126 | eqeq(&dataStack[which]); 127 | } 128 | 129 | else if (!strcmp(cmd, "<=")) { 130 | lteq(&dataStack[which]); 131 | } 132 | 133 | else if (!strcmp(cmd, ">=")) { 134 | gteq(&dataStack[which]); 135 | } 136 | 137 | else if ((cmd[0] == '&') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 138 | var_index = atoi(cmd+1); 139 | StackPush(&dataStack[which], variables[var_index]); 140 | } 141 | 142 | //If the user wants to see the modes enabled. 143 | else if (!strcmp(cmd, "mode")) { 144 | for (a = 0; a < MODETOP; a++) { 145 | if (list[(int) a].enabled) { 146 | printf(BLUE "%s " DEFAULT, list[(int) a].mode); 147 | } 148 | } 149 | printf("\n"); 150 | } 151 | 152 | //If the user wants to see all the modes, complete with if they are enabled. 153 | else if (!strcmp(cmd, "modes")) { 154 | for (a = 0; a < MODETOP; a++) { 155 | printf(BLUE "%s" DEFAULT ":" PURPLE "%d " DEFAULT, list[(int) a].mode, is_enabled(list, list[(int) a].mode)); 156 | } 157 | printf("\n"); 158 | } 159 | 160 | else if (!strcmp(cmd, "+")) { 161 | plus(&dataStack[which]); 162 | } 163 | 164 | else if (!strcmp(cmd, "++")) { 165 | plusplus(&dataStack[which]); 166 | } 167 | 168 | else if (!strcmp(cmd, "**")) { 169 | mulmul(&dataStack[which]); 170 | } 171 | 172 | else if (!strcmp(cmd, ".")) { 173 | showtop(&dataStack[which]); 174 | } 175 | 176 | else if (!strcmp(cmd, "*")) { 177 | mul(&dataStack[which]); 178 | } 179 | 180 | else if (!strcmp(cmd, "dels")) { 181 | delstack(&dataStack[which]); 182 | } 183 | 184 | else if (!strcmp(cmd, "show")) { 185 | StackShow(&dataStack[which]); 186 | } 187 | 188 | else if (!strcmp(cmd, "-")) { 189 | sub(&dataStack[which]); 190 | } 191 | 192 | else if (!strcmp(cmd, "swap")) { 193 | swap(&dataStack[which]); 194 | } 195 | 196 | else if (!strcmp(cmd, "dup")) { 197 | duplicate(&dataStack[which], 0); 198 | } 199 | 200 | else if(!strcmp(cmd, "jump")) { 201 | jump(&dataStack[which]); 202 | } 203 | 204 | else if (!strcmp(cmd, "range")) { 205 | range(&dataStack[which]); 206 | } 207 | 208 | else if (!strcmp(cmd, "drop") || !strcmp(cmd, "pop")) { 209 | drop(&dataStack[which], true); 210 | } 211 | 212 | else if (!strcmp(cmd, "over")) { 213 | duplicate(&dataStack[which], 1); 214 | } 215 | 216 | else if (!strcmp(cmd, "wover")) { 217 | duplicate(&dataStack[which], 2); 218 | } 219 | 220 | else if (!strcmp(cmd, "top")) { 221 | StackPush(&dataStack[which], dataStack[which].top); 222 | } 223 | 224 | else if (!strcmp(cmd, "next")) { 225 | next(); 226 | } 227 | 228 | else if (!strcmp(cmd, "back")) { 229 | back(); 230 | } 231 | 232 | else if (!strcmp(cmd, "outascii")) { 233 | outascii(&charStack); 234 | } 235 | 236 | else if (!strcmp(cmd, "print")) { 237 | allascii(&charStack); 238 | } 239 | 240 | else if (!strcmp(cmd, "mv")) { 241 | a = StackPop(&dataStack[which]); 242 | next(); 243 | StackPush(&dataStack[which], a); 244 | } 245 | 246 | else if (!strcmp(cmd, "/")) { 247 | divide(&dataStack[which]); 248 | } 249 | 250 | else if (cmd[0] == '{') { 251 | printf("return val: %d\n", sscanf(cmd, "{%s}", WORD)); 252 | printf("body: %s\n", WORD); 253 | } 254 | 255 | //Prints total commands. Used with @tracker 256 | else if (!strcmp(cmd,"tot")) { 257 | printf("tot: %d\n", cmds); 258 | } 259 | 260 | //Resets number of commands. Used with @tracker 261 | else if (!strcmp(cmd, "reset")) { 262 | cmds = 0; 263 | } 264 | 265 | //Starting a loop. Interpreted as a word. Saves the index and control, starts saving words to evaluate later. 266 | else if (!strcmp(cmd, "[")) { 267 | if (dataStack[which].top < 1) { 268 | error("not enough frames!"); 269 | } 270 | else { 271 | loopStack->index = (int) StackPop(&dataStack[which]); 272 | loopStack->control = (int) StackPop(&dataStack[which]) + 1; 273 | } 274 | loopStack->save = true; 275 | } 276 | 277 | //Pushes the index to the dataStack. 278 | else if (!strcmp(cmd, "i")) { 279 | StackPush(&dataStack[which], loopStack->index); 280 | } 281 | 282 | //Increments the index, iterates over the commands if the index < control, otherwise resets the loopStack, and stops saving words. 283 | else if (strcmp(cmd, "]") == 0) { 284 | loopStack->index += 1; 285 | //printf("ind %d\ncon %d\n", loopStack->index, loopStack->control); 286 | if (loopStack->index <= loopStack->control) { 287 | for (c = 0; c < loopStack->bufsize; c++) { 288 | //printf("%s\n", loopStack->buffer[c]); 289 | //FIX LAME EVAL 290 | eval(&dataStack[which], loopStack, list, loopStack->buffer[(int) c], cons); 291 | } 292 | } 293 | else { 294 | loopStack->index = 0; 295 | loopStack->control = 0; 296 | memset(loopStack->buffer, '\0', sizeof(loopStack->buffer) * RES_SIZE * DIM2); 297 | loopStack->bufsize = 0; 298 | loopStack->save = false; 299 | } 300 | } 301 | 302 | //If the command is unrecognized and not a mode setting or constant. 303 | else { 304 | if ((cmd[0] != '@') && (cmd[0] != '#')) { 305 | sprintf(msg, "%s - unknown command!", cmd); 306 | error(msg); 307 | } 308 | } 309 | 310 | //If in a loop, saves words. LOOK OUT. EVALUATES THE WORDS IN AN ENDLESS RECURSION. SAVES/EVALUATES THEN ADDS IT TO THE BUFFER. FIX! 311 | if (loopStack->save && strcmp(cmd, "[")) { 312 | *loopStack->buffer[loopStack->bufsize++] = *cmd; 313 | } 314 | } 315 | 316 | //If not setting the mode, do whatever it is the modes do at the end of the eval() process. 317 | if (cmd[0] != '@') { 318 | if (is_enabled(list, "@transparent") && strcmp(cmd, "show") && strcmp(cmd, "tot") && strcmp(cmd, "reset") && strcmp(cmd, ".") && strcmp(cmd, "dels") && strcmp(cmd, "nil")) { 319 | printf("%s | ", cmd); 320 | StackShow(&dataStack[which]); 321 | } 322 | if (is_enabled(list, "@tracker") && strcmp(cmd, "tot") && strcmp(cmd, "reset")) { 323 | cmds++; 324 | } 325 | if (!is_enabled(list, "@tracker") && (cmds != 0)) { 326 | cmds = 0; 327 | } 328 | } 329 | } 330 | 331 | //REPL 332 | int main(int argc, char *argv[]) { 333 | flags flagl; 334 | FILE *fp; 335 | 336 | which = 0; 337 | 338 | //Initializing dataStack 339 | stackT dataStack[NUM_STACKS]; 340 | 341 | //Initializing loop stack 342 | loopstack loopStack; 343 | 344 | //Initializing modes&&const list 345 | #include "structdef.h" 346 | 347 | flagl.version = 0; 348 | flagl.eval = 0; 349 | flagl.shell = 0; 350 | flagl.f = 0; 351 | flagl.help = 0; 352 | flagl.fn = NULL; 353 | int index; 354 | int optt; 355 | opterr = 0; 356 | 357 | while ((optt = getopt(argc, argv, "hvesf:")) != -1) { 358 | switch(optt) { 359 | case 'h': 360 | flagl.version = 1; 361 | flagl.help = 1; 362 | break; 363 | case 'v': 364 | flagl.version = 1; 365 | break; 366 | case 'e': 367 | flagl.eval = 1; 368 | break; 369 | case 'f': 370 | flagl.f = 1; 371 | flagl.fn = optarg; 372 | break; 373 | case 's': 374 | flagl.shell = 1; 375 | break; 376 | case '?': 377 | if (optopt == 'f') 378 | printf("Option `-%c\' requires argument!\n", optopt); 379 | else if (isprint(optopt)) 380 | printf("Unknown option `-%c\'.\n", optopt); 381 | else 382 | printf("Unknown option character `\\x%x\'.\n", optopt); 383 | return 1; 384 | default: 385 | abort(); 386 | } 387 | } 388 | 389 | for (index = optind; index < argc; index++) { 390 | printf("Non-option argument %s\n", argv[index]); 391 | } 392 | 393 | if (flagl.help) { 394 | printf("Usage:\ngecho -[h v e f s]\n where -f has one argument; a file\nand -v prints the version\nand -e evaluates the string passed to gecho\nand -s goes into a shell after evaluating a file\n and -h brings up this screen."); 395 | } 396 | 397 | loopStack.bufsize = 0; 398 | loopStack.save = false; 399 | 400 | for (a = 0; a < NUM_STACKS; a++) 401 | StackInit(&dataStack[(int) a], RES_SIZE); 402 | 403 | StackInit(&charStack, RES_SIZE); 404 | char cmd[DIM2] = "00"; 405 | cmds = 0; 406 | if (argc > 1) { 407 | if (flagl.version) { 408 | printf("%s %.1f on %s\n", PKGNAME, VERSION, OPSYS); 409 | exit(1); 410 | } 411 | if (!flagl.eval && flagl.f) { 412 | fp = fopen(flagl.fn, "r"); 413 | if (fp != NULL) { 414 | while (fscanf(fp, "%s", cmd) != EOF) { 415 | eval(dataStack, &loopStack, list, cmd, cons); 416 | } 417 | fclose(fp); 418 | if (!flagl.shell) { 419 | exit(1); 420 | } 421 | printf("~~~~~~~~~~\n"); 422 | } 423 | else { 424 | printf("error: %s - no such file!\n", flagl.fn); 425 | exit(1); 426 | } 427 | } 428 | } 429 | 430 | if (!flagl.eval && !flagl.shell) { 431 | printf("%s %.1f on %s\n\n", PKGNAME, VERSION, OPSYS); 432 | } 433 | 434 | while(1) { 435 | scanf("%s", cmd); 436 | if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { 437 | if (!flagl.eval) { 438 | printf("\nbye\n"); 439 | } 440 | break; 441 | } 442 | eval(dataStack, &loopStack, list, cmd, cons); 443 | } 444 | return 0; 445 | } 446 | -------------------------------------------------------------------------------- /src/gechoc.c: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | int var_index; 3 | #define PKGNAME "gecho" 4 | #define VERSION 0.6 5 | #include "functions.h" 6 | int cmds; 7 | int top; 8 | double variables[RES_SIZE]; 9 | 10 | int which = 0; 11 | 12 | void next() { 13 | if (which < NUM_STACKS) which++; 14 | else which = 0; 15 | } 16 | 17 | void back() { 18 | if (which > 0) which--; 19 | else which = NUM_STACKS-1; 20 | } 21 | 22 | //This is the eval function. 23 | void eval(stackT dataStack[], loopstack *loopStack, mode list[MODETOP], char cmd[], FILE *toc, const_list cons[CONSTOP]) { 24 | //Checks if the first digit is a number, and if so, pushes it. 25 | if ((cmd[0] == '-') && (isdigit(cmd[1]) || cmd[1] == '.')) { 26 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", atof(cmd)); 27 | } 28 | else if (isdigit(cmd[0]) || ((cmd[0] == '.') && isdigit(cmd[1]))) { 29 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", atof(cmd)); 30 | } 31 | else if (!strcmp(cmd, "<>")) { 32 | fprintf(toc, "StackPush(&charStack, (int) \' \');\n"); 33 | } 34 | else if ((cmd[0] == '\'') || (cmd[0] == '`')) { 35 | if (strlen(cmd) > 1) { 36 | for (a = 1; a < strlen(cmd); a++) { 37 | fprintf(toc, "StackPush(&charStack, (int) \'%c\');\n", cmd[(int) a]); 38 | } 39 | } 40 | else { 41 | fprintf(toc, "error(\"not a valid char/string!\");\n"); 42 | } 43 | } 44 | else { 45 | //Converts the command to all lowercase. 46 | for(c = 0; c < strlen(cmd); c++) { 47 | cmd[(int) c] = tolower(cmd[(int) c]); 48 | } 49 | 50 | if (!strcmp(cmd, "nil")); 51 | 52 | //If it's a mode change...toggle it. 53 | else if ((cmd[0] == '@') && (strlen(cmd) > 1)) { 54 | a = toggle(list, lookup(list, cmd)); 55 | if (a) { 56 | fprintf(toc, "printf(\"--%s %s--\\n\");\n", cmd, is_enabled(list,cmd)?"ON":"OFF"); 57 | } 58 | } 59 | 60 | else if (cmd[0] == '#') { 61 | if (strlen(cmd) > 1) { 62 | if (c_lookup(cons, cmd) != -1) { 63 | fprintf(toc, "StackPush(dataStack[which], cons[c_lookup(cons, cmd)].value);\n"); 64 | } 65 | } 66 | else { 67 | fprintf(toc, "error(\"not enough frames!\");\n"); 68 | } 69 | } 70 | 71 | else if (!strcmp(cmd, "and")) { 72 | fprintf(toc, "log_and(&dataStack[which]);\n"); 73 | } 74 | 75 | else if (!strcmp(cmd, "or")) { 76 | fprintf(toc, "log_or(&dataStack[which]);\n"); 77 | } 78 | 79 | else if (!strcmp(cmd, "next")) { 80 | fprintf(toc, "next();\n"); 81 | next(); 82 | } 83 | 84 | else if (!strcmp(cmd, "back")) { 85 | fprintf(toc, "back();\n"); 86 | back(); 87 | } 88 | 89 | else if ((cmd[0] == '!') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 90 | var_index = atoi(cmd+1); 91 | if (dataStack->top >= 0) { 92 | variables[var_index] = StackPop(&dataStack[which]); 93 | } 94 | else { 95 | fprintf(toc, "error(\"stack is empty!\")\n;"); 96 | } 97 | } 98 | 99 | else if ((cmd[0] == '&') && (strlen(cmd) > 1) && (cmd[1] >= '-') && (cmd[1] <= '9')) { 100 | var_index = atoi(cmd+1); 101 | //printf("ind: %d\n", var_index); 102 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", variables[var_index]); 103 | } 104 | 105 | else if (!strcmp(cmd, "pow")) { 106 | fprintf(toc, "powers(&dataStack[which]);\n"); 107 | } 108 | 109 | else if (!strcmp(cmd, "mod")) { 110 | fprintf(toc, "modulus(&dataStack[which]);"); 111 | } 112 | 113 | else if (!strcmp(cmd, "pi")) { 114 | fprintf(toc, "StackPush(&dataStack[which], %f);\n", M_PI); 115 | } 116 | 117 | else if (!strcmp(cmd, "tan")) { 118 | fprintf(toc, "tangent(&dataStack[which]);\n"); 119 | } 120 | 121 | else if (!strcmp(cmd, "sin")) { 122 | fprintf(toc, "sine(&dataStack[which]);\n"); 123 | } 124 | 125 | else if (!strcmp(cmd, "cos")) { 126 | fprintf(toc, "cosine(&dataStack[which]);\n"); 127 | } 128 | 129 | else if (!strcmp(cmd, "read")) { 130 | fprintf(toc, "userin(&dataStack[which]);\n"); 131 | } 132 | 133 | else if (!strcmp(cmd, ">")) { 134 | fprintf(toc, "gt(&dataStack[which]);\n"); 135 | } 136 | 137 | else if (!strcmp(cmd, "<")) { 138 | fprintf(toc, "lt(&dataStack[which]);\n"); 139 | } 140 | 141 | else if (!strcmp(cmd, "=")) { 142 | fprintf(toc, "eqeq(&dataStack[which]);\n"); 143 | } 144 | 145 | else if (!strcmp(cmd, "<=")) { 146 | fprintf(toc, "lteq(&dataStack[which]);\n"); 147 | } 148 | 149 | else if (!strcmp(cmd, ">=")) { 150 | fprintf(toc, "gteq(&dataStack[which]);\n"); 151 | } 152 | 153 | else if (!strcmp(cmd, "+")) { 154 | fprintf(toc, "plus(&dataStack[which]);\n"); 155 | } 156 | 157 | else if (!strcmp(cmd, "++")) { 158 | fprintf(toc, "plusplus(&dataStack[which]);\n"); 159 | } 160 | 161 | else if (!strcmp(cmd, "**")) { 162 | fprintf(toc, "mulmul(&dataStack[which]);\n"); 163 | } 164 | 165 | else if (!strcmp(cmd, ".")) { 166 | fprintf(toc, "showtop(&dataStack[which]);\n"); 167 | } 168 | 169 | else if (!strcmp(cmd, "*")) { 170 | fprintf(toc, "mul(&dataStack[which]);\n"); 171 | } 172 | 173 | else if (!strcmp(cmd, "dels")) { 174 | fprintf(toc, "delstack(&dataStack[which]);\n"); 175 | } 176 | 177 | else if (!strcmp(cmd, "show")) { 178 | fprintf(toc, "show(&dataStack[which]);\n"); 179 | } 180 | 181 | else if (!strcmp(cmd, "-")) { 182 | fprintf(toc, "sub(&dataStack[which]);\n"); 183 | } 184 | 185 | else if (!strcmp(cmd, "swap")) { 186 | fprintf(toc, "swap(&dataStack[which]);\n"); 187 | } 188 | 189 | else if (!strcmp(cmd, "dup")) { 190 | fprintf(toc, "duplicate(&dataStack[which], 0);\n"); 191 | } 192 | 193 | else if(!strcmp(cmd, "jump")) { 194 | fprintf(toc, "jump(&dataStack[which]);\n"); 195 | } 196 | 197 | else if (!strcmp(cmd, "range")) { 198 | fprintf(toc, "range(&dataStack[which]);\n"); 199 | } 200 | 201 | else if (!strcmp(cmd, "drop") || !strcmp(cmd, "pop")) { 202 | fprintf(toc, "drop(&dataStack[which], true);\n"); 203 | } 204 | 205 | else if (!strcmp(cmd, "over")) { 206 | fprintf(toc, "duplicate(&dataStack[which], 1);\n"); 207 | } 208 | 209 | else if (!strcmp(cmd, "wover")) { 210 | fprintf(toc, "duplicate(&dataStack[which], 2);\n"); 211 | } 212 | 213 | else if (!strcmp(cmd, "top")) { 214 | fprintf(toc, "StackPush(&dataStack[which], dataStack[which]->top);\n"); 215 | } 216 | 217 | else if (!strcmp(cmd, "outascii")) { 218 | fprintf(toc, "outascii(&charStack);\n"); 219 | } 220 | 221 | else if (!strcmp(cmd, "print")) { 222 | fprintf(toc, "allascii(&charStack);\n"); 223 | } 224 | 225 | else if (!strcmp(cmd, "/")) { 226 | fprintf(toc, "divide(&dataStack[which]);"); 227 | } 228 | 229 | //Prints total commands. Used with @tracker 230 | else if (!strcmp(cmd,"tot")) { 231 | fprintf(toc, "printf(\"tot: %d\n\");\n", cmds); 232 | } 233 | 234 | //Resets number of commands. Used with @tracker 235 | else if (!strcmp(cmd, "reset")) { 236 | fprintf(toc, "cmds = 0;\n"); 237 | } 238 | 239 | else if (!strcmp(cmd, "mv")) { 240 | a = StackPop(&dataStack[which]); 241 | next(); 242 | StackPush(&dataStack[which], a); 243 | } 244 | 245 | //Starting a loop. Interpreted as a word. Saves the index and control, starts saving words to evaluate later. 246 | else if (!strcmp(cmd, "[")) { 247 | if (dataStack->top < 1) { 248 | fprintf(toc, "error(\"not enough frames!\");\n"); 249 | } 250 | else { 251 | fprintf(toc, "loopStack->index = (int) StackPop(&dataStack[which]);\nloopStack->control = (int) StackPop(&dataStack[which]) + 1;\n"); 252 | } 253 | fprintf(toc, "loopStack->save = true;\n"); 254 | } 255 | 256 | //Pushes the index to the dataStack. 257 | else if (!strcmp(cmd, "i")) { 258 | fprintf(toc, "StackPush(&dataStack[which], loopStack->index);"); 259 | } 260 | 261 | //Increments the index, iterates over the commands if the index < control, otherwise resets the loopStack, and stops saving words. 262 | else if (strcmp(cmd, "]") == 0) { 263 | fprintf(toc, "loopStack->index += 1;\n"); 264 | //printf("ind %d\ncon %d\n", loopStack->index, loopStack->control); 265 | if (loopStack->index <= loopStack->control) { 266 | for (c = 0; c < loopStack->bufsize; c++) { 267 | //printf("%s\n", loopStack->buffer[c]); 268 | eval(dataStack, loopStack, list, loopStack->buffer[(int) c], toc, cons); 269 | } 270 | } 271 | else { 272 | fprintf(toc, "loopStack->index = 0;\nloopStack->control = 0;\nmemset(loopStack->buffer, '\\0', sizeof(loopStack->buffer) * RES_SIZE * DIM2);\nloopStack->bufsize = 0;\nloopStack->save = false;\n"); 273 | } 274 | } 275 | 276 | //If the command is unrecognized and not a mode setting. 277 | else { 278 | if ((cmd[0] != '@') && (cmd[0] != '#')) { 279 | fprintf(toc, "sprintf(msg, \"%s - unknown command!\");\n", cmd); 280 | fprintf(toc, "error(msg);\n"); 281 | } 282 | } 283 | 284 | //If in a loop, saves words. LOOK OUT. EVALUATES THE WORDS IN AN ENDLESS RECURSION. SAVES/EVALUATES THEN ADDS IT TO THE BUFFER. FIX! 285 | if (loopStack->save && strcmp(cmd, "[")) { 286 | fprintf(toc, "*loopStack->buffer[loopStack->bufsize++] = *cmd;\n"); 287 | } 288 | } 289 | 290 | //If not setting the mode, do whatever it is the modes do at the end of the eval() process. 291 | if (cmd[0] != '@') { 292 | if (is_enabled(list, "@transparent") && strcmp(cmd, "show") && strcmp(cmd, "tot") && strcmp(cmd, "reset") && strcmp(cmd, ".") && strcmp(cmd, "dels") && strcmp(cmd, "nil")) { 293 | fprintf(toc, "printf(\"%s | \");", cmd); 294 | fprintf(toc, "StackShow(&dataStack[which]);\n"); 295 | } 296 | if (is_enabled(list, "@tracker") && strcmp(cmd, "tot") && strcmp(cmd, "reset")) { 297 | fprintf(toc, "cmds++;\n"); 298 | } 299 | if (!is_enabled(list, "@tracker") && (cmds != 0)) { 300 | fprintf(toc, "cmds = 0;\n"); 301 | } 302 | } 303 | } 304 | 305 | //REPL 306 | int main(int argc, char *argv[]) { 307 | FILE *fp; 308 | FILE *toc; 309 | 310 | which = 0; 311 | 312 | //Initializing dataStack 313 | stackT dataStack[NUM_STACKS]; 314 | 315 | //Initializing loop stack 316 | loopstack loopStack; 317 | 318 | //Initializing modes list 319 | #include "structdef.h" 320 | loopStack.bufsize = 0; 321 | loopStack.save = false; 322 | 323 | for (a = 0; a < NUM_STACKS; a++) 324 | StackInit(&dataStack[(int) a], RES_SIZE); 325 | char cmd[DIM2] = "00"; 326 | char filepath[100]; 327 | cmds = 0; 328 | if (argc > 1) { 329 | if (str_in_arr(argc, argv, "-v") || str_in_arr(argc, argv, "--version")) { 330 | printf("%s %.1f on %s\n", PKGNAME, VERSION, OPSYS); 331 | exit(1); 332 | } 333 | fp = fopen(argv[1], "r"); 334 | sprintf(filepath, "%s.c", argv[1]); 335 | toc = fopen(filepath, "w+"); 336 | fprintf(toc, "#include \n"); 337 | if (fp != NULL) { 338 | while (fscanf(fp, "%s", cmd) != EOF) { 339 | eval(dataStack, &loopStack, list, cmd, toc, cons); 340 | } 341 | fclose(fp); 342 | fprintf(toc, "}"); 343 | fclose(toc); 344 | } 345 | else { 346 | printf("error: %s - no such file!\n", argv[1]); 347 | exit(1); 348 | } 349 | } 350 | return 0; 351 | } 352 | -------------------------------------------------------------------------------- /src/header.h: -------------------------------------------------------------------------------- 1 | double a, b, c, ind, con; 2 | #include "functions.h" 3 | #ifndef HEADER_H_ 4 | #define HEADER_H_ 5 | int cmds; 6 | 7 | int which; 8 | 9 | void next() { 10 | if (which < NUM_STACKS) which++; 11 | else which = 0; 12 | } 13 | 14 | void back() { 15 | if (which > 0) which--; 16 | else which = NUM_STACKS-1; 17 | } 18 | 19 | 20 | 21 | int main() { 22 | stackT dataStack[NUM_STACKS]; 23 | stackT charStack; 24 | //loopstack loopStack; 25 | //loopStack.bufsize = 0; 26 | //loopStack.save = false; 27 | for (cmds = 0; cmds < NUM_STACKS; cmds++) 28 | StackInit(&dataStack[NUM_STACKS], RES_SIZE); 29 | StackInit(&charStack, RES_SIZE); 30 | char cmd[DIM2] = "00"; 31 | cmds = 0; 32 | char msg[30]; 33 | 34 | which = 0; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/objects.h: -------------------------------------------------------------------------------- 1 | typedef enum {CHAR, BOOLEAN, FIXNUM, SYMBOL, EOF_OBJECT} object_type; 2 | 3 | typedef struct object { 4 | object_type type; 5 | union { 6 | struct { 7 | char value; 8 | } boolean; 9 | struct { 10 | char *value; 11 | } symbol; 12 | struct { 13 | char value; 14 | } character; 15 | struct { 16 | double value; 17 | } fixnum; 18 | struct { 19 | struct object *(*fn)(struct object *arguments); 20 | } procedure; 21 | } data; 22 | } object; 23 | 24 | typedef struct { 25 | object table[50]; 26 | int top; 27 | int max; 28 | } obj_table; 29 | 30 | object *alloc_object(void) { 31 | object *obj; 32 | 33 | obj = malloc(sizeof(object)); 34 | if (obj == NULL) { 35 | printf("out of memory\n") 36 | exit(1); 37 | } 38 | return obj; 39 | } 40 | 41 | object *tt; 42 | object *ff; 43 | obj_table symbol_table; 44 | object *set_symbol; 45 | object *get_symbol; 46 | 47 | char is_bool(object *obj) { 48 | return obj->type = BOOLEAN; 49 | } 50 | 51 | char is_false(object *obj) { 52 | return obj == ff; 53 | } 54 | 55 | char is_true(object *obj) { 56 | return !is_false(obj); 57 | } 58 | 59 | object make_symbol(char *value) { 60 | object *obj; 61 | obj = alloc_object(); 62 | obj->type = SYMBOL; 63 | obj->data.symbol.value = malloc(strlen(value) + 1); 64 | if (symbol_table.top == symbol_table.max) { 65 | printf("too many symbols\n"); 66 | exit(1); 67 | } 68 | symbol_table[symbol_table.top] = obj; 69 | symbol_table.top++; 70 | return obj; 71 | } 72 | 73 | char is_symbol(object *obj) { 74 | return obj->type == SYMBOL; 75 | } 76 | 77 | object *make_fixnum(double value) { 78 | object *obj; 79 | obj = alloc_object(); 80 | obj->type = FIXNUM; 81 | obj->data.fixnum.value = value; 82 | return object; 83 | } 84 | 85 | char is_fixnum(object *obj) { 86 | return obj->type == FIXNUM; 87 | } 88 | 89 | object *make_character(char value) { 90 | object *obj; 91 | obj = alloc_object(); 92 | obj->type = CHARACTER; 93 | obj->data.character.value = value; 94 | return obj; 95 | } 96 | 97 | char is_character(object *obj) { 98 | return object->type == CHARACTER; 99 | } 100 | 101 | object *add_proc(object *arg0, object *arg1) { 102 | return make_fixnum(arg0.fixnum.value+arg1.fixnum.value); 103 | } 104 | 105 | object *sub_proc(object *arg0, object *arg1) { 106 | return make_fixnum(arg0.fixnum.value-arg1.fixnum.value); 107 | } 108 | 109 | object mul_proc(object *arg0, object *arg2) { 110 | return make_fixnum(arg0.fixnum.value*arg1.fixnum.value); 111 | } 112 | 113 | object div_proc(object *arg0, object *arg2) { 114 | return make_fixnum(arg0.fixnum.value/arg2.fixnum.value); 115 | } 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/oo.h: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | 3 | typedef enum Object_type {BOOLEAN, FIXNUM, SYMBOL, EOF_OBJ}; 4 | 5 | typedef struct Object { 6 | Oject_type type; 7 | union { 8 | struct { 9 | 10 | }; 11 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | #include "structs.h" 2 | #ifndef STACK_H_ 3 | #define STACK_H_ 4 | 5 | int which; 6 | 7 | //Stack struct. 8 | typedef struct { 9 | double *contents; 10 | int maxSize; 11 | int top; 12 | } stackT; 13 | 14 | //Initializes the stack, checking for enough memory. 15 | void StackInit(stackT *stackP, int maxSize) { 16 | double *newContents; 17 | newContents = (double *)malloc(sizeof(double)*maxSize); 18 | if (newContents == NULL) { 19 | fprintf(stderr, "Not enough memory.\n"); 20 | exit(1); 21 | } 22 | stackP->contents = newContents; 23 | stackP->maxSize = maxSize; 24 | stackP->top = -1; 25 | } 26 | 27 | //Destroys the stack and frees the allocated memory. 28 | void StackDestroy(stackT *stackP) { 29 | free(stackP->contents); 30 | stackP->contents = NULL; 31 | stackP->maxSize = 0; 32 | stackP->top = -1; 33 | } 34 | 35 | //Checks if the stack is empty. 36 | int StackIsEmpty(stackT *stackP) { 37 | return stackP->top < 0; 38 | } 39 | 40 | //Checks if the stack is full. 41 | int StackIsFull(stackT *stackP) { 42 | return stackP->top >= stackP->maxSize-1; 43 | } 44 | 45 | //Pushes a number onto the stack. 46 | void StackPush(stackT *stackP, double element) { 47 | if(StackIsFull(stackP)) { 48 | fprintf(stderr, "Can't push element: stack is full.\n"); 49 | exit(1); 50 | } 51 | stackP->contents[++stackP->top] = element; 52 | } 53 | 54 | //Pops a number from the stack. 55 | double StackPop(stackT *stackP) { 56 | if(StackIsEmpty(stackP)) { 57 | fprintf(stderr, "Can't pop element: stack is empty.\n"); 58 | exit(1); 59 | } 60 | return stackP->contents[stackP->top--]; 61 | } 62 | 63 | //Pretty-prints the stack. 64 | void StackShow(stackT *stackP) { 65 | if (stackP->top == -1) { 66 | printf(BLUE "%d" PURPLE " [ ]\n" DEFAULT, which); 67 | } 68 | else if (stackP->top == 0) { 69 | printf(BLUE "%d" PURPLE " [ %.2f ]\n" DEFAULT, which, stackP->contents[0]); 70 | } 71 | else if (stackP->top > 0) { 72 | int i; 73 | printf(BLUE "%d" PURPLE " [ ", which); 74 | for (i = 0; i < stackP->top; i++) { 75 | printf("%.2f, ", stackP->contents[i]); 76 | } 77 | printf("%.2f ]\n" DEFAULT, stackP->contents[stackP->top]); 78 | } 79 | } 80 | 81 | void StackShowVert(stackT *stackP) { 82 | if (stackP->top == -1) { 83 | printf("-top-\n-end-\n"); 84 | } 85 | else if (stackP->top == 0) { 86 | printf("-top-\n%.2f\n-end-\n", stackP->contents[0]); 87 | } 88 | else if (stackP->top > 0) { 89 | int i; 90 | printf("-top-\n"); 91 | for (i = stackP->top; i >= 0; i--) { 92 | printf("%.2f\n", stackP->contents[i]); 93 | } 94 | printf("-end-\n"); 95 | } 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/structdef.h: -------------------------------------------------------------------------------- 1 | #ifndef STRUCTDEF_H_ 2 | #define STRUCTDEF_H_ 3 | mode list[] = { 4 | {"@default", true}, 5 | {"@transparent", false}, 6 | {"@tracker", false}, 7 | }; 8 | 9 | const_list cons[] = { 10 | {"#t", 1}, 11 | {"#true", 1}, 12 | {"#f", 0}, 13 | {"#false", 0}, 14 | {"#pi", M_PI}, 15 | {"#e", M_E}, 16 | {"#phi", M_PHI}, 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/structs.h: -------------------------------------------------------------------------------- 1 | #include "usefunc.h" 2 | #ifndef STRUCTS_H_ 3 | #define STRUCTS_H_ 4 | 5 | //Booleans are useful. 6 | typedef enum { 7 | false, true 8 | } bool; 9 | 10 | //Has an index, control, and can hold all the commands passed inside a loop. 11 | typedef struct { 12 | int index; 13 | int control; 14 | int bufsize; 15 | char buffer[RES_SIZE][DIM2]; 16 | bool save; 17 | } loopstack; 18 | 19 | //Mode string and an enabled flag. This language makes good use of a modes table. 20 | typedef struct { 21 | char mode[DIM2]; 22 | bool enabled; 23 | } mode; 24 | 25 | //Constants! 26 | typedef struct { 27 | char name[DIM2]; 28 | double value; 29 | } const_list; 30 | 31 | //Flag values :) 32 | typedef struct { 33 | int help; 34 | int version; 35 | int eval; 36 | int shell; 37 | int f; 38 | char *fn; 39 | } flags; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/usefunc.h: -------------------------------------------------------------------------------- 1 | #ifndef USEFUNC_H 2 | #define USEFUNC_H 3 | 4 | #include 5 | //#include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #define YELLOW "\e[1;33m" 17 | #define PURPLE "\e[1;35m" 18 | #define BLUE "\e[1;34m" 19 | #define RED "\e[1;31m" 20 | #define DEFAULT "\e[0m" 21 | 22 | #ifndef M_PI 23 | #define M_PI 3.1415926535897932384626433832795028 24 | #endif 25 | 26 | #ifndef M_PHI 27 | #define M_PHI 1.618033988749894848204586834365638 28 | #endif 29 | 30 | #ifndef M_E 31 | #define M_E 2.71828182845904523536028747135266249 32 | #endif 33 | 34 | #define DIM2 30 35 | #define RES_SIZE 100000 36 | #define VAR_SIZE 100 37 | #define NUM_STACKS 5 38 | 39 | #define MODETOP 3 40 | #define CONSTOP 7 41 | 42 | #ifdef __unix__ 43 | #define OPSYS "Unix" 44 | #endif 45 | 46 | #ifdef __APPLE__ 47 | #define OPSYS "Mac OS X" 48 | #endif 49 | 50 | #ifndef OPSYS 51 | #define OPSYS "unsupported system" 52 | #endif 53 | 54 | #endif 55 | --------------------------------------------------------------------------------