// Version 0.0.1 BETA published under the GNU license // Written by Gerson Kurz (Gerson.Kurz@t-online.de) // Sorry, code isn't obfuscated yet... WIll do so for the release version. #include "string.h" #include "stdio.h" #include "stdlib.h" #include "time.h" #define IFEQ(EXPRESSION,LABEL) \ if EXPRESSION goto LABEL; //"125 " Add argument [0] to argument [1] #define IC_ADD 1638 //"11 6" Divide argument [0] by argument [1] #define IC_DIV 1568 //"12 4" Subtract argument [1] from argument [0] #define IC_SUB 1687 //"131 " Multiply argument [0] with argument [1] #define IC_MUL 1715 //"13 2" NAND argument[0] with argument[1] #define IC_NAND 1806 //"16 " [two spaces] Assign argument[0] to argument[1] #define IC_SET 2177 //"1 1 " This function will output argument [0] as single ascii character. #define IC_OUTC 2562 //"60 " This function will input one ascii character and return it. Both input arguments are ignored. #define IC_INC 8106 //"1 00" Execute argument[0], then argument[1], returns * always. This is the queueing function for instructions. #define IC_EXEC2 2541 //"61 8" While argument[0], execute argument[1] #define IC_WHILE 8225 //"60 3" Define a new function which has a 90% chance of executing argument[0], and a 10% chance of executing argument[1]. #define IC_FUNCDEF 8099 //"5 5" Compare argument[0], argument[1] #define IC_CMP 7980 //"5 60" If both arguments last compared were equal, execute argument[0], else argument[1] #define IC_IFEQ 7931 //"5 67" If argument[0] was less than argument [1], execute argument[0], else argument[1] #define IC_IFLT 7938 //"119 " If argument 0 is a random number (more specifically: was created by a failure of a function to return the correct result), return argument 1, otherwise return argument 0. #define IC_SECURE 1561 #define IC_VARDEC 2548 #define IC_VARUSE 1008 #define IC_RANDOM_NUMBER 1 // TOKEN:* #define IC_REPEAT_ARGUMENT 2 // TOKEN:_ #define IC_ARGUMENT_1 3 // TOKEN:+ #define IC_ARGUMENT_2 4 // TOKEN:- // 11 6/*/_\ */ // IC_DIV SEP IC_RANDOM SEP IC_REPEAT SEP. #define MAX_INSTRUCTION_CODE_ARRAY 128 #define MAX_INSTRUCTION_PER_ARRAY 1024 typedef struct s_instruction instruction; struct s_instruction { long code; long value; long name; long label; long function; // instruction queue instruction* next; instruction* prev; // argument queue instruction* first; instruction* last; }; typedef struct s_instruction_array instruction_array; struct s_instruction_array { int n_used; instruction a[MAX_INSTRUCTION_PER_ARRAY]; }; typedef struct s_variable { struct s_variable* next; long name; long size; long* data; } variable; variable* root_variable = 0; instruction_array* code_array[MAX_INSTRUCTION_CODE_ARRAY]; int n_code_array_used = -1; long seedX,seedK; void INITIALIZE_RANDOM_NUMBERS() { seedX = time(0) ^ 902531011L; } // this is park & miller standard RNG with addons from "Numerical Recipes in C" long RANDOM_NUMBER() { seedX ^= 1013904223L; seedK = seedX/127773; seedX = 16807*(seedX-seedK*127773)-2836*seedX; seedX ^= 1013904223L; return seedX; } void reset_instruction_data() { int i = 0; while( i < n_code_array_used ) free(code_array[i++]); while( root_variable ) { variable* temp = root_variable->next; free(root_variable); root_variable = temp; } n_code_array_used = -1; } int is_whitespace(char c) { return (c == '-') || (c == '\r') || (c == '\n') || ((c >= 'A') && (c <= 'Z') && (c != 'E') && (c != 'S')); } long* find_variable(long name, long index) { static long unused; variable* p = root_variable; while( p ) { if( p->name == name ) { if( (index >= 0) && (index < p->size) ) { return &(p->data[index]); } } p = p->next; } unused = RANDOM_NUMBER(); return &unused; } variable* allocate_variable(long name, long size) { long* data = malloc(sizeof(long)*size); if( data ) { variable* p = malloc(sizeof(variable)); if( p ) { p->data = data; p->name = name; p->size = size; p->next = root_variable; root_variable = p; return p; } free(data); } return 0; } instruction* allocate_instruction() { if( (n_code_array_used != -1) && code_array[n_code_array_used] && ( code_array[n_code_array_used]->n_used < MAX_INSTRUCTION_CODE_ARRAY ) ) return &(code_array[n_code_array_used]->a[code_array[n_code_array_used]->n_used++]); if( n_code_array_used < MAX_INSTRUCTION_CODE_ARRAY) { code_array[++n_code_array_used] = calloc(sizeof(instruction_array),1); return &(code_array[n_code_array_used]->a[code_array[n_code_array_used]->n_used++]); } return 0; } instruction* create_instruction(long code,instruction* p) { if( p ) { p->code = code; if( code >= 7 ) { p->first = allocate_instruction(); p->last = allocate_instruction(); p->first->next = p->last; p->last->prev = p->first; } } return p; } int last_argument_was_wrong = 0; long run_recursive(instruction* p) { long a,b; variable* v; a = RANDOM_NUMBER(); if( a % 1000 == 7 ) { last_argument_was_wrong = 32; return a; } switch(p->code) { case IC_RANDOM_NUMBER: p->value = RANDOM_NUMBER(); break; case IC_REPEAT_ARGUMENT: p->value = ( p->prev ) ? p->prev->value : RANDOM_NUMBER(); break; case IC_ADD: a = run_recursive(p->first); b = run_recursive(p->last); p->value = a+b; break; case IC_DIV: a = run_recursive(p->first); b = run_recursive(p->last); p->value = b ? a / b : RANDOM_NUMBER(); break; case IC_OUTC: putchar(run_recursive(p->first)); p->value = 1; break; case IC_SUB: a = run_recursive(p->first); b = run_recursive(p->last); p->value = a-b; break; case IC_MUL: a = run_recursive(p->first); b = run_recursive(p->last); p->value = a*b; break; case IC_NAND: a = run_recursive(p->first) ? 1 : 0; b = run_recursive(p->last) ? 1 : 0; p->value = (~a)&&(~b); break; case IC_VARDEC: a = run_recursive(p->first); b = run_recursive(p->last); v = allocate_variable(b,a); if( !v ) { printf( "ELVIS HAS REALLY LEFT THE BUILDING, YOU KNOW" ); getchar(); p->value = 0; } else { p->value = 1; } break; case IC_VARUSE: a = run_recursive(p->first); b = run_recursive(p->last); p->value = *find_variable(a,b); break; case IC_SET: a = run_recursive(p->first); if( p->last->code == IC_VARUSE ) { long c; c = run_recursive(p->last->first); b = run_recursive(p->last->last); *find_variable(c,b) = a; } else { printf( "RUNTIME ERROR #%d", RANDOM_NUMBER() ); } /* //"16 " [two spaces] Assign argument[0] to argument[1] #define IC_SET 2177 //"1 1 " This function will output argument [0] as single ascii character. #define IC_OUTC 2562 //"60 " This function will input one ascii character and return it. Both input arguments are ignored. #define IC_INC 8106 //"1 00" Execute argument[0], then argument[1], returns * always. This is the queueing function for instructions. #define IC_EXEC2 2541 //"61 8" While argument[0], execute argument[1] #define IC_WHILE 8225 //"60 3" Define a new function which has a 90% chance of executing argument[0], and a 10% chance of executing argument[1]. #define IC_FUNCDEF 8099 //"5 5" Compare argument[0], argument[1] #define IC_CMP 7980 //"5 60" If both arguments last compared were equal, execute argument[0], else argument[1] #define IC_IFEQ 7931 //"5 67" If argument[0] was less than argument [1], execute argument[0], else argument[1] #define IC_IFLT 7938 //"119 " If argument 0 is a random number (more specifically: was created by a failure of a function to return the correct result), return argument 1, otherwise return argument 0. #define IC_SECURE 1561 */ case IC_SECURE: last_argument_was_wrong = 0; p->value = run_recursive(p->first); if( last_argument_was_wrong ) { p->value = run_recursive(p->last); } else last_argument_was_wrong = 0; } if( last_argument_was_wrong ) last_argument_was_wrong--; return p->value; } long run(instruction* p) { long result; while( p ) { result = run_recursive(p); p = p->next; } return result; } long eleven2dec( char* representation ) { long result = 0, digit; char c; a: c = *(representation++); if( c == 0 ) goto b; if( c == ' ') digit = 10; else digit = c - '0'; result = result*11 + digit; goto a; b: return result; } char* dec2eleven( long number ) { static char representation[80]; char* p = representation; while( number ) { long r = number % 11; if( r < 10 ) *(p++) = '0' + (char) r; else *(p++) = ' '; number /= 11; } *p = 0; _strrev(representation); return representation; } int alternating_syntax_switch = 0; void dump_source_recursive(FILE* fp,instruction* p) { switch(p->code) { case IC_RANDOM_NUMBER: fputc('*',fp); break; case IC_REPEAT_ARGUMENT: fputc('_',fp); break; default: fputs(dec2eleven(p->code),fp); if(alternating_syntax_switch) { fputc('=',fp); dump_source_recursive(fp,p->first); fputc('+',fp); dump_source_recursive(fp,p->last); fputc('.',fp); } else { fputc('/',fp); dump_source_recursive(fp,p->first); fputc('/',fp); dump_source_recursive(fp,p->last); fputc('\\',fp); } } alternating_syntax_switch = ~alternating_syntax_switch; } void dump_source(char* filename,instruction* p) { FILE* fp = filename ? fopen(filename,"wt") : stdout; if( fp ) { while( p ) { dump_source_recursive(fp,p); p = p->next; } if( filename) fclose(fp); } } void create_number_zero(instruction* q) { instruction* p; create_instruction(IC_SECURE,q); p = q->first; create_instruction(IC_SUB,p); create_instruction(IC_RANDOM_NUMBER,p->first); create_instruction(IC_REPEAT_ARGUMENT,p->last); p = q->last; create_instruction(IC_SUB,p); create_instruction(IC_NAND,p->first); create_instruction(IC_RANDOM_NUMBER,p->first->first); create_instruction(IC_RANDOM_NUMBER,p->first->last); create_instruction(IC_REPEAT_ARGUMENT,p->last); } void create_number_one(instruction* q) { instruction* p; create_instruction(IC_SECURE,q); p = q->first; create_instruction(IC_DIV,p); create_instruction(IC_RANDOM_NUMBER,p->first); create_instruction(IC_REPEAT_ARGUMENT,p->last); p = q->last; create_instruction(IC_NAND,p); create_instruction(IC_RANDOM_NUMBER,p->first); create_instruction(IC_REPEAT_ARGUMENT,p->last); } void create_number_two(instruction* q) { instruction* p; create_instruction(IC_SECURE,q); p = q->first; create_instruction(IC_ADD,p); create_instruction(IC_DIV,p->first); create_instruction(IC_RANDOM_NUMBER,p->first->first); create_instruction(IC_REPEAT_ARGUMENT,p->first->last); create_instruction(IC_REPEAT_ARGUMENT,p->last); p = q->last; create_instruction(IC_ADD,p); create_instruction(IC_NAND,p->first); create_instruction(IC_RANDOM_NUMBER,p->first->first); create_instruction(IC_REPEAT_ARGUMENT,p->first->last); create_instruction(IC_REPEAT_ARGUMENT,p->last); } char *wp, *rp; int product() { if( *rp == '1' ) { *(wp++) = '1'; *wp = 0; rp++; return 1; } if( *rp == '0' ) { *(wp++) = '0'; *wp = 0; rp++; return 1; } if( *rp == '2' ) { int closing_brackets = 0, i; rp++; if( *rp != '*' ) { *(wp++) = '2'; *wp = 0; return 1; } *(wp++) = '*'; *(wp++) = '('; *(wp++) = '2'; *(wp++) = ','; closing_brackets++; while( *rp == '*' ) { if( rp[2] != '*' ) { *(wp++) = '2'; rp+=2; break; } *(wp++) = '*'; *(wp++) = '('; *(wp++) = '2'; *(wp++) = ','; closing_brackets++; rp+=2; } for( i = 0; i < closing_brackets; i++ ) *(wp++) = ')'; *wp = 0; return 1; } return 0; } char* create_number_parser( char* expression ) { static char result[256],a0[256],a1[256],*op; rp = expression; result[0] = a0[0] = a1[0] = 0; wp = a0; if( product() ) { int closing_brackets = 0, i; if( *rp != '+' ) return a0; result[0] = 0; do { if( *rp ) rp++; op = rp; wp = a1; if( !product() ) { sprintf( result+strlen(result), "%s", a0 ); break; } rp = op; sprintf( result+strlen(result), "+(%s,", a0 ); wp = a0; closing_brackets++; } while( product() ); wp = result+strlen(result); for( i = 0; i < closing_brackets; i++ ) *(wp++) = ')'; *wp = 0; return result; } return 0; } char* create_number_code( long h ) { static char buffer[256], *p; int i, j; p = buffer; *p = 0; i = 0; if( h <= 2 ) { buffer[0] = h + '0'; buffer[1] = 0; return buffer; } while(h) { if(h%2) { if( buffer[0] ) *(p++) = '+'; if(i) { for( j=0; j>=1; } *p = 0; return buffer; } instruction* create_number_instruction_recursive(instruction* p) { if( *rp == '0' ) { rp++; create_number_zero(p); return p; } if( *rp == '1' ) { rp++; create_number_one(p); return p; } if( *rp == '2' ) { rp++; create_number_two(p); return p; } if( *rp == '+' || *rp == '*' ) { create_instruction((*rp == '*') ? IC_MUL : IC_ADD,p); rp++; if( *rp == '(' ) { rp++; if( !create_number_instruction_recursive(p->first)) return 0; if( *rp == ',' ) { rp++; if( !create_number_instruction_recursive(p->last) ) return 0; if( *rp == ')' ) { rp++; return p; } } } } return 0; } instruction* create_number_instruction(char* expression) { instruction* result = allocate_instruction(); rp = expression; create_number_instruction_recursive(result); return result; } //JAVA2K Sourcecode FUNCTION {FUNCTION}. //ARGUMENT FUNCTION | '+' | '-' | '_' | '*' | VARIABLE. //VARIABLE NAME "?". char* rp = 0; int ELEVEN_BASED_DIGIT(int* digit) { if( (*rp >= '0') && (*rp <= '9') ) { *digit = *rp - '0'; rp++; return 1; } if( *rp == ' ' ) { *digit = 10; rp++; return 1; } return 0; } // global variables RULE long last_known_result = 0; int NAME(long* result, int check_for_valid_name ) { int digit; last_known_result = -1; if( ELEVEN_BASED_DIGIT(&digit) ) { *result = digit; while( ELEVEN_BASED_DIGIT(&digit) ) *result = *result *11 + digit; last_known_result = *result; return check_for_valid_name ? ((*result % 7) == 0): 1; } return 0; } int ARGUMENT(instruction* p); int FUNCTION(instruction* p) { char* op = rp; if( NAME(&(p->code),1) ) { if( *rp == '/' ) { rp++; p->first = allocate_instruction(); if( ARGUMENT(p->first) ) { if( *rp == '/' ) { rp++; p->last = allocate_instruction(); if( ARGUMENT(p->last) ) { if( *rp == '\\' ) { rp++; p->last->prev = p->first; p->first->next = p->last; return 1; } } } } } else if( *rp == '=' ) { rp++; p->last = allocate_instruction(); if( ARGUMENT(p->last) ) { if( *rp == '+' ) { rp++; p->first = allocate_instruction(); if( ARGUMENT(p->first) ) { if( *rp == '.' ) { rp++; p->last->prev = p->first; p->first->next = p->last; return 1; } } } } } } else if( last_known_result >= 0 ) { long name,label,function; name = last_known_result; if( strncmp(rp, "<=>~(", 5 ) == 0 ) { rp+=5; if( NAME(&label,0) ) { if( *rp == '*' ) { rp++; if( NAME(&function,0) ) { if( strncmp(rp,");",2) == 0 ) { rp+=2; return 1; } } } } } } rp = op; return 0; } int ARGUMENT(instruction* p) { int i; static int ics[] = { IC_ARGUMENT_1, IC_ARGUMENT_2, IC_REPEAT_ARGUMENT, IC_RANDOM_NUMBER }; static char ccs[] = "+-_*"; for( i = 0; ccs[i]; i++ ) { if( *rp == ccs[i] ) { rp++; p->code = ics[i]; return 1; } } if( FUNCTION(p) ) return 1; return 0; } long current_name = 0; instruction* read_line(instruction* previous_instruction) { current_name = 0; if( previous_instruction == 0 ) { previous_instruction = allocate_instruction(); previous_instruction->name = current_name++; } else { previous_instruction->next = allocate_instruction(); previous_instruction->next->prev = previous_instruction; previous_instruction = previous_instruction->next; previous_instruction->name = current_name++; } return FUNCTION(previous_instruction) ? previous_instruction : 0; } instruction* read_source(char* filename) { FILE* fp = fopen(filename,"rt"); if(fp) { instruction* result, *ip; char* buffer = calloc(1,70000), *write_pos,*read_pos, *line = calloc(1,1024); write_pos = buffer; while( !feof(fp) && fgets(line,1024,fp) ) { read_pos = line; while( *read_pos ) { if( !is_whitespace(*read_pos) ) { *(write_pos++) = *read_pos; } read_pos++; } *write_pos = 0; } fclose(fp); reset_instruction_data(); rp = buffer; result = 0; ip = 0; while(1) { if( !*rp ) break; ip = read_line(ip); if( !result ) result = ip; if( !ip ) { printf( "SYNTAX ERROR SOMEWHERE\n" ); break; } } free(buffer); return result; } return 0; } int main( int argc, char* argv[] ) { char buffer[256],*q; long number; argc = 0; printf( "ELVIS HAS LEFT THE BUILDING: "); L0000: gets(buffer); IFEQ((buffer[0] != '~'),L0001) number = atol(buffer+1); if( number%7 == 0) putchar('*'); printf( "%s^", dec2eleven( atol(buffer+1) )); goto L0000; L0001: IFEQ((buffer[0] != '/'),L0002) number = eleven2dec(buffer+1); if( number%7 == 0) putchar('*'); printf( "%ld", number); goto L0000; L0002: IFEQ((buffer[0] != '?'),L0003) printf( "REQUIRED FILE MISSING."); goto L0000; L0003: IFEQ((buffer[0] != '!'),L0004) printf( "%s", create_number_code(atol(buffer+1))); goto L0000; L0004: IFEQ((buffer[0] != '#'),L0005) q = strchr(buffer,','); if( q ) { rp = q+1; if( NAME(&number,1) ) { *q = 0; reset_instruction_data(); argc = 0; dump_source(q+1,create_number_instruction(create_number_parser(create_number_code(atol(buffer+1))))); } } else { reset_instruction_data(); argc = 0; dump_source(0,create_number_instruction(create_number_parser(create_number_code(atol(buffer+1))))); } goto L0000; L0005: IFEQ((buffer[0] != 'D'),L0006) IFEQ((!argc),L0000) *((int*)0) = *((int*)0); exit(-1); L0006: rp = buffer; if( NAME(&number,1) ) { instruction* p; p = read_source(buffer); if( p ) { run(p); argc = 1; } } goto L0000; return 0; } // main()