/*---------------------------------------------------------------------------*/ 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 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 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 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 print_statement(void) { uint8_t nonl; uint8_t t; uint8_t nv = 0; do { t = current_token; nonl = 0; DEBUG_PRINTF("Print loop\n"); if (nv == 0) { if(t == TOKENIZER_STRING) { /* Handle string const specially - length rules */ tokenizer_string_func(charout, NULL); tokenizer_next(); nv = 1; continue; } else if(TOKENIZER_STRINGEXP(t)) { charoutstr(stringexpr()); nv = 1; continue; } else if(TOKENIZER_NUMEXP(t)) { intout(intexpr()); nv = 1; continue; } else if(t == TOKENIZER_TAB) { nv = 1; accept_tok(TOKENIZER_TAB); chartab(bracketed_intexpr()); continue; } else if(t == TOKENIZER_AT) { int x,y; nv = 1; accept_tok(TOKENIZER_AT); y = intexpr(); accept_tok(TOKENIZER_COMMA); x = intexpr(); if (move_cursor(x,y)) chpos = x; continue; } } nv = 0; if(t == TOKENIZER_COMMA) { charout('\t', NULL); nonl = 1; tokenizer_next(); } else if(t == TOKENIZER_SEMICOLON) { nonl = 1; tokenizer_next(); } else if (!statement_end()) { syntax_error(); break; } } while(!statement_end()); if (!nonl) charout('\n', 0); DEBUG_PRINTF("End of print\n"); }
//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 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(); }
local size_t sentencizer_next(struct mascara *imp, struct mr_token **tks) { struct sentencizer *szr = (struct sentencizer *)imp; struct sentence *sent = &szr->sent; assert(szr->str && "text no set"); sentence_clear(sent); size_t len; const unsigned char *last_period; const unsigned char *str = next_sentence(szr, &len, &last_period); if (!str) { *tks = NULL; return 0; } size_t offset_incr = szr->offset_incr + str - szr->str; struct tokenizer tkr; tokenizer_init(&tkr, szr->vtab); tokenizer_set_text(&tkr.base, str, len, offset_incr); struct mr_token *tk; while (tokenizer_next(&tkr.base, &tk)) { if (tk->str == (const char *)last_period || !sentencizer_reattach_period(sent, tk)) { sentence_add(sent, tk); if (sent->len == MR_MAX_SENTENCE_LEN) { szr->p = (const unsigned char *)tk->str + tk->len; break; } } } *tks = sent->tokens; return sent->len; }
/*---------------------------------------------------------------------------*/ 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 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 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 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 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; }
/*---------------------------------------------------------------------------*/ void tokenizer_next(void) { if(tokenizer_finished()) { return; } DEBUG_PRINTF("tokenizer_next: %p\n", nextptr); ptr = nextptr; while(*ptr == ' ') { ++ptr; } current_token = get_next_token(); if(current_token == TOKENIZER_REM) { while(!(*nextptr == '\n' || tokenizer_finished())) { ++nextptr; } if(*nextptr == '\n') { ++nextptr; } tokenizer_next(); } DEBUG_PRINTF("tokenizer_next: '%s' %d\n", ptr, current_token); return; }
/*---------------------------------------------------------------------------*/ static void expr(struct typevalue *r1) { struct typevalue r2; int op; relation(r1); op = current_token; DEBUG_PRINTF("logicrelation: token %d\n", op); /* FIXME: unclear the while is correct here. It's not correct in most BASIC to write A > B > C, rather relations should be two part linked with logic */ while(op == TOKENIZER_AND || op == TOKENIZER_OR) { tokenizer_next(); relation(&r2); /* No type checks needed on relations */ DEBUG_PRINTF("logicrelation: %d %d %d\n", r1->d.i, op, r2.d.i); switch(op) { case TOKENIZER_AND: r1->d.i = r1->d.i & r2.d.i; break; case TOKENIZER_OR: r1->d.i = r1->d.i | r2.d.i; break; } op = current_token; } r1->type = TYPE_INTEGER; }
Phrase * phrase_from_string (const gchar *str) { Tokenizer *tok; gchar *term; Phrase *phrase; g_return_val_if_fail(str != NULL, NULL); if (index(str, '/') != NULL) { gchar **strs; guint idx; strs = g_strsplit(str, "/", 0); phrase = phrase_new(); for (idx = 0; strs[idx] != NULL; idx++) { phrase_append(phrase, strs[idx]); } g_strfreev(strs); } else { tok = tokenizer_new(str); phrase = phrase_new(); while(term = tokenizer_next(tok)){ phrase_append_nocopy(phrase, term); } tokenizer_free(tok); } return phrase; }
/*---------------------------------------------------------------------------*/ static void term(struct typevalue *v) { struct typevalue f2; int op; factor(v); op = current_token; DEBUG_PRINTF("term: token %d\n", op); while(op == TOKENIZER_ASTR || op == TOKENIZER_SLASH || op == TOKENIZER_MOD) { tokenizer_next(); factor(&f2); typecheck_int(v); typecheck_int(&f2); DEBUG_PRINTF("term: %d %d %d\n", v->d.i, op, f2.d.i); switch(op) { case TOKENIZER_ASTR: v->d.i *= f2.d.i; break; case TOKENIZER_SLASH: if (f2.d.i == 0) ubasic_error(divzero); v->d.i /= f2.d.i; break; case TOKENIZER_MOD: if (f2.d.i == 0) ubasic_error(divzero); v->d.i %= f2.d.i; break; } op = current_token; } DEBUG_PRINTF("term: %d\n", v->d.i); }
//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{ } }
/*---------------------------------------------------------------------------*/ void tokenizer_init(const char *program) { ptr = program; current_line = 1; current_token = get_next_token(); while (current_token==TOKENIZER_CR && !tokenizer_finished()) tokenizer_next(); }
/*---------------------------------------------------------------------------*/ static void jump_linenum_slow(int linenum) { tokenizer_init(program_ptr); while(tokenizer_num() != linenum) { do { do { tokenizer_next(); } while(current_token != TOKENIZER_CR && current_token != TOKENIZER_ENDOFINPUT); if(current_token == TOKENIZER_CR) { tokenizer_next(); } } while(current_token != TOKENIZER_NUMBER); DEBUG_PRINTF("jump_linenum_slow: Found line %d\n", tokenizer_num()); } }
//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 input_statement(void) { struct typevalue r; var_t v; char buf[129]; uint8_t t; uint8_t first = 1; int l; t = current_token; if (t == TOKENIZER_STRING) { tokenizer_string_func(charout, NULL); tokenizer_next(); t = current_token; accept_either(TOKENIZER_COMMA, TOKENIZER_SEMICOLON); } else { charout('?', NULL); charout(' ', NULL); } begin_input(); /* Consider the single var allowed version of INPUT - it's saner for strings by far ? */ do { int n = 0; struct typevalue s[MAX_SUBSCRIPT]; if (!first) accept_either(TOKENIZER_COMMA, TOKENIZER_SEMICOLON); first = 0; t = current_token; v = tokenizer_variable_num(); accept_either(TOKENIZER_INTVAR, TOKENIZER_STRINGVAR); if (current_token == TOKENIZER_LEFTPAREN) n = parse_subscripts(s); /* FIXME: this works for stdin but not files .. */ if ((l = read(0, buf + 1, 128)) <= 0) { write(2, "EOF\n", 4); exit(1); } charreset(); /* Newline input so move to left */ if (t == TOKENIZER_INTVAR) { r.type = TYPE_INTEGER; /* For now */ r.d.i = atoi(buf + 1); /* FIXME: error checking */ } else { /* Turn a C string into a BASIC one */ r.type = TYPE_STRING; if (buf[l-1] == '\n') l--; *((uint8_t *)buf) = l; r.d.p = (uint8_t *)buf; } ubasic_set_variable(v, &r, n, s); } while(!statement_end()); end_input(); }
/*---------------------------------------------------------------------------*/ 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 uint8_t accept_tok(uint8_t token) { if(token != current_token) { DEBUG_PRINTF("Token not what was expected (expected %d, got %d)\n", token, current_token); tokenizer_error_print(); exit(1); } DEBUG_PRINTF("Expected %d, got it\n", token); tokenizer_next(); /* This saves lots of extra calls - return the new token */ return current_token; }
//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 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 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 mathexpr(struct typevalue *v) { struct typevalue t2; int op; term(v); op = current_token; DEBUG_PRINTF("mathexpr: token %d\n", op); while(op == TOKENIZER_PLUS || op == TOKENIZER_MINUS || op == TOKENIZER_BAND || op == TOKENIZER_BOR) { tokenizer_next(); term(&t2); if (op != TOKENIZER_PLUS) typecheck_int(v); typecheck_same(v, &t2); DEBUG_PRINTF("mathexpr: %d %d %d\n", v->d.i, op, t2.d.i); switch(op) { case TOKENIZER_PLUS: if (v->type == TYPE_INTEGER) v->d.i += t2.d.i; else { uint8_t *p; uint8_t l = *v->d.p; p = string_temp(l + *t2.d.p); memcpy(p + 1, v->d.p + 1, l); memcpy(p + l + 1, t2.d.p + 1, *t2.d.p); v->d.p = p; } break; case TOKENIZER_MINUS: v->d.i -= t2.d.i; break; case TOKENIZER_BAND: v->d.i &= t2.d.i; break; case TOKENIZER_BOR: v->d.i |= t2.d.i; break; } op = current_token; } DEBUG_PRINTF("mathexpr: %d\n", v->d.i); }