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

Pages: 1-4041-

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-02 20:21

heh

Name: Anonymous 2018-03-02 20:56

concatenative server-side framework. it will be called Backend Forth

Name: Anonymous 2018-03-02 21:26

Name: Anonymous 2018-03-07 3:17

I wrote a simple interpreter for a stack-based language recently.

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

Name: Anonymous 2018-03-07 5:47

>>6
#define modulo(A, B) (A - B * floor(A / B))
why

Name: Anonymous 2018-03-07 7:17

>>6
learn2switch

Name: Anonymous 2018-03-07 9:04

>>7
I just copied it hurriedly from somewhere without thinking.
>>8
You can't switch on char * strings, though.

Name: Anonymous 2018-03-07 9:26

>>9
You can't switch on char * strings, though.
which should be a clue that what you're doing isn't the right way.

Name: Anonymous 2018-03-07 9:28

>>9
You can hash the string and switch on resulting hashes.

Name: Anonymous 2018-03-07 14:20

>>11
Noted.

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

Name: Anonymous 2018-03-07 14:39

I can't believe that this actually looks better now, I wasn't even serious about the hash.

Name: >>10, not >>12 2018-03-07 14:48

>>13
why weren't you serious? it's the simplest solution I can think of.

Name: Anonymous 2018-03-07 23:04

Should I make the stack a union of an enum type, a double and an unsigned long? In this way I could store both numbers and symbols on the stack, which means the symbols would not need to be interpreted immediately.

Name: Anonymous 2018-03-08 7:19

>>15
I guess a tagged union would be the obvious choice

Name: Anonymous 2018-03-08 11:48

>>12
minor update, now it reads from either stdin or file (instead of reading the arguments of bash)
so you can do

./stack main.stk
or
cat main.stk | ./stack

Instead of posting the whole file I'll just post the diff.

-//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;

Name: Anonymous 2018-03-08 11:50

>>17
nice buffer overflow!

Name: Anonymous 2018-03-08 13:37

>>18
Thanks. But most strings aren't over 100 characters without spaces. I thought for quick prototyping and testing it would be acceptable. Should I check the length of the next word before choosing to accept it? Or just truncate it?

Name: Anonymous 2018-03-08 13:44

>>19
depends on your requirements replacing %s with %99s is good for what the language is now, but it will suck if you want to add string handling

Name: Anonymous 2018-03-08 13:56

fuck string handling, strings are bloat

Name: Anonymous 2018-03-08 14:25

dubs are not bloat

Name: Anonymous 2018-03-08 20:14

I'm throwing away some functions like sum and prod. Since there are going to be types other than doubles now, which can be on the stack, it's difficult to define their behavior. Sum everything on the stack, up til a non-number is found? Sum everything on the stack, ignoring symbols? Are the symbols eaten up or are their relative positions conserved? Etc. There will be separate data structures for accumulation later.

>>20,21
I'm not particularly concerned with string handling right now, there are other languages that do that fairly well.

Name: Anonymous 2018-03-09 12:56

#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

Name: Anonymous 2018-03-09 22:18

Using C is the closest thing to eating shit you can do on a computer.

Name: Anonymous 2018-03-09 22:54

>>25
That's why you use C to write an interpreter for a better language.

Name: Anonymous 2018-03-09 23:15

>>25
what about using php?

Name: Anonymous 2018-03-09 23:34

>>27
That's what you get when you use C to write an interpreter for a better language.

Name: Anonymous 2018-03-10 0:23

2 interpreters 1 cpu

Name: Anonymous 2018-03-10 1:25

>>28
what about javascript?

Name: Anonymous 2018-03-10 1:32

makecli.sh
#!/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

Name: Anonymous 2018-03-12 4:19

This is a different file, called heap.c. It's still a bit raw, but it's a good start.

Your post is too damn long! (6,221 characters over the limit.)

https://bpaste.net/show/73346a7e4f44

E.g.
$ ./makecli.sh ./heap
{ 1 2 3 4 5 } { dup mul } map prettyprint
{
1
4
9
16
25
}
{ 1 2 3 4 5 } { dup mul } map 0 { add } reduce
55

Name: Anonymous 2018-03-13 19:28

>>32
Minor update, getting things to work correctly.

heap.c:
https://bpaste.net/show/6ffcb116f3c6

diff:
+#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]);
-}
+}


main.stk:
{ /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

Name: >>33 2018-03-13 20:26

I hadn't tested it, but one of the comments seems to be causing a buffer overflow. Possibly something to do with strings being too big.

Name: Anonymous 2018-03-13 20:59

>>34
Add

item[9] = '\0';
before apply(hash(item), item, 1) at main

This solves the problem.

Name: Anonymous 2018-03-13 20:59

>>31
I never use sh/bash but is there a reason you couldnt just 'while true read|$1'

Name: Anonymous 2018-03-13 21:45

>>36
$ man read

...
STDOUT
Not used.


Read reads the line into a var, modifying the shell execution environment.

If there are no args it does nothing. I also don't think yours would detect an end of file.

$ man read

...
EXIT STATUS
The following exit values shall be returned:

0 Successful completion.

>0 End-of-file was detected or an error occurred.


Also, I've updated makecli.sh a bit:

#!/bin/sh

cmd=$1

printf "> "
while read -r line; do
reply=`echo "$line" | $cmd`
printf "%s\n" $reply
printf "> "
done

Name: Anonymous 2018-03-13 22:25

>>37
oh. my shell doesnt have a read builtin, so I just use "while((putchar(getchar()))!='\n'){}", wihch is more or less how it acts on the other OS I use.(Though there, it has more features, like reading in n lines and ptuting them all on the output, another thing or two.). Though you're right about EOF, but all my file send in newlines anyway.j
but, testing it with mine, it works with dc fine.

Name: Anonymous 2018-03-13 23:59

>>38
You code with those fingers?

Name: Anonymous 2018-03-14 0:24

>>39
My keyboard is near the end of its life.

Name: Anonymous 2018-03-15 13:36

filter and reduce

/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

Name: Anonymous 2018-03-15 13:37

>>41
For some reason the curly brackets were eaten...

Name: Anonymous 2018-03-15 13:40

Name: Anonymous 2018-03-15 14:59

check my anal kudasai

Name: Anonymous 2018-03-16 9:22

Next step is implementing lexical scoping (right now variables collide and it is quite buggy).

Name: Anonymous 2018-03-19 3:45

>>42
because of the shitty sexpcode parser, probably

Name: Anonymous 2022-10-17 1:04

Way to bump a five year old thread!
Thanks.

Anyway, since I found this thread again and also the code which I thought lost, I update it with what I have gotten to so far:

heap.c
https://gist.github.com/Capaverde/521a6cf4e15f043261a1f2fee2a97921

main.stk
https://gist.github.com/Capaverde/1a03d32d86d9a18db999724f3fb6bec6

Name: Anonymous 2022-10-17 6:25

>>47
I have to say that this is quite cool, admin-kun.

Name: Anonymous 2022-10-17 8:37

>>47
ZOMG BASED ADMIN!?!?!?!?!

Name: Anonymous 2022-10-17 15:34

>>47
Way to bump a five year old thread!
Forbidden meme, an unearthed presence from a different time...

Name: Anonymous 2022-10-24 19:18

>>48,49
I am not the admin, but thanks for the compliment.
I would have worked more on the language but I had two tests last week and also have two tests this week.

Name: Anonymous 2022-10-25 6:41

>>51
>not admin
>overrides the old thread autosage protocol
doubt.kt

Name: Anonymous 2022-10-25 15:04

Whomest'th art thou quoting?

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