Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

stack-based language for web

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

Name: Anonymous 2018-03-07 3:24

#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;
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List