You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SQA-Homework/afl_fuzz/tests/BASIC/token.cc

907 lines
18 KiB

void prints(char *);
void printd(int);
void inputs(char *, int);
int inputd();
void *malloc(int);
int INT_TOKEN;
int STR_TOKEN;
int VAR_TOKEN;
int SUBSTRING;
int STRFUNC;
int PLUS;
int MINUS;
int MULTIPLY;
int DIVIDE;
int EQUALS;
int GREATER_THAN;
int LESS_THAN;
int NOT_EQUALS;
int AND;
int OR;
//Variable types
int INTVAR;
int STRVAR;
int PRINT;
int INPUT;
int INPUTSTR;
int RUN;
int END;
int IF;
int WHILE;
int LET;
int DIM;
int GOSUB;
int GOTO;
int RETURN;
int LIST;
int error;
void init_tokens(){
INT_TOKEN = 1;
STR_TOKEN = 2;
SUBSTRING = 3;
STRFUNC = 4;
PLUS = 5;
MINUS = 6;
MULTIPLY = 7;
DIVIDE = 8;
EQUALS = 9;
GREATER_THAN = 10;
LESS_THAN = 11;
NOT_EQUALS = 12;
AND = 13;
OR = 14;
VAR_TOKEN = 15;
INTVAR = 0;
STRVAR = 1;
PRINT = 1;
INPUT = 2;
INPUTSTR = 3;
RUN = 4;
END = 5;
IF = 6;
WHILE = 7;
DIM = 8;
GOSUB = 9;
GOTO = 10;
RETURN = 11;
LIST = 12;
}
int alpha(char c){
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
int digit(char c){
return c >= '0' && c <= '9';
}
void skip_whitespace(char **c){
while(**c && (**c == ' ' || **c == '\t' || **c == '\n'))
*c = *c + 1;
}
int strcmp(char *a, char *b){
while(*a && *a == *b){
a = a + 1;
b = b + 1;
}
return *b - *a;
}
void *create_variable(int type, void *values, int num_elements){
void **output;
output = kmalloc(POINTER_SIZE*3);
output[0] = (void *) type;
output[1] = values;
output[2] = (void *) num_elements;
return output;
}
void get_word(char *buffer, char **c, int buffer_length){
skip_whitespace(c);
while(buffer_length && (alpha(**c) || digit(**c) || **c == '_')){
*buffer = **c;
buffer = buffer + 1;
*c = *c + 1;
buffer_length = buffer_length - 1;
}
if(!buffer_length)
buffer = buffer - 1;
*buffer = 0;
}
int order_of_operations(int token_type){
if(token_type == PLUS || token_type == MINUS){
return 4;
} else if(token_type == MULTIPLY || token_type == DIVIDE){
return 5;
} else if(token_type == EQUALS || token_type == GREATER_THAN || token_type == LESS_THAN){
return 3;
} else if(token_type == AND){
return 2;
} else if(token_type == OR){
return 1;
}
return 0;
}
void *create_token(int type, void *value1, void *value2){
void *output;
output = kmalloc(POINTER_SIZE*3);
((int *) output)[0] = type;
((void **) output)[1] = value1;
((void **) output)[2] = value2;
return output;
}
int get_int(char **c){
int invert;
int output;
if(**c == '-'){
invert = 1;
*c = *c + 1;
} else {
invert = 0;
}
output = 0;
while(**c >= '0' && **c <= '9'){
output = output*10 + **c - '0';
*c = *c + 1;
}
if(invert)
output = -output;
return output;
}
char *get_str(char **c){
int str_len;
char *temp;
char *output;
str_len = 0;
temp = *c;
while(*temp && *temp != '"'){
str_len = str_len + 1;
temp = temp + 1;
}
output = kmalloc(CHAR_SIZE*(str_len + 1));
temp = output;
while(**c && **c != '"'){
*temp = **c;
*c = *c + 1;
temp = temp + 1;
}
*temp = 0;
return output;
}
void *get_expression(char **c);
void free_expression(void *);
void *get_var(char **c){
char *buffer;
void *index;
buffer = kmalloc(32);
get_word(buffer, c, 32);
skip_whitespace(c);
if(**c == '['){
*c = *c + 1;
index = get_expression(c);
if(**c == ']')
*c = *c + 1;
} else {
index = (void *) 0;
}
return create_token(VAR_TOKEN, buffer, index);
}
void *get_function(char **c, int *err){
char buffer[32];
char *temp;
void *arg1;
void *arg2;
void *arg3;
void **output;
*err = 0;
temp = *c;
get_word(buffer, &temp, 32);
if(!strcmp(buffer, "SUBSTR")){
*c = temp;
skip_whitespace(c);
if(**c == '('){
*c = *c + 1;
} else {
return (void *) 0;
}
arg1 = get_expression(c);
if(**c == ',' && (int) arg1){
*c = *c + 1;
} else {
if((int) arg1)
free_expression(arg1);
*err = 1;
return (void *) 0;
}
arg2 = get_expression(c);
if(**c == ',' && (int) arg2){
*c = *c + 1;
} else {
free_expression(arg1);
if(arg2)
free_expression(arg2);
*err = 1;
return (void *) 0;
}
arg3 = get_expression(c);
if(**c == ')' && (int) arg3){
*c = *c + 1;
} else {
free_expression(arg1);
free_expression(arg2);
if((int) arg3)
free_expression(arg3);
*err = 1;
return (void *) 0;
}
output = kmalloc(POINTER_SIZE*4);
output[0] = (void *) SUBSTRING;
output[1] = arg1;
output[2] = arg2;
output[3] = arg3;
return output;
} else if(!strcmp(buffer, "STR")){
*c = temp;
skip_whitespace(c);
if(**c == '('){
*c = *c + 1;
} else {
return (void *) 0;
}
arg1 = get_expression(c);
if(**c == ')' && (int) arg1){
*c = *c + 1;
} else {
if((int) arg1)
free_expression(arg1);
*err = 1;
return (void *) 0;
}
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) STRFUNC;
output[1] = arg1;
return output;
} else {
return (void *) 0;
}
}
void *get_value(char **c){
char *str;
void *output;
int err;
skip_whitespace(c);
if(**c == '-' || (**c >= '0' && **c <= '9')){
return create_token(INT_TOKEN, (void *) get_int(c), (void *) 0);
} else if(**c == '('){
*c = *c + 1;
output = get_expression(c);
if(**c == ')')
*c = *c + 1;
return output;
} else if(alpha(**c)){
output = get_function(c, &err);
if(err)
return (void *) 0;
if(!output)
return get_var(c);
return output;
} else if(**c == '"'){
*c = *c + 1;
str = get_str(c);
if(**c == '"')
*c = *c + 1;
return create_token(STR_TOKEN, str, (void *) 0);
}
return (void *) 0;
}
int get_operation(char **c){
skip_whitespace(c);
if(**c == '+'){
*c = *c + 1;
return PLUS;
} else if(**c == '-'){
*c = *c + 1;
return MINUS;
} else if(**c == '*'){
*c = *c + 1;
return MULTIPLY;
} else if(**c == '/'){
*c = *c + 1;
return DIVIDE;
} else if(**c == '='){
*c = *c + 1;
return EQUALS;
} else if(**c == '>'){
*c = *c + 1;
return GREATER_THAN;
} else if(**c == '<'){
*c = *c + 1;
return LESS_THAN;
} else if(**c == '!' && *(*c + 1) == '='){
*c = *c + 2;
return NOT_EQUALS;
} else if(**c == '&'){
*c = *c + 1;
return AND;
} else if(**c == '|'){
*c = *c + 1;
return OR;
}
return 0;
}
void *get_expression_recursive(void *output, char **c){
void *value;
int current_operation;
int next_operation;
char *temp;
while(current_operation = get_operation(c)){
value = get_value(c);
if(!(int) value){
free_expression(output);
return (void *) 0;
}
temp = *c;
next_operation = get_operation(&temp);
if(order_of_operations(next_operation) > order_of_operations(current_operation)){
value = get_expression_recursive(value, c);
}
if((int) value){
output = create_token(current_operation, output, value);
} else {
free_expression(output);
return (void *) 0;
}
}
return output;
}
void *get_expression(char **c){
void *value;
value = get_value(c);
if(!(int) value){
return (void *) 0;
}
return get_expression_recursive(value, c);
}
void free_expression(void *expr){
if(((int *) expr)[0] == INT_TOKEN){
kfree(expr);
} else if(((int *) expr)[0] == STR_TOKEN){
kfree(((void **) expr)[1]);
kfree(expr);
} else if(((int *) expr)[0] == VAR_TOKEN){
if((int) ((void **) expr)[2])
free_expression(((void **) expr)[2]);
kfree(((void **) expr)[1]);
kfree(expr);
} else if(((int *) expr)[0] == PLUS || ((int *) expr)[0] == MINUS || ((int *) expr)[0] == MULTIPLY || ((int *) expr)[0] == DIVIDE || ((int *) expr)[0] == EQUALS || ((int *) expr)[0] == NOT_EQUALS || ((int *) expr)[0] == GREATER_THAN || ((int *) expr)[0] == LESS_THAN || ((int *) expr)[0] == AND || ((int *) expr)[0] == OR){
free_expression(((void **) expr)[1]);
free_expression(((void **) expr)[2]);
kfree(expr);
} else if(((int *) expr)[0] == SUBSTRING){
free_expression(((void **) expr)[1]);
free_expression(((void **) expr)[2]);
free_expression(((void **) expr)[3]);
kfree(expr);
} else if(((int *) expr)[0] == STRFUNC){
free_expression(((void **) expr)[1]);
kfree(expr);
}
}
void list_expression(void *expr){
if(((int *) expr)[0] == INT_TOKEN){
printd(((int *) expr)[1]);
} else if(((int *) expr)[0] == STR_TOKEN){
prints("\"");
prints(((char **) expr)[1]);
prints("\"");
} else if(((int *) expr)[0] == VAR_TOKEN){
prints(((char **) expr)[1]);
if(((void **) expr)[2]){
prints("[");
list_expression(((void **) expr)[2]);
prints("]");
}
} else if(((int *) expr)[0] == PLUS){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" + ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == MINUS){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" - ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == MULTIPLY){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" * ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == DIVIDE){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" / ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == EQUALS){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" = ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == NOT_EQUALS){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" != ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == GREATER_THAN){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" > ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == LESS_THAN){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" < ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == AND){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" & ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == OR){
prints("("); list_expression(((void **) expr)[1]); prints(")");
prints(" | ("); list_expression(((void **) expr)[2]); prints(")");
} else if(((int *) expr)[0] == SUBSTRING){
prints("SUBSTR(");
list_expression(((void **) expr)[1]);
prints(", ");
list_expression(((void **) expr)[2]);
prints(", ");
list_expression(((void **) expr)[3]);
prints(")");
} else if(((int *) expr)[0] == STRFUNC){
prints("STR(");
list_expression(((void **) expr)[1]);
prints(")");
}
}
void **parse_print(char **c){
void **output;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) PRINT;
output[1] = get_expression(c);
skip_whitespace(c);
if(!(int) output[1]){
kfree(output);
return (void **) 0;
} else if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_print(void **statement){
prints("PRINT ");
list_expression(statement[1]);
}
void **parse_input(char **c){
void **output;
skip_whitespace(c);
if(!alpha(**c))
return (void **) 0;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) INPUT;
output[1] = get_var(c);
skip_whitespace(c);
if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_input(void **statement){
prints("INPUT ");
list_expression(statement[1]);
}
void **parse_inputstr(char **c){
void **output;
skip_whitespace(c);
if(!alpha(**c))
return (void **) 0;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) INPUTSTR;
output[1] = get_var(c);
skip_whitespace(c);
if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_inputstr(void **statement){
prints("INPUTSTR ");
list_expression(statement[1]);
}
void **parse_let(char **c){
void **output;
skip_whitespace(c);
if(!alpha(**c))
return (void **) 0;
output = kmalloc(POINTER_SIZE*3);
output[0] = (void *) LET;
output[1] = get_var(c);
skip_whitespace(c);
if(**c != '='){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
*c = *c + 1;
skip_whitespace(c);
output[2] = get_expression(c);
if(**c || !(int) output[2]){
free_expression(output[1]);
if((int) output[2])
free_expression(output[2]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_let(void **statement){
prints("LET ");
list_expression(statement[1]);
prints(" = ");
list_expression(statement[2]);
}
void **parse_dim(char **c){
void **output;
skip_whitespace(c);
if(!alpha(**c))
return (void **) 0;
output = kmalloc(POINTER_SIZE*3);
output[0] = (void *) DIM;
output[1] = get_var(c);
skip_whitespace(c);
if(**c != ','){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
*c = *c + 1;
skip_whitespace(c);
output[2] = get_expression(c);
skip_whitespace(c);
if(**c || !(int) output[2]){
free_expression(output[1]);
if((int) output[2])
free_expression(output[2]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_dim(void **statement){
prints("DIM ");
list_expression(statement[1]);
prints(", ");
list_expression(statement[2]);
}
void **parse_if(char **c){
void **output;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) IF;
output[1] = get_expression(c);
skip_whitespace(c);
if(!(int) output[1]){
kfree(output);
return (void **) 0;
} else if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_if(void **statement){
prints("IF ");
list_expression(statement[1]);
}
void **parse_goto(char **c){
void **output;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) GOTO;
output[1] = get_expression(c);
skip_whitespace(c);
if(!(int) output[1]){
kfree(output);
return (void **) 0;
} else if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_goto(void **statement){
prints("GOTO ");
list_expression(statement[1]);
}
void **parse_gosub(char **c){
void **output;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) GOSUB;
output[1] = get_expression(c);
skip_whitespace(c);
if(!(int) output[1]){
kfree(output);
return (void **) 0;
} else if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_gosub(void **statement){
prints("GOSUB ");
list_expression(statement[1]);
}
void **parse_while(char **c){
void **output;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) WHILE;
output[1] = get_expression(c);
skip_whitespace(c);
if(!(int) output[1]){
kfree(output);
return (void **) 0;
} else if(**c){
free_expression(output[1]);
kfree(output);
return (void **) 0;
}
return output;
}
void list_while(void **statement){
prints("WHILE ");
list_expression(statement[1]);
}
void **parse_run(char **c){
void **output;
skip_whitespace(c);
if(**c)
return (void **) 0;
output = kmalloc(POINTER_SIZE);
output[0] = (void *) RUN;
return output;
}
void list_run(void **statement){
prints("RUN");
}
void **parse_end(char **c){
void **output;
char buffer[32];
skip_whitespace(c);
if(!**c){
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) END;
output[1] = (void *) 0;
return output;
}
get_word(buffer, c, 32);
skip_whitespace(c);
if(**c)
return (void **) 0;
output = kmalloc(POINTER_SIZE*2);
output[0] = (void *) END;
if(!strcmp(buffer, "IF"))
output[1] = (void *) IF;
else if(!strcmp(buffer, "WHILE"))
output[1] = (void *) WHILE;
else {
kfree(output);
return (void **) 0;
}
return output;
}
void list_end(void **statement){
if(statement[1] == (void *) IF){
prints("END IF");
} else if(statement[1] == (void *) WHILE){
prints("END WHILE");
} else {
prints("END");
}
}
void **parse_return(char **c){
void **output;
skip_whitespace(c);
if(!**c){
output = kmalloc(POINTER_SIZE);
output[0] = (void *) RETURN;
return output;
}
return (void **) 0;
}
void list_return(void **statement){
prints("RETURN");
}
void **parse_list(char **c){
void **output;
skip_whitespace(c);
if(!**c){
output = kmalloc(POINTER_SIZE);
output[0] = (void *) LIST;
return output;
}
return (void **) 0;
}
void list_list(void **statement){
prints("LIST");
}
void **get_statement(char **c){
char buffer[32];
get_word(buffer, c, 32);
if(!strcmp(buffer, "PRINT"))
return parse_print(c);
else if(!strcmp(buffer, "INPUT"))
return parse_input(c);
else if(!strcmp(buffer, "INPUTSTR"))
return parse_inputstr(c);
else if(!strcmp(buffer, "RUN"))
return parse_run(c);
else if(!strcmp(buffer, "END"))
return parse_end(c);
else if(!strcmp(buffer, "IF"))
return parse_if(c);
else if(!strcmp(buffer, "WHILE"))
return parse_while(c);
else if(!strcmp(buffer, "LET"))
return parse_let(c);
else if(!strcmp(buffer, "DIM"))
return parse_dim(c);
else if(!strcmp(buffer, "GOTO"))
return parse_goto(c);
else if(!strcmp(buffer, "GOSUB"))
return parse_gosub(c);
else if(!strcmp(buffer, "RETURN"))
return parse_return(c);
else if(!strcmp(buffer, "LIST"))
return parse_list(c);
else
return (void **) 0;
}
void free_statement(void **statement){
if((int) statement[0] == PRINT){
free_expression(statement[1]);
kfree(statement);
} else if((int) statement[0] == INPUT){
if(((int *) statement[1])[2])
free_expression(((void **) statement[1])[2]);
kfree(((void **) statement[1])[1]);
kfree(statement[1]);
kfree(statement);
} else if((int) statement[0] == RUN){
kfree(statement);
} else if((int) statement[0] == END){
kfree(statement);
} else if((int) statement[0] == IF){
free_expression(statement[1]);
kfree(statement);
} else if((int) statement[0] == WHILE){
free_expression(statement[1]);
kfree(statement);
} else if((int) statement[0] == LET){
free_expression(statement[1]);
free_expression(statement[2]);
kfree(statement);
} else if((int) statement[0] == DIM){
free_expression(statement[1]);
free_expression(statement[2]);
kfree(statement);
} else if((int) statement[0] == GOTO){
free_expression(statement[1]);
kfree(statement);
} else if((int) statement[0] == GOSUB){
free_expression(statement[1]);
kfree(statement);
} else if((int) statement[0] == LIST){
kfree(statement);
}
}