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

★ /prog/ Challenge Vol. 5 ★

Name: Anonymous 2010-06-11 23:51

The challenge suggestion thread was too busy going nowhere, and I feel like writing some code, so here is a /prog/ challenge.

THE CHALLENGE:
Design a toy programming language. You may implement either a compiler or interpreter, and you may write the implementation in any language of your choosing.

Post the source code to your implementation as well as programs in your language to accomplish at least two of the following tasks, plus one ``wild card'' program not listed here.

    • Factorial calculator
    • Fibonacci sequence generator
    • Prime number sieve (e.g. Eratosthenes, Atkin, etc.)
    • fgrep (output lines of input containing a given string)
    • Caesar cipher
    • Simple interactive calculator
    • Tic-tac-toe (AI not required)
    • The game of Nim (http://en.wikipedia.org/wiki/Nim)

Entries must be submitted prior to 2010-06-21 00:00, which gives one full week and two weekends. Judgment will be in three categories: presentation and cleverness of designed language, clarity of implementation, and overall usefulness/entertainment/trolling value of the ``wild card'' program.

Winner will receive ten Susscoins, to be transferred via /prog/mail.

Name: Anonymous 2010-06-12 8:38

EXPERT C SOLUTION. Work in progress. Currently solutions for problem 1 and 2.


/*   turd.c
 *
 *   turd language interpreter v0.01
 *
 *   Released under the GPL v3
 *
 *   Copyright (C)  (name withheld)
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define TYPE_UNKNOWN    0
#define TYPE_VAR        1
#define TYPE_BUILTIN    2
#define TYPE_FUNC        3

#define VAR_UNKNOWN        0
#define VAR_INT            1
#define VAR_STR            2

typedef struct {
    int type;
    int subtype;
    int iv;
    char *sv;
    int (*builtin)(int,char*);
} obj_t;

obj_t OBJ[128];
char *BUF[1024]; // 1024 lines max
int LINE;
char GOTO = 0;
int DEBUG = 0;

int *RI(char *s) {
    if(DEBUG) printf("RI: %s\n",s);
    static int I;
    I=0;
    if(isalpha(*s)) {
        if(OBJ[*s].type==TYPE_VAR) {
            switch(OBJ[*s].subtype) {
                case VAR_INT: I = OBJ[*s].iv; break;
                case VAR_STR: I = atoi(OBJ[*s].sv); break;
            }
        }
    } else {
        I = atoi(s);
    }
    return &I;
}

#define BUILTIN(n)    int builtin_ ## n (int v, char *s)
#define SET_BUILTIN(o,b) OBJ[o].type = TYPE_BUILTIN; OBJ[o].builtin = builtin_ ## b

BUILTIN(assign_int) {
    OBJ[v].iv = *RI(s);
    OBJ[v].type = TYPE_VAR;
    OBJ[v].subtype = VAR_INT;
    //printf("assign int: %c = %d\n",v,OBJ[v].iv);
    return 0;
}

BUILTIN(assign_str) {
    OBJ[v].type = TYPE_VAR;
    OBJ[v].subtype = VAR_STR;
    free(OBJ[v].sv);
    OBJ[v].sv = strdup(s);
    if(DEBUG) printf("assign str: %c = \"%s\"\n",v,OBJ[v].sv);
    return 0;
}

int *arithmetic_prepare(int v, char *s, int *c) {
    char *p,*f;
    int i;
    static int a[32];
    f = s = strdup(s);
    if(*s=='=') {
        // TODO verify current type
        if(DEBUG) printf("arithmetic: reflexive\n");
        s++;
    } else {
        if(DEBUG) printf("arithmetic: non-reflexive\n");
        OBJ[v].iv;
    }
    for(i=0;i<31;i++) {
        if((p = strchr(s,',')))
            *p++ = 0;
        a[i]=*RI(s);
        if(DEBUG) printf("list %02d: %d\n",i,a[i]);
        if(!p)
            break;
        s = p;
    }
END:
    OBJ[v].type = TYPE_VAR;
    OBJ[v].subtype = VAR_INT;
    if(*f=='=') {
        // reflexive
        *c = i+1;
        if(DEBUG) printf("list: return count %d\n",*c);
        free(f);
        return a;
    }
    free(f);
    *c = i;
    if(DEBUG) printf("list: return count %d\n",*c);
    OBJ[v].iv = a[0];
    return a+1;
}

BUILTIN(add) {
    int c,*a = arithmetic_prepare(v,s,&c);
    while(c--) { OBJ[v].iv += *a++; }
    if(DEBUG) printf("plus: result %c = %d\n",v,OBJ[v].iv);
    return 0;
}
BUILTIN(subtract) {
    int c, *a = arithmetic_prepare(v,s,&c);
    while(c--) { OBJ[v].iv -= *a++; }
    if(DEBUG) printf("subtract: result %c = %d\n",v,OBJ[v].iv);
    return 0;
}
BUILTIN(multiply) {
    int c, *a = arithmetic_prepare(v,s,&c);
    while(c--) { OBJ[v].iv *= *a++; }
    if(DEBUG) printf("multiply: result %c = %d\n",v,OBJ[v].iv);
    return 0;
}
BUILTIN(divide) {
    int n=0, c, *a = arithmetic_prepare(v,s,&c);
    while(*a) { n += *a; a++; }
    OBJ[v].iv = n;
    //printf("plus: result %c = %d\n",v,OBJ[v].iv);
    return 0;
}

BUILTIN(goto) {
    int l;
    char *p;
    if(v=='X') {
        exit(atoi(s));
    }
    for(l=0;l<1024;l++) {
        p = BUF[l];
        if(!p)
            break;
        if(*p++!='@')
            continue;
        if(v!=*p)
            continue;
        LINE = l;
        return 0;
    }
    printf("error: label not found: @%C\n",v);
    return -1;
}

BUILTIN(print) {
    /* TODO: parse \n etc and do not force newline */
    switch(OBJ[v].type) {
        case TYPE_VAR:
            switch(OBJ[v].subtype) {
                case VAR_INT: printf("%d\n",OBJ[v].iv); break;
                case VAR_STR: printf("%s\n",OBJ[v].sv); break;
            }
            break;
    }
    return 0;
}

