Last active
March 13, 2018 20:57
-
-
Save Capaverde/521a6cf4e15f043261a1f2fee2a97921 to your computer and use it in GitHub Desktop.
Revisions
-
Capaverde revised this gist
Mar 13, 2018 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -852,6 +852,7 @@ int main(int argc, char * argv[]){ if (ret == EOF){ break; } item[9] = '\0'; apply(hash(item), item, 1); } apply(_closecurlybracket, NULL, 1); -
toyprotector revised this gist
Mar 13, 2018 . 1 changed file with 132 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -23,7 +23,11 @@ unsigned long hash(char * s){ #define _opencurlybracket 123UL //{ #define _closecurlybracket 125UL //} #define _forwardslash 47UL // '/' //#define _backslash 92UL // '\' #define _ampersand 38UL //& #define _def 6710628UL #define _defun 474416047460UL //like def, but (if type was 'p') forces type to be 'x' - executable #define _eq 29029UL #define _neq 7431534UL #define _and 6581857UL @@ -52,12 +56,19 @@ unsigned long hash(char * s){ #define _lookup 123649615949676UL #define _prettyprint 8246224458791350896UL #define _type 1701869940UL #define _deeptype 7309475736231175524UL #define _null 1819047278UL //#define deepmap #define _dup 7370084UL #define _swap 1885435763UL #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}; typedef struct { unsigned long symbol; unsigned long meaning; char type; } entry; //usually a pointer [index] to the heap, but can also be a number or a symbol entry dict[128]; //symbol and meaning @@ -68,6 +79,7 @@ label labels[256]; //symbol and printable form #define TYPE_NUMBER 'n' #define TYPE_SYMBOL 's' #define TYPE_POINTER 'p' #define TYPE_EXECUTABLE 'x' //a pointer for code instead of data #define TYPE_PRIMITIVE 'f' unsigned long heap[512]; @@ -197,6 +209,7 @@ void apply(unsigned long symbol, char * item, int quoting){ if (quoting == 1 && symbol != _opencurlybracket && symbol != _closecurlybracket){ switch(symbol){ case _def: case _defun: case _eq: case _neq: case _and: @@ -224,8 +237,11 @@ void apply(unsigned long symbol, char * item, int quoting){ case _lookup: case _prettyprint: case _type: case _deeptype: case _null: case _dup: case _swap: case _drop: stack[pointer] = symbol; typestack[pointer] = 'f'; pointer += 1; @@ -238,20 +254,23 @@ void apply(unsigned long symbol, char * item, int quoting){ return; } //interpret it as a symbol if (item[0] == '/'){ //quote auxi = binarysearch_dict(symbol); aux = hash(&item[1]); if (auxi == -1){ insertsort_dict(symbol, aux, 's'); } 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); } } } else { @@ -299,7 +318,42 @@ void apply(unsigned long symbol, char * item, int quoting){ case _def: if (pointer >= 2){ //stack[pointer-1] is the symbol, stack[pointer-2] is the pointer (or number or another symbol) 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'; } } } pointer -= 2; } break; @@ -370,18 +424,28 @@ void apply(unsigned long symbol, char * item, int quoting){ //lookup heap, interpret it up til null is found if (pointer >= 1){ aux = stack[pointer-1]; //a pointer auxt = typestack[pointer-1]; if (auxt != 'p' && auxt != 'f' && auxt != 'x'){ return; } pointer -= 1; if (auxt == 'f'){ apply(aux, NULL, 0); return; } //iterate from heap[aux], aux++, until heap[aux] == null //check its type at typeheap[aux] to know how to interpret it, it can be s, n, p, or f while (typeheap[aux] != TYPE_NULL){ switch (typeheap[aux]){ case 's': stack[pointer] = heap[aux]; typestack[pointer] = 's'; pointer += 1; 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; case 'n': stack[pointer] = heap[aux]; typestack[pointer] = 'n'; @@ -394,8 +458,14 @@ void apply(unsigned long symbol, char * item, int quoting){ stack[pointer] = heap[aux]; typestack[pointer] = 'p'; pointer += 1; //apply(_apply, NULL, 0); //apply must be explicit for pointers 'p', while it is automatic for pointers 'x' is code or data break; /*case 'x': stack[pointer] = heap[aux]; typestack[pointer] = 'x'; pointer += 1; apply(_apply, NULL, 0); break;*/ //no default, these are the only possible ones } aux += 1; @@ -627,7 +697,7 @@ void apply(unsigned long symbol, char * item, int quoting){ pointer -= 1; } break; case _lookup: //explicit dictionary lookup if (pointer >= 1){ auxi = binarysearch_dict(stack[pointer-1]); if (auxi == -1){ @@ -659,6 +729,7 @@ void apply(unsigned long symbol, char * item, int quoting){ printf("f %lu ", aux); //primitives aren't in labels - gonna need to create a table for them later break; case 'p': case 'x': printf("{\n"); while (typeheap[aux] != TYPE_NULL){ stack[pointer] = heap[aux]; @@ -689,6 +760,24 @@ void apply(unsigned long symbol, char * item, int quoting){ } } break; 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; case _dup: if (pointer >= 1){ stack[pointer] = stack[pointer-1]; @@ -707,32 +796,47 @@ void apply(unsigned long symbol, char * item, int quoting){ typestack[pointer-1] = auxt; } break; case _drop: if (pointer >= 1){ pointer -= 1; } break; //default: /* stack[pointer] = (unsigned long) strtoul(item, &end, 10); //non functional, pretty much if (*end == '\0'){ typestack[pointer] = 'n'; pointer += 1; return; } //interpret it as a symbol if (item[0] == '/'){ //quote auxi = binarysearch_dict(symbol); if (auxi == -1){ //insertsort_dict(symbol, hash(&item[1]), 's'); } } stack[pointer] = symbol; typestack[pointer] = 's'; pointer += 1; auxi = binarysearch_labels(symbol); if (auxi == -1){ insertsort_labels(symbol, item); }*/ } } } int main(int argc, char * argv[]){ FILE * file; char item[20]; char status; int ret; int auxi; for (int i = 0; i < sizeof(primitives)/sizeof(unsigned long); i++){ insertsort_dict(_ampersand + primitives[i]*256, primitives[i], 'f'); } if (argc > 1){ //file argument file = fopen(argv[1], "r"); if (file == NULL){ @@ -750,7 +854,7 @@ int main(int argc, char * argv[]){ } apply(hash(item), item, 1); } apply(_closecurlybracket, NULL, 1); apply(_apply, NULL, 0); //print the stack for (int i = pointer-1; i >= 0; i--){ //either symbols, numbers or pointers @@ -767,15 +871,15 @@ int main(int argc, char * argv[]){ strcpy(item, labels[auxi].string); printf("%s\n", item); } else { printf("s%lu\n", stack[i]); } break; case TYPE_NULL: printf("%lu(null)", stack[i]); break; default: printf("%c%lu\n", typestack[i], stack[i]); } } return 0; } -
Capaverde created this gist
Mar 12, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,781 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> //only unsigned longs for both symbols and pointers. pointers point to heap. there is a dictionary which contains pairs of symbols and pointers //instead of tagging, a type heap in a one-to-one correspondence with the heap //insertsort into the dict and labels later //(numbers also added) //compile with: gcc heap.c -o heap 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 _opencurlybracket 123UL //{ #define _closecurlybracket 125UL //} #define _def 6710628UL #define _eq 29029UL #define _neq 7431534UL #define _and 6581857UL #define _or 29295UL #define _not 7630702UL #define _gt 29799UL #define _lt 29804UL #define _gteq 1902474343UL #define _lteq 1902474348UL #define _if 26217UL #define _ifelse 111546414229097UL #define _while 435610544247UL #define _repeat 127961662514546UL #define _for 7499622UL #define _lit 7629164UL #define _apply 521510350945UL #define _head 1684104552UL #define _tail 1818845556UL #define _filter 125780070525286UL #define _map 7364973UL #define _reduce 111477845681522UL #define _add 6579297UL #define _mul 7107949UL #define _sub 6452595UL #define _mod 6582125UL #define _lookup 123649615949676UL #define _prettyprint 8246224458791350896UL #define _type 1701869940UL //#define _deeptype //#define deepmap #define _dup 7370084UL #define _swap 1885435763UL typedef struct { unsigned long symbol; unsigned long meaning; char type; } entry; //usually a pointer [index] to the heap, but can also be a number or a symbol entry dict[128]; //symbol and meaning typedef struct { unsigned long symbol; char string[10]; } label; label labels[256]; //symbol and printable form #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]; unsigned long stack[1024]; char typestack[1024]; int pointer = 0; //stack int hpointer = 0; //heap and typeheap int dpointer = 0; //dict int lpointer = 0; //labels int binarysearch_labels(unsigned long symbol){ // label * labels, int lpointer, no need to pass them if (lpointer == 0){ return -1; } int lowerbound = 0; int upperbound = lpointer - 1; int middle; if (labels[upperbound].symbol == symbol){ return upperbound; } if (labels[lowerbound].symbol == symbol){ return lowerbound; } while (1){ middle = (lowerbound + upperbound)/2; if (labels[middle].symbol == symbol){ return middle; } else if (labels[middle].symbol < symbol){ lowerbound = middle; } else if (labels[middle].symbol > symbol){ upperbound = middle; } if (upperbound - lowerbound <= 1){ return -1; //not found } } } void insertsort_labels(unsigned long symbol, char * string){ //label * labels, int lpointer, no need to pass them labels[lpointer].symbol = symbol; strcpy(labels[lpointer].string, string); unsigned long aux_s; char aux_str[10]; for (int i = lpointer-1; i >= 0; i--){ if (labels[i].symbol > labels[i+1].symbol){ aux_s = labels[i].symbol; strcpy(aux_str, labels[i].string); labels[i].symbol = labels[i+1].symbol; strcpy(labels[i].string, labels[i+1].string); labels[i+1].symbol = aux_s; strcpy(labels[i+1].string, aux_str); } else { break; } } lpointer += 1; //this is a side-effect outside the function } int binarysearch_dict(unsigned long symbol){ //entry * dict, int dpointer, no need to pass them if (dpointer == 0){ return -1; } int lowerbound = 0; int upperbound = dpointer - 1; int middle; if (dict[upperbound].symbol == symbol){ return upperbound; } if (dict[lowerbound].symbol == symbol){ return lowerbound; } while (1){ middle = (lowerbound + upperbound)/2; if (dict[middle].symbol == symbol){ return middle; } else if (dict[middle].symbol < symbol){ lowerbound = middle; } else if (dict[middle].symbol > symbol){ upperbound = middle; } if (upperbound - lowerbound <= 1){ return -1; //not found } } } void insertsort_dict(unsigned long symbol, unsigned long meaning, char type){ //entry * dict, int dpointer, no need to pass them dict[dpointer].symbol = symbol; dict[dpointer].meaning = meaning; dict[dpointer].type = type; unsigned long aux_s; unsigned long aux_m; char aux_t; for (int i = dpointer-1; i >= 0; i--){ if (dict[i].symbol > dict[i+1].symbol){ aux_s = dict[i].symbol; aux_m = dict[i].meaning; aux_t = dict[i].type; dict[i].symbol = dict[i+1].symbol; dict[i].meaning = dict[i+1].meaning; dict[i].type = dict[i+1].type; dict[i+1].symbol = aux_s; dict[i+1].meaning = aux_m; dict[i+1].type = aux_t; } else { break; } } dpointer += 1; //this is a side-effect outside the function } void apply(unsigned long symbol, char * item, int quoting){ unsigned long aux; unsigned long aux2; unsigned long aux3; unsigned long aux4; int auxi; char auxt; char auxt2; int i; char * end; char auxstr[10]; if (quoting == 1 && symbol != _opencurlybracket && symbol != _closecurlybracket){ switch(symbol){ case _def: case _eq: case _neq: case _and: case _or: case _not: case _gt: case _lt: case _gteq: case _lteq: case _apply: case _if: case _ifelse: case _while: case _repeat: case _for: case _head: case _tail: case _filter: case _map: case _reduce: case _add: case _mul: case _sub: case _mod: //common case of bug is forgetting to add the command here - should need to only add in one place instead case _lookup: case _prettyprint: case _type: case _dup: case _swap: stack[pointer] = symbol; typestack[pointer] = 'f'; pointer += 1; break; default: stack[pointer] = (unsigned long) strtoul(item, &end, 10); if (*end == '\0'){ typestack[pointer] = 'n'; pointer += 1; return; } //interpret it as a symbol //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 (auxi == -1){ insertsort_labels(symbol, item); } } else { stack[pointer] = dict[auxi].meaning; typestack[pointer] = dict[auxi].type; pointer += 1; } } } else { switch (symbol){ //moved outside main for recursion // block symbols are { and } (after PostScript) case _opencurlybracket: stack[pointer] = _opencurlybracket; typestack[pointer] = 's'; pointer += 1; break; case _closecurlybracket: stack[pointer] = _closecurlybracket; typestack[pointer] = 's'; pointer += 1; for (i = pointer-1; i >= 0; i--){ if (stack[i] == _opencurlybracket){ break; } } if (i < 0){ pointer = 0; //no open bracket found, nothing to be done, clear the stack and move on printf("Unmatched bracket\n"); break; } pointer = i; aux = hpointer; while (1){ i += 1; if (stack[i] != _closecurlybracket){ heap[hpointer] = stack[i]; typeheap[hpointer] = typestack[i]; //s, p, f hpointer += 1; } else { break; } } heap[hpointer] = 0; //termination typeheap[hpointer] = TYPE_NULL; hpointer += 1; //push the pointer to the start of the block to the stack stack[pointer] = aux; typestack[pointer] = 'p'; pointer += 1; break; case _def: if (pointer >= 2){ //stack[pointer-1] is the symbol, stack[pointer-2] is the pointer (or number or another symbol) insertsort_dict(stack[pointer-1], stack[pointer-2], typestack[pointer-2]); pointer -= 2; } break; case _eq: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-1] == stack[pointer-2]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _neq: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-1] != stack[pointer-2]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _and: if (pointer >= 2){ stack[pointer-2] = ((stack[pointer-1] != 0) && (stack[pointer-2] != 0)) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _or: if (pointer >= 2){ stack[pointer-2] = ((stack[pointer-1] != 0) || (stack[pointer-2] != 0)) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _not: if (pointer >= 1){ stack[pointer-1] = (stack[pointer-1] == 0) ? 1 : 0; typestack[pointer-1] = 'n'; } break; case _gt: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-2] > stack[pointer-1]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _lt: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-2] < stack[pointer-1]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _gteq: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-2] >= stack[pointer-1]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _lteq: if (pointer >= 2){ stack[pointer-2] = (stack[pointer-2] <= stack[pointer-1]) ? 1 : 0; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _apply: //... f apply //lookup heap, interpret it up til null is found if (pointer >= 1){ aux = stack[pointer-1]; //a pointer if (typestack[pointer-1] != 'p') //there's nothing to do if it is a different type return; //iterate from heap[aux], aux++, until heap[aux] == null //check its type at typeheap[aux] to know how to interpret it, it can be s, n, p, or f pointer -= 1; while (typeheap[aux] != TYPE_NULL){ switch (typeheap[aux]){ case 's': stack[pointer] = heap[aux]; //dictionary lookup must be explicit, use lookup typestack[pointer] = 's'; pointer += 1; break; case 'n': stack[pointer] = heap[aux]; typestack[pointer] = 'n'; pointer += 1; break; case 'f': apply(heap[aux], NULL, 0); break; case 'p': stack[pointer] = heap[aux]; typestack[pointer] = 'p'; pointer += 1; //apply(_apply, NULL, 0); //apply must be explicit since it is not known whether the array is code or data break; //no default, these are the only possible ones } aux += 1; } } break; case _if: //cond f if if (pointer >= 2){ if (stack[pointer-2] != 0){ aux = stack[pointer-1]; auxt = typestack[pointer-1]; pointer -= 2; //apply aux here stack[pointer] = aux; typestack[pointer] = auxt; pointer += 1; apply(_apply, NULL, 0); } else { pointer -= 2; } } break; case _ifelse: //cond f1 f2 ifelse if (pointer >= 3){ aux = (stack[pointer-3] != 0) ? stack[pointer-2] : stack[pointer-1]; auxt = (stack[pointer-3] != 0) ? typestack[pointer-2] : typestack[pointer-1]; pointer -= 3; //apply aux here stack[pointer] = aux; typestack[pointer] = auxt; pointer += 1; apply(_apply, NULL, 0); } break; case _while: //cond f while, but cond is an expression if (pointer >= 2){ aux = stack[pointer-2]; auxt = typestack[pointer-2]; aux2 = stack[pointer-1]; pointer -= 2; while (1){ stack[pointer] = aux; typestack[pointer] = auxt; //could also be 'n', no? 1 f while - though there's no exit statement yet pointer += 1; apply(_apply, NULL, 0); //eval cond if (stack[pointer-1] != 0){ pointer -= 1; stack[pointer] = aux2; typestack[pointer] = 'p'; pointer += 1; apply(_apply, NULL, 0); } else { pointer -= 1; break; } } } break; case _repeat: //f n repeat //repeat f (i.e apply) n times if (pointer >= 2){ aux = stack[pointer-2]; aux2 = stack[pointer-1]; pointer -= 2; for (i = 0; i < aux2; i++){ stack[pointer] = aux; typestack[pointer] = 'p'; pointer += 1; apply(_apply, NULL, 0); } } break; case _for: //start end step f for if (pointer >= 4){ aux = stack[pointer-4]; aux2 = stack[pointer-3]; aux3 = stack[pointer-2]; aux4 = stack[pointer-1]; pointer -= 4; for (i = aux; i < aux2; i += aux3){ //i f a bunch of times stack[pointer] = i; typestack[pointer] = 'n'; pointer += 1; stack[pointer] = aux4; typestack[pointer] = 'p'; pointer += 1; apply(_apply, NULL, 0); } } break; case _head: if (pointer >= 1){ aux = stack[pointer-1]; pointer -= 1; stack[pointer] = heap[aux]; typestack[pointer] = typeheap[aux]; pointer += 1; } break; case _tail: if (pointer >= 1){ aux = stack[pointer-1]; pointer -= 1; stack[pointer] = aux + 1; typestack[pointer] = 'p'; pointer += 1; } break; case _filter: //list f filter if (pointer >= 2){ aux = stack[pointer-2]; aux2 = stack[pointer-1]; auxt = typestack[pointer-1]; //'p' or 'f' pointer -= 2; aux3 = hpointer; while (typeheap[aux] != TYPE_NULL){ stack[pointer] = heap[aux]; // list head typestack[pointer] = typeheap[aux]; pointer += 1; stack[pointer] = aux2; typestack[pointer] = auxt; pointer += 1; apply(_apply, NULL, 0); if (stack[pointer-1] != 0) { heap[hpointer] = heap[aux]; typeheap[hpointer] = typeheap[aux]; hpointer += 1; pointer -= 1; } else { pointer -= 1; } aux += 1; } heap[hpointer] = 0; typeheap[hpointer] = TYPE_NULL; hpointer += 1; stack[pointer] = aux3; typestack[pointer] = 'p'; pointer += 1; } break; case _map: //list f map if (pointer >= 2){ aux = stack[pointer-2]; aux2 = stack[pointer-1]; auxt = typestack[pointer-1]; pointer -= 2; aux3 = hpointer; while (typeheap[aux] != TYPE_NULL){ stack[pointer] = heap[aux]; // list head typestack[pointer] = typeheap[aux]; pointer += 1; stack[pointer] = aux2; typestack[pointer] = auxt; pointer += 1; apply(_apply, NULL, 0); heap[hpointer] = stack[pointer-1]; typeheap[hpointer] = typestack[pointer-1]; hpointer += 1; pointer -= 1; aux += 1; } heap[hpointer] = 0; typeheap[hpointer] = TYPE_NULL; hpointer += 1; stack[pointer] = aux3; typestack[pointer] = 'p'; pointer += 1; } break; case _reduce: //list acc f reduce, e.g. { 1 2 3 4 } 0 { add } reduce if (pointer >= 3){ aux = stack[pointer-3]; aux2 = stack[pointer-2]; auxt = typestack[pointer-2]; aux3 = stack[pointer-1]; auxt2 = typestack[pointer-1]; pointer -= 3; //first place acc on stack stack[pointer] = aux2; typestack[pointer] = auxt; pointer += 1; //now just put list head on stack, f on stack, apply, increment aux while (typeheap[aux] != TYPE_NULL){ stack[pointer] = heap[aux]; typestack[pointer] = typeheap[aux]; pointer += 1; stack[pointer] = aux3; typestack[pointer] = auxt2; pointer += 1; apply(_apply, NULL, 0); aux += 1; } } break; case _add: if (pointer >= 2){ stack[pointer-2] = stack[pointer-2] + stack[pointer-1]; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _mul: if (pointer >= 2){ stack[pointer-2] = stack[pointer-2] * stack[pointer-1]; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _sub: if (pointer >= 2){ stack[pointer-2] = stack[pointer-2] - stack[pointer-1]; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _mod: if (pointer >= 2){ stack[pointer-2] = stack[pointer-2] % stack[pointer-1]; typestack[pointer-2] = 'n'; pointer -= 1; } break; case _lookup: //dictionary lookup must be explicit if (pointer >= 1){ auxi = binarysearch_dict(stack[pointer-1]); if (auxi == -1){ //nothing } else { stack[pointer-1] = dict[auxi].meaning; typestack[pointer-1] = dict[auxi].type; } } break; //need a way to pretty print lists case _prettyprint: //in fact truncated to 'prettypr' - unsigned long only takes 8 bytes (could this differ between machines?) if (pointer >= 1){ aux = stack[pointer-1]; auxt = typestack[pointer-1]; pointer -= 1; //if auxt == 'p', recursively print all content switch (auxt) { case 'n': printf("%lu\n", aux); break; case 's': printf("%s\n", labels[binarysearch_labels(aux)].string); //assuming found because I'm hurried break; case TYPE_NULL: printf("%lu (null)\n", aux); break; case 'f': printf("f %lu ", aux); //primitives aren't in labels - gonna need to create a table for them later break; case 'p': printf("{\n"); while (typeheap[aux] != TYPE_NULL){ stack[pointer] = heap[aux]; typestack[pointer] = typeheap[aux]; pointer += 1; apply(_prettyprint, NULL, 0); aux += 1; } printf("}\n"); break; default: printf("%lu %c\n", aux, auxt); } } break; case _type: //x type if (pointer >= 1){ //need to create a symbol from the typestack value stack[pointer-1] = (unsigned long) typestack[pointer-1]; typestack[pointer-1] = 's'; //I would do a ... = hash(typestack[pointer-1]), but it's all chars, and chars have the same value as their hashes auxi = binarysearch_labels(stack[pointer-1]); if (auxi == -1){ auxstr[0] = (char) stack[pointer-1]; auxstr[1] = '\0'; insertsort_labels(stack[pointer-1], auxstr); } } break; case _dup: if (pointer >= 1){ stack[pointer] = stack[pointer-1]; typestack[pointer] = typestack[pointer-1]; pointer += 1; } break; case _swap: //a b swap if (pointer >= 2){ aux = stack[pointer-2]; auxt = typestack[pointer-2]; stack[pointer-2] = stack[pointer-1]; typestack[pointer-2] = typestack[pointer-1]; stack[pointer-1] = aux; typestack[pointer-1] = auxt; } break; default: stack[pointer] = (unsigned long) strtoul(item, &end, 10); if (*end == '\0'){ typestack[pointer] = 'n'; pointer += 1; return; } //interpret it as a symbol stack[pointer] = symbol; typestack[pointer] = 's'; pointer += 1; auxi = binarysearch_labels(symbol); if (auxi == -1){ insertsort_labels(symbol, item); } } } } int main(int argc, char * argv[]){ FILE * file; char item[20]; char status; int ret; int auxi; if (argc > 1){ //file argument file = fopen(argv[1], "r"); if (file == NULL){ printf("No such file: %s\n", argv[1]); exit(1); } } else { file = stdin; } apply(_opencurlybracket, NULL, 1); while (1){ ret = fscanf(file, "%19s", item, &status); if (ret == EOF){ break; } apply(hash(item), item, 1); } apply(_closecurlybracket, NULL, 1); //even quoting a '}' it works properly apply(_apply, NULL, 0); //print the stack for (int i = pointer-1; i >= 0; i--){ //either symbols, numbers or pointers switch (typestack[i]){ case 'n': printf("%lu\n", stack[i]); break; case 'p': printf("_%lu\n", stack[i]); //'_' means pointer break; case 's': auxi = binarysearch_labels(stack[i]); if (auxi != -1){ strcpy(item, labels[auxi].string); printf("%s\n", item); } else { printf("s %lu\n", stack[i]); } break; case TYPE_NULL: printf("%lu (null)", stack[i]); break; default: printf("%lu %c\n", stack[i], typestack[i]); } } return 0; }