Name: Anonymous 2018-03-02 17:21
I'd like to anally deform brains of web developers with a new concatenative server-side framework. it will be called Backend Forth
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
//needs -lm flag to compile, i.e, gcc stack.c -o stack -lm
//to do: make it read from stdin if no file argument is provided, and read from the specified file otherwise - this would solve the "*" expansion bug
#define modulo(A, B) (A - B * floor(A / B))
double stack[1024];
int pointer = 0;
int main(int argc, char * argv[]){
double aux = 0;
double aux2 = 0;
double aux3 = 0;
for (int i = 1; i < argc; i++){
//+ - * /
if (!strcmp(argv[i], "add") || !strcmp(argv[i], "+")){
if (pointer >= 2){
stack[pointer-2] += stack[pointer-1];
pointer -= 1;
}
}
else if (!strcmp(argv[i], "sub") || !strcmp(argv[i], "-")){
if (pointer >= 2){
stack[pointer-2] -= stack[pointer-1];
pointer -= 1;
}
} else if (!strcmp(argv[i], "mul") || !strcmp(argv[i], "*")){ //bash treats "*" as special character...
if (pointer >= 2){
stack[pointer-2] *= stack[pointer-1];
pointer -= 1;
}
} else if (!strcmp(argv[i], "div") || !strcmp(argv[i], "/")){
if (pointer >= 2){
stack[pointer-2] /= stack[pointer-1];
pointer -= 1;
}
} else if (!strcmp(argv[i], "expt") || !strcmp(argv[i], "pow") || !strcmp(argv[i], "^")){
if (pointer >= 2){
stack[pointer-2] = pow(stack[pointer-2], stack[pointer-1]);
pointer -= 1;
}
} else if (!strcmp(argv[i], "sum")){ //sum everything in the stack
aux = 0; //accumulator
for (int j = pointer-1; j>=0; j--){
aux += stack[j];
}
stack[0] = aux;
pointer = 1;
} else if (!strcmp(argv[i], "prod")){ //multiply everything in the stack
aux = 1;
for (int j = pointer-1; j>=0; j--){
aux *= stack[j];
}
stack[0] = aux;
pointer = 1;
} else if (!strcmp(argv[i], "%") || !strcmp(argv[i], "mod")){
if (pointer >= 2){
stack[pointer-2] = modulo(stack[pointer-2], stack[pointer-1]);
}
} else if (!strcmp(argv[i], "neg")){
if (pointer >= 1){
stack[pointer-1] = - stack[pointer-1];
}
} else if (!strcmp(argv[i], "abs")){
if (pointer >= 1){
stack[pointer-1] = fabs(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "floor")){
if (pointer >= 1){
stack[pointer-1] = floor(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "ceil")){
if (pointer >= 1){
stack[pointer-1] = ceil(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "round")){
if (pointer >= 1){
stack[pointer-1] = round(stack[pointer-1]);
}
}
//sqrt is useful to have as a separate word
else if (!strcmp(argv[i], "sqrt")){
if (pointer >= 1){
stack[pointer-1] = pow(stack[pointer-1], 0.5);
}
}
//trigonometric functions, sin, cos, tan, csc, sec, cot, pi and arc functions
else if (!strcmp(argv[i], "sin")){
if (pointer >= 1){
stack[pointer-1] = sin(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "cos")){
if (pointer >= 1){
stack[pointer-1] = cos(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "tan")){
if (pointer >= 1){
stack[pointer-1] = tan(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "csc")){
if (pointer >= 1){
stack[pointer-1] = 1/sin(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "sec")){
if (pointer >= 1){
stack[pointer-1] = 1/cos(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "cot")){
if (pointer >= 1){
stack[pointer-1] = 1/tan(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "pi")){
stack[pointer] = 3.1415926536;
pointer += 1;
} else if (!strcmp(argv[i], "asin")){
if (pointer >= 1){
stack[pointer-1] = asin(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "acos")){
if (pointer >= 1){
stack[pointer-1] = acos(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "atan")){
if (pointer >= 1){
stack[pointer-1] = atan(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "acsc")){
if (pointer >= 1){
stack[pointer-1] = asin(1/stack[pointer-1]);
}
} else if (!strcmp(argv[i], "asec")){
if (pointer >= 1){
stack[pointer-1] = acos(1/stack[pointer-1]);
}
} else if (!strcmp(argv[i], "acot")){
if (pointer >= 1){
stack[pointer-1] = atan(1/stack[pointer-1]);
}
}
//log10 (alias log), ln, and log(a,b) (alias logb)
else if (!strcmp(argv[i], "ln")){
if (pointer >= 1){
stack[pointer-1] = log(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "log") || !strcmp(argv[i], "log10")){
if (pointer >= 1){
stack[pointer-1] = log10(stack[pointer-1]);
}
} else if (!strcmp(argv[i], "logb")){
if (pointer >= 2){
stack[pointer-2] = log(stack[pointer-2])/log(stack[pointer-1]);
pointer -= 1;
}
} else if (!strcmp(argv[i], "log2")){
if (pointer >= 1){
stack[pointer-1] = log(stack[pointer-1])/log(2);
}
} else if (!strcmp(argv[i], "e")){
stack[pointer] = 2.7182818285;
pointer += 1;
} else if (!strcmp(argv[i], "exp")){
if (pointer >= 1){
stack[pointer-1] = pow(2.7182818285, stack[pointer-1]);
}
} else if (!strcmp(argv[i], "dup")){
if (pointer >= 1){
stack[pointer] = stack[pointer-1];
pointer += 1;
}
} else if (!strcmp(argv[i], "exch") || !strcmp(argv[i], "swap")){
if (pointer >= 2){
aux = stack[pointer-2];
stack[pointer-2] = stack[pointer-1];
stack[pointer-1] = aux;
}
} else if (!strcmp(argv[i], "drop") || !strcmp(argv[i], "pop")){
if (pointer >= 1){
pointer -= 1;
}
} else if (!strcmp(argv[i], "clear")){
pointer = 0;
} else if (!strcmp(argv[i], "copy")){
//this operator adds a copy of the top n objects on the stack
if (pointer >= 1){
aux = floor(stack[pointer-1]);
pointer -= 1;
for (int j=pointer-aux;j < pointer;j++){
stack[(int) (j+aux)] = stack[j];
}
pointer += aux;
}
}
//eq, neq, gt, lt, or, and, not
//there are no anonymous functions currently, and the stack only accepts double
//ift (if-then), ifte (if-then-else), without interpretation of code
else if (!strcmp(argv[i], "eq") || !strcmp(argv[i], "==")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] == stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "neq") || !strcmp(argv[i], "!=")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] != stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "gt") || !strcmp(argv[i], ">")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] > stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "lt") || !strcmp(argv[i], "<")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] < stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "gte") || !strcmp(argv[i], ">=")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] >= stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "lte") || !strcmp(argv[i], "<=")){
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] <= stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "or")){
if (pointer >= 2){
stack[pointer-2] = ((stack[pointer-2] != 0) || (stack[pointer-1] != 0)) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "and")){
if (pointer >= 2){
stack[pointer-2] = ((stack[pointer-2] != 0) && (stack[pointer-1] != 0)) ? 1 : 0;
pointer -= 1;
}
} else if (!strcmp(argv[i], "not")){
if (pointer >= 1){
stack[pointer-1] = (stack[pointer-1] == 0) ? 1 : 0;
}
} else if (!strcmp(argv[i], "ift") || !strcmp(argv[i], "if-then")){
if (pointer >= 2){
aux = stack[pointer-2];
stack[pointer-2] = stack[pointer-1];
pointer -= (aux != 0) ? 1 : 2;
}
} else if (!strcmp(argv[i], "ifte") || !strcmp(argv[i], "if-then-else")){
if (pointer >= 3){
stack[pointer-3] = (stack[pointer-3] != 0) ? stack[pointer-2] : stack[pointer-1];
pointer -= 2;
}
}
//xor, iff (not bitwise, since these are doubles)
else if (!strcmp(argv[i], "xor")){
if (pointer >= 2){
stack[pointer-2] = (((stack[pointer-2] != 0) && (stack[pointer-1] == 0)) || ((stack[pointer-2] == 0) && (stack[pointer-1] != 0)))
? 1 : 0;
pointer -= 1;
//I think this could be done with a simple "!="
}
} else if (!strcmp(argv[i], "iff")){
if (pointer >= 2){
stack[pointer-2] = (((stack[pointer-2] != 0) && (stack[pointer-1] != 0)) || ((stack[pointer-2] == 0) && (stack[pointer-1] == 0)))
? 1 : 0;
pointer -= 1;
}
}
//roll, rot, over,
else if (!strcmp(argv[i], "over")){
if (pointer >= 2){
stack[pointer] = stack[pointer-2];
pointer += 1;
}
} else if (!strcmp(argv[i], "rot")){
//rot transforms the top three stack values from (a b c) to (b c a), i.e. shift left
if (pointer >= 3){
aux = stack[pointer-3];
for (int j = pointer-3; j < pointer-1; j++){
stack[j] = stack[j+1];
}
stack[pointer-1] = aux;
}
} else if (!strcmp(argv[i], "roll")){
//m n roll : rotate n times (shift right), but not the whole stack, only the top m
if (pointer >= 2){
aux = floor(fmax(fmin(stack[pointer-2],pointer),2)); //m
aux2 = floor(stack[pointer-1]); //n
aux2 = (aux2 < 0) ? aux - modulo(abs(aux2), aux) : aux2;
pointer -= 2;
while (aux2 > 0){
aux3 = stack[pointer-1];
for (int j = pointer-1; j > pointer-aux; j--){
stack[j] = stack[j-1];
}
stack[(int) (pointer-aux)] = aux3;
aux2--;
}
}
}
else if (!strcmp(argv[i], "index")){
//n index
if (pointer >= 1){
aux = floor(stack[pointer-1]);
pointer -= 1;
if (pointer >= aux){
stack[pointer] = stack[(int) (pointer-aux)];
pointer += 1;
}
}
}
//might be able to implement map, reduce/fold and filter once I have blocks working
else if (!strcmp(argv[i], "stack")){
//print the whole stack, from top to bottom
for (int j = pointer-1; j >= 0; j--){
printf("%f\n", stack[j]);
}
} else if (!strcmp(argv[i], "=")){
//remove the topmost object from the stack and print it
if (pointer >= 1){
printf("%f\n", stack[pointer-1]);
pointer -= 1;
}
}
//count
//e.g. count 0 eq
//while? for? repeat? they all need blocks (which will later be implemented as lists on a stack of lists)
else if (!strcmp(argv[i], "count")){
stack[pointer] = pointer;
pointer += 1;
} else {
stack[pointer] = (double) atof(argv[i]);
pointer = pointer + 1;
//if pointer > 1023 ...
}
}
//print the stack
for (int i = pointer-1; i >= 0; i--){
printf("%f\n", stack[i]);
}
return 0;
}
You can't switch on char * strings, though.which should be a clue that what you're doing isn't the right way.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
//needs -lm flag to compile, i.e, gcc stack.c -o stack -lm
//to do: make it read from stdin if no file argument is provided, and read from the specified file otherwise - this would solve the "*" expansion bug
//hash for switch statement
unsigned long hash(char * s){
unsigned long acc = 0;
unsigned long weight = 1;
while (*s != '\0'){
acc += (*s) * (weight);
weight *= 256;
s++;
}
return acc;
}
#define _add 6579297
#define _plussign 43 //+
#define _sub 6452595
#define _minussign 45 //-
#define _mul 7107949
#define _starsign 42 //*
#define _div 7760228
#define _divisionsign 47 //'/'
#define _expt 1953527909
#define _pow 7827312
#define _hatsign 94 //^
#define _sum 7173491
#define _prod 1685025392
#define _mod 6582125
#define _percentsign 37 //%
#define _neg 6776174
#define _abs 7561825
#define _floor 491495844966
#define _ceil 1818846563
#define _round 431349919602
#define _sqrt 1953657203
#define _sin 7235955
#define _cos 7565155
#define _tan 7233908
#define _csc 6517603
#define _sec 6514035
#define _cot 7630691
#define _pi 26992
#define _asin 1852404577
#define _acos 1936679777
#define _atan 1851880545
#define _acsc 1668506465
#define _asec 1667593057
#define _acot 1953456993
#define _ln 28268
#define _log 6778732
#define _log10 206987292524
#define _logb 1650945900
#define _log2 845639532
#define _e 101
#define _exp 7370853
#define _dup 7370084
#define _exch 1751349349
#define _swap 1885435763
#define _drop 1886351972
#define _pop 7368560
#define _clear 491260308579
#define _copy 2037411683
#define _eq 29029
#define _doubleequalsign 15677 //==
#define _neq 7431534
#define _shriekequalsign 15649 //!=
#define _gt 29799
#define _greaterthansign 62 //>
#define _lt 29804
#define _lessthansign 60 //<
#define _gte 6648935
#define _greaterthanequalsign 15678 //>=
#define _lte 6648940
#define _lessthanequalsign 15676 //<=
#define _or 29295
#define _and 6581857
#define _not 7630702
#define _ift 7628393
#define _if_then 31073746738308713 //if-then
#define _ifte 1702127209
#define _if_then_else 3273665478445065833 //if-then-else
#define _xor 7499640
#define _iff 6710889
#define _over 1919252079
#define _rot 7630706
#define _roll 1819045746
#define _index 517097156201
#define _stack 461228831859
#define _equalsign 61 //=
#define _count 500069396323
double stack[1024];
int pointer = 0;
int main(int argc, char * argv[]){
double aux = 0;
double aux2 = 0;
double aux3 = 0;
for (int i = 1; i < argc; i++){
//+ - * /
//testing switch
switch (hash(argv[i])){
case _add:
case _plussign:
if (pointer >= 2){
stack[pointer-2] += stack[pointer-1];
pointer -= 1;
}
break;
case _sub:
case _minussign:
if (pointer >= 2){
stack[pointer-2] -= stack[pointer-1];
pointer -= 1;
}
break;
case _mul:
case _starsign: //bash treats "*" as special character...
if (pointer >= 2){
stack[pointer-2] *= stack[pointer-1];
pointer -= 1;
}
break;
case _div:
case _divisionsign:
if (pointer >= 2){
stack[pointer-2] /= stack[pointer-1];
pointer -= 1;
}
break;
case _expt:
case _pow:
case _hatsign:
if (pointer >= 2){
stack[pointer-2] = pow(stack[pointer-2], stack[pointer-1]);
pointer -= 1;
}
break;
case _sum: //sum everything in the stack
aux = 0; //accumulator
for (int j = pointer-1; j>=0; j--){
aux += stack[j];
}
stack[0] = aux;
pointer = 1;
break;
case _prod: //multiply everything in the stack
aux = 1;
for (int j = pointer-1; j>=0; j--){
aux *= stack[j];
}
stack[0] = aux;
pointer = 1;
break;
case _percentsign:
case _mod:
if (pointer >= 2){
stack[pointer-2] = fmod(stack[pointer-2], stack[pointer-1]);
}
break;
case _neg:
if (pointer >= 1){
stack[pointer-1] = - stack[pointer-1];
}
break;
case _abs:
if (pointer >= 1){
stack[pointer-1] = fabs(stack[pointer-1]);
}
break;
case _floor:
if (pointer >= 1){
stack[pointer-1] = floor(stack[pointer-1]);
}
break;
case _ceil:
if (pointer >= 1){
stack[pointer-1] = ceil(stack[pointer-1]);
}
break;
case _round:
if (pointer >= 1){
stack[pointer-1] = round(stack[pointer-1]);
}
break;
//sqrt is useful to have as a separate word
case _sqrt:
if (pointer >= 1){
stack[pointer-1] = pow(stack[pointer-1], 0.5);
}
break;
//trigonometric functions, sin, cos, tan, csc, sec, cot, pi and arc functions
case _sin:
if (pointer >= 1){
stack[pointer-1] = sin(stack[pointer-1]);
}
break;
case _cos:
if (pointer >= 1){
stack[pointer-1] = cos(stack[pointer-1]);
}
break;
case _tan:
if (pointer >= 1){
stack[pointer-1] = tan(stack[pointer-1]);
}
break;
case _csc:
if (pointer >= 1){
stack[pointer-1] = 1/sin(stack[pointer-1]);
}
break;
case _sec:
if (pointer >= 1){
stack[pointer-1] = 1/cos(stack[pointer-1]);
}
break;
case _cot:
if (pointer >= 1){
stack[pointer-1] = 1/tan(stack[pointer-1]);
}
break;
case _pi:
stack[pointer] = 3.1415926536;
pointer += 1;
break;
case _asin:
if (pointer >= 1){
stack[pointer-1] = asin(stack[pointer-1]);
}
break;
case _acos:
if (pointer >= 1){
stack[pointer-1] = acos(stack[pointer-1]);
}
break;
case _atan:
if (pointer >= 1){
stack[pointer-1] = atan(stack[pointer-1]);
}
break;
case _acsc:
if (pointer >= 1){
stack[pointer-1] = asin(1/stack[pointer-1]);
}
break;
case _asec:
if (pointer >= 1){
stack[pointer-1] = acos(1/stack[pointer-1]);
}
break;
case _acot:
if (pointer >= 1){
stack[pointer-1] = atan(1/stack[pointer-1]);
}
break;
//log10 (alias log), ln, and log(a,b) (alias logb)
case _ln:
if (pointer >= 1){
stack[pointer-1] = log(stack[pointer-1]);
}
break;
case _log:
case _log10:
if (pointer >= 1){
stack[pointer-1] = log10(stack[pointer-1]);
}
break;
case _logb:
if (pointer >= 2){
stack[pointer-2] = log(stack[pointer-2])/log(stack[pointer-1]);
pointer -= 1;
}
break;
case _log2:
if (pointer >= 1){
stack[pointer-1] = log(stack[pointer-1])/log(2);
}
break;
case _e:
stack[pointer] = 2.7182818285;
pointer += 1;
break;
case _exp: //exp usually supports complex numbers...
if (pointer >= 1){
stack[pointer-1] = pow(2.7182818285, stack[pointer-1]);
}
break;
case _dup:
if (pointer >= 1){
stack[pointer] = stack[pointer-1];
pointer += 1;
}
break;
case _exch:
case _swap:
if (pointer >= 2){
aux = stack[pointer-2];
stack[pointer-2] = stack[pointer-1];
stack[pointer-1] = aux;
}
break;
case _drop:
case _pop:
if (pointer >= 1){
pointer -= 1;
}
break;
case _clear:
pointer = 0;
break;
case _copy:
//this operator adds a copy of the top n objects on the stack
if (pointer >= 1){
aux = floor(stack[pointer-1]);
pointer -= 1;
for (int j=pointer-aux;j < pointer;j++){
stack[(int) (j+aux)] = stack[j];
}
pointer += aux;
}
break;
//eq, neq, gt, lt, or, and, not
//there are no anonymous functions currently, and the stack only accepts double
//ift (if-then), ifte (if-then-else), without interpretation of code
case _eq:
case _doubleequalsign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] == stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _neq:
case _shriekequalsign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] != stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _gt:
case _greaterthansign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] > stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _lt:
case _lessthansign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] < stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _gte:
case _greaterthanequalsign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] >= stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _lte:
case _lessthanequalsign:
if (pointer >= 2){
stack[pointer-2] = (stack[pointer-2] <= stack[pointer-1]) ? 1 : 0;
pointer -= 1;
}
break;
case _or:
if (pointer >= 2){
stack[pointer-2] = ((stack[pointer-2] != 0) || (stack[pointer-1] != 0)) ? 1 : 0;
pointer -= 1;
}
break;
case _and:
if (pointer >= 2){
stack[pointer-2] = ((stack[pointer-2] != 0) && (stack[pointer-1] != 0)) ? 1 : 0;
pointer -= 1;
}
break;
case _not:
if (pointer >= 1){
stack[pointer-1] = (stack[pointer-1] == 0) ? 1 : 0;
}
break;
case _ift:
case _if_then:
if (pointer >= 2){
aux = stack[pointer-2];
stack[pointer-2] = stack[pointer-1];
pointer -= (aux != 0) ? 1 : 2;
}
break;
case _ifte:
case _if_then_else:
if (pointer >= 3){
stack[pointer-3] = (stack[pointer-3] != 0) ? stack[pointer-2] : stack[pointer-1];
pointer -= 2;
}
break;
//xor, iff (not bitwise, since these are doubles)
case _xor:
if (pointer >= 2){
stack[pointer-2] = (((stack[pointer-2] != 0) && (stack[pointer-1] == 0)) || ((stack[pointer-2] == 0) && (stack[pointer-1] != 0)))
? 1 : 0;
pointer -= 1;
//I think this could be done with a simple "!="
}
break;
case _iff:
if (pointer >= 2){
stack[pointer-2] = (((stack[pointer-2] != 0) && (stack[pointer-1] != 0)) || ((stack[pointer-2] == 0) && (stack[pointer-1] == 0)))
? 1 : 0;
pointer -= 1;
}
break;
//roll, rot, over,
case _over:
if (pointer >= 2){
stack[pointer] = stack[pointer-2];
pointer += 1;
}
break;
case _rot:
//rot transforms the top three stack values from (a b c) to (b c a), i.e. shift left
if (pointer >= 3){
aux = stack[pointer-3];
for (int j = pointer-3; j < pointer-1; j++){
stack[j] = stack[j+1];
}
stack[pointer-1] = aux;
}
break;
case _roll:
//m n roll : rotate n times (shift right), but not the whole stack, only the top m
if (pointer >= 2){
aux = floor(fmax(fmin(stack[pointer-2],pointer),2)); //m
aux2 = floor(stack[pointer-1]); //n
aux2 = (aux2 < 0) ? aux - fmod(abs(aux2), aux) : aux2;
pointer -= 2;
while (aux2 > 0){
aux3 = stack[pointer-1];
for (int j = pointer-1; j > pointer-aux; j--){
stack[j] = stack[j-1];
}
stack[(int) (pointer-aux)] = aux3;
aux2--;
}
}
break;
case _index:
//n index
if (pointer >= 1){
aux = floor(stack[pointer-1]);
pointer -= 1;
if (pointer >= aux){
stack[pointer] = stack[(int) (pointer-aux)];
pointer += 1;
}
}
break;
//might be able to implement map, reduce/fold and filter once I have blocks working
case _stack:
//print the whole stack, from top to bottom
for (int j = pointer-1; j >= 0; j--){
printf("%f\n", stack[j]);
}
case _equalsign:
//remove the topmost object from the stack and print it
if (pointer >= 1){
printf("%f\n", stack[pointer-1]);
pointer -= 1;
}
break;
//count
//e.g. count 0 eq
//while? for? repeat? they all need blocks (which will later be implemented as lists on a stack of lists)
case _count:
stack[pointer] = pointer;
pointer += 1;
break;
default:
stack[pointer] = (double) atof(argv[i]);
pointer = pointer + 1;
//if pointer > 1023 ...
}
}
//print the stack
for (int i = pointer-1; i >= 0; i--){
printf("%f\n", stack[i]);
}
return 0;
}
./stack main.stk
cat main.stk | ./stack
-//to do: make it read from stdin if no file argument is provided, and read from the specified file otherwise - this would solve the "*" expansion bug
-#define _add 6579297
-#define _plussign 43 //+
-#define _sub 6452595
-#define _minussign 45 //-
-#define _mul 7107949
-#define _starsign 42 //*
-#define _div 7760228
-#define _divisionsign 47 //'/'
-#define _expt 1953527909
-#define _pow 7827312
-#define _hatsign 94 //^
-#define _sum 7173491
-#define _prod 1685025392
-#define _mod 6582125
-#define _percentsign 37 //%
-#define _neg 6776174
-#define _abs 7561825
-#define _floor 491495844966
-#define _ceil 1818846563
-#define _round 431349919602
-#define _sqrt 1953657203
-#define _sin 7235955
-#define _cos 7565155
-#define _tan 7233908
-#define _csc 6517603
-#define _sec 6514035
-#define _cot 7630691
-#define _pi 26992
-#define _asin 1852404577
-#define _acos 1936679777
-#define _atan 1851880545
-#define _acsc 1668506465
-#define _asec 1667593057
-#define _acot 1953456993
-#define _ln 28268
-#define _log 6778732
-#define _log10 206987292524
-#define _logb 1650945900
-#define _log2 845639532
-#define _e 101
-#define _exp 7370853
-#define _dup 7370084
-#define _exch 1751349349
-#define _swap 1885435763
-#define _drop 1886351972
-#define _pop 7368560
-#define _clear 491260308579
-#define _copy 2037411683
-#define _eq 29029
-#define _doubleequalsign 15677 //==
-#define _neq 7431534
-#define _shriekequalsign 15649 //!=
-#define _gt 29799
-#define _greaterthansign 62 //>
-#define _lt 29804
-#define _lessthansign 60 //<
-#define _gte 6648935
-#define _greaterthanequalsign 15678 //>=
-#define _lte 6648940
-#define _lessthanequalsign 15676 //<=
-#define _or 29295
-#define _and 6581857
-#define _not 7630702
-#define _ift 7628393
-#define _if_then 31073746738308713 //if-then
-#define _ifte 1702127209
-#define _if_then_else 3273665478445065833 //if-then-else
-#define _xor 7499640
-#define _iff 6710889
-#define _over 1919252079
-#define _rot 7630706
-#define _roll 1819045746
-#define _index 517097156201
-#define _stack 461228831859
-#define _equalsign 61 //=
-#define _count 500069396323
+#define _add 6579297UL
+#define _plussign 43UL //+
+#define _sub 6452595UL
+#define _minussign 45UL //-
+#define _mul 7107949UL
+#define _starsign 42UL //*
+#define _div 7760228UL
+#define _divisionsign 47UL //'/'
+#define _expt 1953527909UL
+#define _pow 7827312UL
+#define _hatsign 94UL //^
+#define _sum 7173491UL
+#define _prod 1685025392UL
+#define _mod 6582125UL
+#define _percentsign 37UL //%
+#define _neg 6776174UL
+#define _abs 7561825UL
+#define _floor 491495844966UL
+#define _ceil 1818846563UL
+#define _round 431349919602UL
+#define _sqrt 1953657203UL
+#define _sin 7235955UL
+#define _cos 7565155UL
+#define _tan 7233908UL
+#define _csc 6517603UL
+#define _sec 6514035UL
+#define _cot 7630691UL
+#define _pi 26992UL
+#define _asin 1852404577UL
+#define _acos 1936679777UL
+#define _atan 1851880545UL
+#define _acsc 1668506465UL
+#define _asec 1667593057UL
+#define _acot 1953456993UL
+#define _ln 28268UL
+#define _log 6778732UL
+#define _log10 206987292524UL
+#define _logb 1650945900UL
+#define _log2 845639532UL
+#define _e 101UL
+#define _exp 7370853UL
+#define _dup 7370084UL
+#define _exch 1751349349UL
+#define _swap 1885435763UL
+#define _drop 1886351972UL
+#define _pop 7368560UL
+#define _clear 491260308579UL
+#define _copy 2037411683UL
+#define _eq 29029UL
+#define _doubleequalsign 15677UL //==
+#define _neq 7431534UL
+#define _shriekequalsign 15649UL //!=
+#define _gt 29799UL
+#define _greaterthansign 62UL //>
+#define _lt 29804UL
+#define _lessthansign 60UL //<
+#define _gte 6648935UL
+#define _greaterthanequalsign 15678UL //>=
+#define _lte 6648940UL
+#define _lessthanequalsign 15676UL //<=
+#define _or 29295UL
+#define _and 6581857UL
+#define _not 7630702UL
+#define _ift 7628393UL
+#define _if_then 31073746738308713UL //if-then
+#define _ifte 1702127209UL
+#define _if_then_else 3273665478445065833UL //if-then-else
+#define _xor 7499640UL
+#define _iff 6710889UL
+#define _over 1919252079UL
+#define _rot 7630706UL
+#define _roll 1819045746UL
+#define _index 517097156201UL
+#define _stack 461228831859UL
+#define _equalsign 61UL //=
+#define _count 500069396323UL
+
- for (int i = 1; i < argc; i++){
- //+ - * /
- //testing switch
- switch (hash(argv[i])){
+ FILE * file;
+ int ret;
+ char item[100];
+ char status;
+ if (argc > 1){
+ file = fopen(argv[1], "r");
+ if (file == NULL){
+ printf("Not found: %s\n", argv[1]);
+ exit(1);
+ }
+ } else {
+ file = stdin;
+ }
+ while (1){
+ ret = fscanf(file, "%s", item, &status);
+ if (ret == EOF){
+ break;
+ }
+ switch (hash(item)){
+ //+ - * /
- case _starsign: //bash treats "*" as special character...
+ case _starsign:
- stack[pointer] = (double) atof(argv[i]);
- pointer = pointer + 1;
- //if pointer > 1023 ...
+ stack[pointer] = (double) atof(item);
+ pointer += 1;
%s
with %99s
is good for what the language is now, but it will suck if you want to add string handling #define TYPE_NULL '\0'
#define TYPE_NUMBER 'n'
#define TYPE_SYMBOL 's'
#define TYPE_POINTER 'p'
#define TYPE_PRIMITIVE 'f'
unsigned long heap[512];
char typeheap[512];
mat3x3(X) :- vec3(first(X)), vec3(second(X)), vec3(third(X)), null(fourth(X)).
vec3(X) :- number(first(X)), number(second(X)), number(third(X)), null(fourth(X)).
ppp0nnn0nnn0nnn0
#!/bin/sh
cmd=$1
while read line; do
reply=`echo "$line" | $cmd`
printf "%s\n" $reply
done
$ ./makecli.sh ./stack
10 7 *
70.000000
10 7 * 7 sqrt -
67.354249
3 4 dup * swap dup * add sqrt
5.000000
Your post is too damn long! (6,221 characters over the limit.)
{ 1 2 3 4 5 } { dup mul } map prettyprint{
{ 1 2 3 4 5 } { dup mul } map 0 { add } reduce55
+#define _forwardslash 47UL // '/'
+//#define _backslash 92UL // '\'
+#define _ampersand 38UL //&
+#define _defun 474416047460UL //like def, but (if type was 'p') forces type to be 'x' - executable
-//#define _deeptype
+#define _deeptype 7309475736231175524UL
+#define _null 1819047278UL
+#define _drop 1886351972UL
+unsigned long primitives[] = {_opencurlybracket, _closecurlybracket,
+ _def, _defun, _eq, _neq, _and, _or, _not, _gt, _lt, _gteq, _lteq, _if, _ifelse, _while, _repeat,
+ _for, _lit, _apply, _head, _tail, _filter, _map, _reduce, _add, _mul, _sub, _mod, _lookup, _prettyprint,
+ _type, _deeptype, _dup, _swap};
+
+#define TYPE_EXECUTABLE 'x' //a pointer for code instead of data
+ case _defun:
+ case _deeptype:
+ case _null:
+ case _drop:
- //check if it is in the dict
- auxi = binarysearch_dict(symbol);
- if (auxi == -1){
- stack[pointer] = symbol;
- typestack[pointer] = 's';
- pointer += 1;
- auxi = binarysearch_labels(symbol);
+ if (item[0] == '/'){ //quote
+ auxi = binarysearch_dict(symbol);
+ aux = hash(&item[1]);
- insertsort_labels(symbol, item);
+ insertsort_dict(symbol, aux, 's');
- } else {
- stack[pointer] = dict[auxi].meaning;
- typestack[pointer] = dict[auxi].type;
- pointer += 1;
+ auxi = binarysearch_labels(aux);
+ if (auxi == -1){
+ insertsort_labels(aux, &item[1]);
+ }
+ }
+ stack[pointer] = symbol;
+ typestack[pointer] = 's';
+ pointer += 1;
+ auxi = binarysearch_labels(symbol);
+ if (auxi == -1){
+ insertsort_labels(symbol, item);
- insertsort_dict(stack[pointer-1], stack[pointer-2], typestack[pointer-2]);
+ auxi = binarysearch_dict(stack[pointer-1]);
+ if (auxi == -1){
+ insertsort_dict(stack[pointer-1], stack[pointer-2], typestack[pointer-2]);
+ } else {
+ dict[auxi].symbol = stack[pointer-1];
+ dict[auxi].meaning = stack[pointer-2];
+ dict[auxi].type = typestack[pointer-2];
+ }
+ pointer -= 2;
+ }
+ break;
+ case _defun:
+ if (pointer >= 2){
+ //p s defun
+ auxi = binarysearch_dict(stack[pointer-1]);
+ auxt = (typestack[pointer-2] == 'p') ? 'x' : typestack[pointer-2];
+ if (auxi == -1){
+ insertsort_dict(stack[pointer-1], stack[pointer-2], auxt);
+ if (auxt == 'x'){
+ insertsort_dict(_ampersand + stack[pointer-1]*256, stack[pointer-2], 'p');
+ }
+ } else {
+ dict[auxi].symbol = stack[pointer-1];
+ dict[auxi].meaning = stack[pointer-2];
+ dict[auxi].type = auxt;
+ if (auxt == 'x'){
+ auxi = binarysearch_dict(_ampersand + stack[pointer-1]*256);
+ if (auxi == -1){
+ insertsort_dict(_ampersand + stack[pointer-1]*256, stack[pointer-2], 'p');
+ } else {
+ dict[auxi].symbol = _ampersand + stack[pointer-1]*256;
+ dict[auxi].meaning = stack[pointer-2];
+ dict[auxi].type = 'p';
+ }
+ }
+ }
- if (typestack[pointer-1] != 'p') //there's nothing to do if it is a different type
+ auxt = typestack[pointer-1];
+ if (auxt != 'p' && auxt != 'f' && auxt != 'x'){
+ }
+ pointer -= 1;
+ if (auxt == 'f'){
+ apply(aux, NULL, 0);
+ return;
+ }
- pointer -= 1;
- stack[pointer] = heap[aux]; //dictionary lookup must be explicit, use lookup
+ stack[pointer] = heap[aux];
- break;
+ apply(_lookup, NULL, 0); //dictionary lookup is automatic, use '/' to quote (e.g. 10 /n def)
+ if (typestack[pointer-1] == 'x'){
+ apply(_apply, NULL, 0);
+ }
+ break;
- //apply(_apply, NULL, 0); //apply must be explicit since it is not known whether the array is code or data
+ //apply(_apply, NULL, 0); //apply must be explicit for pointers 'p', while it is automatic for pointers 'x' is code or data
+ /*case 'x':
+ stack[pointer] = heap[aux];
+ typestack[pointer] = 'x';
+ pointer += 1;
+ apply(_apply, NULL, 0);
+ break;*/
- case _lookup: //dictionary lookup must be explicit
+ case _lookup: //explicit dictionary lookup
+ case 'x':
+ case _deeptype:
+ if (pointer >= 1){ //this would do best to return a string, not a symbol, because deeptypes can be larger than 8 chars
+ //stack[pointer-1] = (unsigned long) typestack[pointer-1];
+ //typestack[pointer-1] = 's';
+ if (typestack[pointer-1] == 'p'){
+
+ } else {
+
+ }
+ }
+ break;
+ case _null:
+ //{ type 0 eq } /null defun
+ if (pointer >= 1){
+ stack[pointer-1] = (typestack[pointer-1] == TYPE_NULL) ? 1 : 0;
+ typestack[pointer-1] = 'n';
+ }
+ break;
- default:
- stack[pointer] = (unsigned long) strtoul(item, &end, 10);
+ case _drop:
+ if (pointer >= 1){
+ pointer -= 1;
+ }
+ break;
+ //default:
+ /* stack[pointer] = (unsigned long) strtoul(item, &end, 10); //non functional, pretty much
+ if (item[0] == '/'){ //quote
+ auxi = binarysearch_dict(symbol);
+ if (auxi == -1){
+ //insertsort_dict(symbol, hash(&item[1]), 's');
+ }
+ }
- }
+ }*/
+
+ for (int i = 0; i < sizeof(primitives)/sizeof(unsigned long); i++){
+ insertsort_dict(_ampersand + primitives[i]*256, primitives[i], 'f');
+ }
- apply(_closecurlybracket, NULL, 1); //even quoting a '}' it works properly
+ apply(_closecurlybracket, NULL, 1);
- printf("s %lu\n", stack[i]);
+ printf("s%lu\n", stack[i]);
- printf("%lu (null)", stack[i]);
+ printf("%lu(null)", stack[i]);
- printf("%lu %c\n", stack[i], typestack[i]);
+ printf("%c%lu\n", typestack[i], stack[i]);
-}
+}
{ /n def
1 /i def
&{ { n i gteq } { i i 1 add /i def } while &} apply
} /genlist defun
10 genlist prettyprint
{ This is a comment. Below I implement a map that is equivalent to the hardcoded one. } drop
{ dup mul } /square defun
{ /f def
/list def
&{ { list head null not } { list head f apply list tail /list def } while &} apply
} /mymap defun
10 genlist &square mymap prettyprint
{ Alternatively, use an anonymous function. } drop
10 genlist { dup mul } mymap prettyprint
{ The difference between def and defun is merely of the default behavior when met by the interpreter. } drop
{ 2 add } /add2 defun
1 add2
{ 2 add } /add2_ def
1 add2_ apply
{ A '&' before a defun'd block turns its behavior into a def'd block. } drop
1 &add2 apply
{ This is useful to pass functions as arguments, which otherwise would be impossible for defun'd blocks.
And without defun some pieces of code would turn excessively verbose. } drop
#!/bin/sh
cmd=$1
printf "> "
while read -r line; do
reply=`echo "$line" | $cmd`
printf "%s\n" $reply
printf "> "
done
/f def /list def &list head null not list head f apply list head if list tail /list def while & apply /myfilter defun
1 2 3 4 5 6 2 mod 0 eq myfilter prettyprint
/f def /acc def /list def
acc
list head null not list head f apply list tail /list def while /myreduce defun
1 2 3 4 5 6 0 &add myreduce
Way to bump a five year old thread!Thanks.
Way to bump a five year old thread!Forbidden meme, an unearthed presence from a different time...