BUILTIN(if) {
    static char a[256];
    strcpy(a,s);
    char *p = strrchr(a,'@');
    if(!p) {
        printf("error: expecting @ for ?\n");
        return -1;
    }
    *p++ = 0;
    GOTO = *p;
    switch(OBJ[v].type) {
        case TYPE_VAR:
            switch(OBJ[v].subtype) {
                case VAR_INT:
                    switch(*a) {
                        case '=':
                            return (OBJ[v].iv == *RI(a+1));
                        case '<':
                        case '>':
                            // TODO
                            break;
                    }
                case VAR_STR:
                    return (strcmp(OBJ[v].sv,s)==0);
            }
            break;
    }
    return -1;
}


int main(int argc, char **argv) {
    char *s,*p,op;
    int i,r=0;
    FILE *f = stdin;
    memset(OBJ,0,sizeof(OBJ));
    memset(BUF,0,sizeof(BUF));

    SET_BUILTIN('#',assign_int);
    SET_BUILTIN(':',assign_str);
    SET_BUILTIN('+',add);
    SET_BUILTIN('-',subtract);
    SET_BUILTIN('*',multiply);
    SET_BUILTIN('/',divide);
    SET_BUILTIN('>',print);
    SET_BUILTIN('@',goto);
    SET_BUILTIN('?',if);

    builtin_assign_str('Z',argv[0]);
    for(i=1;i<argc;i++) {
        printf("argv[%d]: %s\n",i,argv[i]);
        if(i==1 && strcmp(argv[1],"-f")==0) {
            f = NULL;
            if(argv[2]) {
                f = fopen(argv[2],"r");
            }
            if(!f) {
                printf("error: failed to open file\n");
                return 1;
            }
            printf("opened file %s\n",argv[2]);
            i++;
            r = 2;
            continue;
        }
        builtin_assign_str('@'+(i-r),argv[i]);
    }

    for(LINE=0;LINE<1024;LINE++) {
        s = malloc(256);
        if(!fgets(s,256,f))
            break;
        if((p = strchr(s,'\n')))
            *p = 0;
        while(isspace(*s))
            s++;
        BUF[LINE] = s;
    }

    for(LINE=0;LINE<1024;LINE++) {
        s = BUF[LINE];
        if(!s)
            break;
        if(DEBUG) printf("===========================\n");
        if(DEBUG) printf("line: %s\n",s);
        switch(*s) {
            case 0:        continue; //blank line
            case '#':    continue; //comment line
            case '@':    continue;  //goto label
            default:    break;
        }
        if(!isalpha(*s)) {
            printf("error: unexpected (%C)\n",*s);
            break;
        }
        op = s[1];
        if(OBJ[op].type!=TYPE_BUILTIN) {
            printf("error: invalid instruction (%C)\n",op);
            break;
        }
        r = OBJ[op].builtin(*s,s+2);
        if(r<0) {
            if(DEBUG) printf("exiting due to error\n");
            return 1;
        }
        if(r>0) {
            if(GOTO) {
                builtin_goto(GOTO,"");
                GOTO = 0;
            }
        }
    }
    return 0;
}


---------------

#!/change/to/your/path/turd -f

# factorial.turd
#

# Create integer n with value of command line argument 1 (A)
n#A

# Create integer a with value of n
a#n

# Label L
@L

# Decrement n
n-=1

# If n = 1 goto @E
n?=1@E

# Derp
a*=n

# Goto @L
L@

# Label @E
@E

# Print a to stdout
a>

------------

#!/path/turd -f
#
# Fibonacci sequence generator. Pass number of terms as
# command line argument

a#0
b#1
a>
b>

@L
n+=1
n?=A@X
c+a,b
c>
a#b
b#c
L@

Name: Anonymous 2010-06-13 6:30

BIG NEWS EVERYBODY

turd 0.02 released

now with fibs, fact, and prime sieve

http://www.zshare.net/download/77182774740b729e

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