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.
907 lines
18 KiB
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);
|
|
}
|
|
}
|
|
|