/*---------------------------------------------------------------------------*/ static int relation(void) { int r1, r2; int op; r1 = expr(); op = tokenizer_token(); DEBUG_PRINTF("relation: token %d\n", op); while(op == TOKENIZER_LT || op == TOKENIZER_GT || op == TOKENIZER_EQ) { tokenizer_next(); r2 = expr(); DEBUG_PRINTF("relation: %d %d %d\n", r1, op, r2); switch(op) { case TOKENIZER_LT: r1 = r1 < r2; break; case TOKENIZER_GT: r1 = r1 > r2; break; case TOKENIZER_EQ: r1 = r1 == r2; break; } op = tokenizer_token(); } return r1; }
/*---------------------------------------------------------------------------*/ static int term(void) { int f1, f2; int op; f1 = factor(); op = tokenizer_token(); DEBUG_PRINTF("term: token %d\n", op); while(op == TOKENIZER_ASTR || op == TOKENIZER_SLASH || op == TOKENIZER_MOD) { tokenizer_next(); f2 = factor(); DEBUG_PRINTF("term: %d %d %d\n", f1, op, f2); switch(op) { case TOKENIZER_ASTR: f1 = f1 * f2; break; case TOKENIZER_SLASH: f1 = f1 / f2; break; case TOKENIZER_MOD: f1 = f1 % f2; break; } op = tokenizer_token(); } DEBUG_PRINTF("term: %d\n", f1); return f1; }
/*---------------------------------------------------------------------------*/ static VARIABLE_TYPE expr(void) { int t1, t2; int op; t1 = term(); op = tokenizer_token(); DEBUG_PRINTF("expr: token %d\n", op); while(op == TOKENIZER_PLUS || op == TOKENIZER_MINUS || op == TOKENIZER_AND || op == TOKENIZER_OR) { tokenizer_next(); t2 = term(); DEBUG_PRINTF("expr: %d %d %d\n", t1, op, t2); switch(op) { case TOKENIZER_PLUS: t1 = t1 + t2; break; case TOKENIZER_MINUS: t1 = t1 - t2; break; case TOKENIZER_AND: t1 = t1 & t2; break; case TOKENIZER_OR: t1 = t1 | t2; break; } op = tokenizer_token(); } DEBUG_PRINTF("expr: %d\n", t1); return t1; }
//static int expr(void) int expr(void) { int t1, t2; int op; t1 = term(); op = tokenizer_token(); while(op == TOKENIZER_PLUS || op == TOKENIZER_MINUS || op == TOKENIZER_AND || op == TOKENIZER_OR) { tokenizer_next(); t2 = term(); switch(op) { case TOKENIZER_PLUS: t1 = t1 + t2; break; case TOKENIZER_MINUS: t1 = t1 - t2; break; case TOKENIZER_AND: t1 = t1 & t2; break; case TOKENIZER_OR: t1 = t1 | t2; break; } op = tokenizer_token(); } return t1; }
//static int term(void) int term(void) { int f1, f2; int op; f1 = factor(); op = tokenizer_token(); while(op == TOKENIZER_ASTR || op == TOKENIZER_SLASH || op == TOKENIZER_MOD) { tokenizer_next(); f2 = factor(); switch(op) { case TOKENIZER_ASTR: f1 = f1 * f2; break; case TOKENIZER_SLASH: f1 = f1 / f2; break; case TOKENIZER_MOD: f1 = f1 % f2; break; } op = tokenizer_token(); } return f1; }
//static int relation(void) int relation(void) { int r1, r2; int op; r1 = expr(); op = tokenizer_token(); while(op == TOKENIZER_LT || op == TOKENIZER_GT || op == TOKENIZER_EQ) { tokenizer_next(); r2 = expr(); switch(op) { case TOKENIZER_LT: r1 = r1 < r2; break; case TOKENIZER_GT: r1 = r1 > r2; break; case TOKENIZER_EQ: r1 = r1 == r2; break; } op = tokenizer_token(); } return r1; }
//static void gosub_statement(void) void gosub_statement(void) { int linenum,nextnum; char *tmpptr, *tmpnextptr; accept(TOKENIZER_GOSUB); linenum = tokenizer_num(); accept(TOKENIZER_NUMBER); tmpptr = ptr; tmpnextptr = nextptr; while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT){ tokenizer_next(); } accept(TOKENIZER_CR); nextnum = tokenizer_num(); ptr = tmpptr; nextptr = tmpnextptr; if(gosub_stack_ptr < MAX_GOSUB_STACK_DEPTH) { gosub_stack[gosub_stack_ptr] = nextnum; gosub_stack_ptr++; jump_linenum(linenum); }else{ } }
static int term (void) { int f1, f2, op; f1 = factor(); op = tokenizer_token(); while (op == T_ASTERISK || op == T_SLASH) { tokenizer_next(); f2 = factor(); switch (op) { case T_ASTERISK: f1 = f1 * f2; break; case T_SLASH: if (f2 == 0) { /* Divide by zero. */ dprintf( "*warning: divide by zero\n", E_WARNING); f1 = 0; } else { f1 = f1 / f2; } break; } op = tokenizer_token(); } return f1; }
/*---------------------------------------------------------------------------*/ static void if_statement(void) { int r; accept(TOKENIZER_IF); r = relation(); DEBUG_PRINTF("if_statement: relation %d\n", r); accept(TOKENIZER_THEN); if(r) { statement(); } else { do { tokenizer_next(); } while(tokenizer_token() != TOKENIZER_ELSE && tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT); if(tokenizer_token() == TOKENIZER_ELSE) { tokenizer_next(); statement(); } else if(tokenizer_token() == TOKENIZER_CR) { tokenizer_next(); } } }
//static void comment_accept(void) void comment_accept(void) { int op; op = tokenizer_token(); while((TOKENIZER_CR != op)&&(TOKENIZER_ENDOFINPUT != op)){ tokenizer_next(); op = tokenizer_token(); } }
static void find_linenum (int linenum) { /* Skip irrelevant new-lines and comments. */ while (tokenizer_token() != T_NUMBER) tokenizer_next(); while (tokenizer_num() != linenum && tokenizer_token() != T_EOF) { /* Check line number, then skip the rest of line statement. */ do { do { tokenizer_next(); } while (tokenizer_token() != T_EOL && tokenizer_token() != T_EOF); if (tokenizer_token() == T_EOL) { /* Skip irrelevant new-lines and comments. */ while (tokenizer_token() != T_NUMBER && tokenizer_token() != T_EOF) tokenizer_next(); } } while (tokenizer_token() != T_NUMBER && tokenizer_token() != T_EOF); } }
/*---------------------------------------------------------------------------*/ static void accept(int token) { if(token != tokenizer_token()) { DEBUG_PRINTF("Token not what was expected (expected %d, got %d)\n", token, tokenizer_token()); tokenizer_error_print(); exit(1); } DEBUG_PRINTF("Expected %d, got it\n", token); tokenizer_next(); }
//static void accept(int token) void accept(int token) { #if TEST char buf[10]; #endif if(token != tokenizer_token()) { #if TEST buf[0] = (token/10) + '0'; buf[1] = (token%10) + '0'; buf[2] = ' '; buf[3] = (current_token/10) + '0'; buf[4] = (current_token%10) + '0'; buf[5] = '\n'; buf[6] = 0x00; // printf(buf); // cputs_p(6,buf); glcd_PutsA(buf); #endif tokenizer_error_print(); ended = 1; glcd_DrawCursor(); // exit(1); } tokenizer_next(); }
/*---------------------------------------------------------------------------*/ static void jump_linenum_slow(int linenum) { tokenizer_init(program_ptr); while(tokenizer_num() != linenum) { do { do { tokenizer_next(); } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT); if(tokenizer_token() == TOKENIZER_CR) { tokenizer_next(); } } while(tokenizer_token() != TOKENIZER_NUMBER); DEBUG_PRINTF("jump_linenum_slow: Found line %d\n", tokenizer_num()); } }
static void accept (int token) { char string[10]; if (token != tokenizer_token()) { /* Token was unexpected. */ to_string(string, sizeof string); dprintf("*vvtbi.c: unexpected `%s' " "near `%s', expected: `%s'\n", E_ERROR, vvtbi_token(tokenizer_token()), /* If empty, EOF! */ ((strlen(string)) ? string : "EOF"), vvtbi_token(token)); } tokenizer_next(); }
static void print_statement (void) { accept(T_PRINT); do { /* Print a string literal. */ if (tokenizer_token() == T_STRING) { printf("%s", tokenizer_string()); tokenizer_next(); } /* A seperator, send a space. */ else if (tokenizer_token() == T_SEPERATOR) { printf(" "); tokenizer_next(); } /* Evaluate and print an expression. */ else if (tokenizer_token() == T_LETTER || tokenizer_token() == T_NUMBER || tokenizer_token() == T_LEFT_PAREN) printf("%d", expression()); else { break; } /* This additionally ensures a new-line character is present at the end of the line-statement. */ if (tokenizer_finished()) accept(T_EOL); } while (tokenizer_token() != T_EOL && tokenizer_token() != T_EOF); printf("\n"); tokenizer_next(); }
/*---------------------------------------------------------------------------*/ static void print_statement(void) { accept(TOKENIZER_PRINT); do { DEBUG_PRINTF("Print loop\n"); if(tokenizer_token() == TOKENIZER_STRING) { tokenizer_string(string, sizeof(string)); printf("%s", string); tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_COMMA) { printf(" "); tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_SEMICOLON) { tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_VARIABLE || tokenizer_token() == TOKENIZER_NUMBER) { printf("%d", expr()); } else { break; } } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT); printf("\n"); DEBUG_PRINTF("End of print\n"); tokenizer_next(); }
//static void print_statement(void) void print_statement(void) { char buf[20]; accept(TOKENIZER_PRINT); do { if(tokenizer_token() == TOKENIZER_STRING) { tokenizer_string(strings[MAX_STRINGNUM], sizeof(strings[MAX_STRINGNUM])); glcd_PutsA(strings[MAX_STRINGNUM]); tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_COMMA) { glcd_PutsA(" "); tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_SEMICOLON) { tokenizer_next(); } else if(tokenizer_token() == TOKENIZER_VARIABLE || tokenizer_token() == TOKENIZER_NUMBER) { glcd_PutsA(ltodeci(expr(),buf,6)); } else { break; } } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT); glcd_PutsA("\n"); // cputs_p(6,"Print"); tokenizer_next(); }
static void line_statement (void) { int token; /* Skip irrelevant new-lines. */ if (tokenizer_token() == T_EOL) { do { tokenizer_next(); } while (tokenizer_token() == T_EOL); } token = tokenizer_token(); /* Unless a comment, line number is mandatory. */ if (token != T_REM) { accept(T_NUMBER); } statement(); }
//static void jump_linenum(int linenum) void jump_linenum(int linenum) { ptr = BASICBUF; nextptr = ptr; tokenizer_init(ptr); while(tokenizer_num() != linenum) { do { do { tokenizer_next(); } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT); if(tokenizer_token() == TOKENIZER_CR) { tokenizer_next(); } if(tokenizer_token() == TOKENIZER_ENDOFINPUT){ ended = 1; return; } } while(tokenizer_token() != TOKENIZER_NUMBER); } }
static int relation (void) { int r1, r2, op; r1 = expression(); op = tokenizer_token(); while (op == T_EQUAL || op == T_LT || op == T_GT || op == T_LT_EQ || op == T_GT_EQ || op == T_NOT_EQUAL) { tokenizer_next(); r2 = expression(); switch (op) { case T_EQUAL: r1 = r1 == r2; break; case T_LT: r1 = r1 < r2; break; case T_GT: r1 = r1 > r2; break; case T_LT_EQ: r1 = r1 <= r2; break; case T_GT_EQ: r1 = r1 >= r2; break; case T_NOT_EQUAL: r1 = r1 != r2; break; } op = tokenizer_token(); } return r1; }
static int expression (void) { int t1, t2, op; t1 = term(); op = tokenizer_token(); while(op == T_PLUS || op == T_MINUS) { tokenizer_next(); t2 = term(); switch (op) { case T_PLUS: t1 = t1 + t2; break; case T_MINUS: t1 = t1 - t2; break; } op = tokenizer_token(); } return t1; }
/*---------------------------------------------------------------------------*/ static int factor(void) { int r; DEBUG_PRINTF("factor: token %d\n", tokenizer_token()); switch(tokenizer_token()) { case TOKENIZER_NUMBER: r = tokenizer_num(); DEBUG_PRINTF("factor: number %d\n", r); accept(TOKENIZER_NUMBER); break; case TOKENIZER_LEFTPAREN: accept(TOKENIZER_LEFTPAREN); r = expr(); accept(TOKENIZER_RIGHTPAREN); break; default: r = varfactor(); break; } return r; }
static int search_cvars(const char *var_name) { int idx=0; // Variablenname in Tabelle suchen #if USE_PROGMEM while((int *)pgm_read_word(&cvars[idx].pvar) != NULL && strncasecmp_P(var_name, cvars[idx].var_name, MAX_NAME_LEN)) { idx++; } #else while(cvars[idx].pvar != NULL && strncasecmp(cvars[idx].var_name, var_name, MAX_NAME_LEN)) { idx++; } #endif // keinen Tabelleneintrag gefunden! #if USE_PROGMEM if ((int *)pgm_read_word(&cvars[idx].pvar) == NULL) { #else if (cvars[idx].pvar == NULL) { #endif tokenizer_error_print(current_linenum, UNKNOWN_CVAR_NAME); ubasic_break(); } return idx; } void vpoke_statement(void) { int idx=0; #if USE_PROGMEM int *var_temp; #endif accept(TOKENIZER_VPOKE); accept(TOKENIZER_LEFTPAREN); // Variablenname ermitteln if(tokenizer_token() == TOKENIZER_STRING) { tokenizer_next(); } idx=search_cvars(tokenizer_last_string_ptr()); accept(TOKENIZER_RIGHTPAREN); accept(TOKENIZER_EQ); #if USE_PROGMEM var_temp=(int *)pgm_read_word(&cvars[idx].pvar); *var_temp=expr(); #else *cvars[idx].pvar = expr(); #endif //tokenizer_next(); }
/*---------------------------------------------------------------------------*/ static void statement(void) { int token; token = tokenizer_token(); switch(token) { case TOKENIZER_PRINT: print_statement(); break; case TOKENIZER_IF: if_statement(); break; case TOKENIZER_GOTO: goto_statement(); break; case TOKENIZER_GOSUB: gosub_statement(); break; case TOKENIZER_RETURN: return_statement(); break; case TOKENIZER_FOR: for_statement(); break; case TOKENIZER_PEEK: peek_statement(); break; case TOKENIZER_POKE: poke_statement(); break; case TOKENIZER_NEXT: next_statement(); break; case TOKENIZER_END: end_statement(); break; case TOKENIZER_LET: accept(TOKENIZER_LET); /* Fall through. */ case TOKENIZER_VARIABLE: let_statement(); break; default: DEBUG_PRINTF("ubasic.c: statement(): not implemented %d\n", token); exit(1); } }
//static int factor(void) int factor(void) { int r; switch(tokenizer_token()) { case TOKENIZER_NUMBER: r = tokenizer_num(); accept(TOKENIZER_NUMBER); break; case TOKENIZER_LEFTPAREN: accept(TOKENIZER_LEFTPAREN); r = expr(); accept(TOKENIZER_RIGHTPAREN); break; default: r = varfactor(); break; } return r; }
static void statement (void) { int token; char string[10]; token = tokenizer_token(); switch (token) { /* REM statement (comment). */ case T_REM: tokenizer_next(); accept(T_EOL); break; /* Print statement. */ case T_PRINT: print_statement(); break; /* If statement. */ case T_IF: if_statement(); break; /* Goto statement. */ case T_GOTO: goto_statement(); break; /* Let statement. */ case T_LET: accept(T_LET); /* Fall through... */ case T_LETTER: let_statement(); break; default: /* Unrecognized statement! */ to_string(string, sizeof string); dprintf("*vvtbi.c: statement(): " "not implemented near `%s'\n", E_ERROR, /* If empty, EOF! */ ((strlen(string)) ? string : "EOF")); break; } }
/*---------------------------------------------------------------------------*/ void tokenizer_string(char *dest, int len) { char *string_end; int string_len; if(tokenizer_token() != TOKENIZER_STRING) { return; } string_end = strchr(ptr + 1, '"'); if(string_end == NULL) { return; } string_len = string_end - ptr - 1; if(len < string_len) { string_len = len; } memcpy(dest, ptr + 1, string_len); dest[string_len] = 0; }
/*---------------------------------------------------------------------------*/ void tokenizer_label(char *dest, int len) { char *string_end; int string_len; if(tokenizer_token() != TOKENIZER_LABEL) { return; } // allow string \r, \n, tabulation and space to end labels string_end = strpbrk(ptr + 1, " \t\r\n"); if(string_end == NULL) { return; } string_len = string_end - ptr - 1; if(len < string_len) { string_len = len; } memcpy(dest, ptr + 1, string_len); dest[string_len] = 0; }
static int factor (void) { int r; switch (tokenizer_token()) { case T_NUMBER: r = tokenizer_num(); accept(T_NUMBER); break; case T_LEFT_PAREN: accept(T_LEFT_PAREN); r = expression(); accept(T_RIGHT_PAREN); break; default: r = get_variable( tokenizer_variable_num()); accept(T_LETTER); break; } return r; }