Skip to content

Instantly share code, notes, and snippets.

@Capaverde
Last active March 13, 2018 20:57
Show Gist options
  • Select an option

  • Save Capaverde/521a6cf4e15f043261a1f2fee2a97921 to your computer and use it in GitHub Desktop.

Select an option

Save Capaverde/521a6cf4e15f043261a1f2fee2a97921 to your computer and use it in GitHub Desktop.

Revisions

  1. Capaverde revised this gist Mar 13, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions heap.c
    Original 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);
  2. @toyprotector toyprotector revised this gist Mar 13, 2018. 1 changed file with 132 additions and 28 deletions.
    160 changes: 132 additions & 28 deletions heap.c
    Original 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
    #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
    //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]);
    if (auxi == -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);
    }
    }
    } 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)
    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';
    }
    }
    }
    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
    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'){
    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
    pointer -= 1;
    while (typeheap[aux] != TYPE_NULL){
    switch (typeheap[aux]){
    case 's':
    stack[pointer] = heap[aux]; //dictionary lookup must be explicit, use lookup
    stack[pointer] = heap[aux];
    typestack[pointer] = 's';
    pointer += 1;
    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;
    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 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
    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: //dictionary lookup must be explicit
    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;
    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 (*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); //even quoting a '}' it works properly
    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]);
    printf("s%lu\n", stack[i]);
    }
    break;
    case TYPE_NULL:
    printf("%lu (null)", stack[i]);
    printf("%lu(null)", stack[i]);
    break;
    default:
    printf("%lu %c\n", stack[i], typestack[i]);
    printf("%c%lu\n", typestack[i], stack[i]);
    }
    }
    return 0;
    }
    }
  3. Capaverde created this gist Mar 12, 2018.
    781 changes: 781 additions & 0 deletions heap.c
    Original 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;
    }