int parseexpression() { int invert = 0; switch (token) { case TOK_ADD: token = tokeniser_next(); break; case TOK_SUB: token = tokeniser_next(); invert = 1; break; } int lhs = parseterm(); if (invert) { lhs = -lhs; } if (token == TOK_ADD) { token = tokeniser_next(); int rhs = parseterm(); if (token == TOK_ERR) { return 0; } return lhs + rhs; } if (token == TOK_SUB) { token = tokeniser_next(); int rhs = parseterm(); if (token == TOK_ERR) { return 0; } return lhs - rhs; } return lhs; }
int parsefactor() { if (token == TOK_NUM) { int lhs = tokeniser_number(); token = tokeniser_next(); return lhs; } else if (token == TOK_VAR) { char* varName = tokeniser_string(); token = tokeniser_next(); return getvariable(varName); } else { printf("invalid expression\n"); token = TOK_ERR; return 0; } }
int main(int argc, char *argv[]) { int ecode; bfcc_options bfopts = {0}; if (parse_arguments(argc, argv, &bfopts) != 0) { return -2; } FILE *f = stdin; if (bfopts.input_file != 0) { f = fopen(bfopts.input_file, "r"); if (!f) { fprintf(stderr, "Unknown file.\n"); return ERROR_FILE_NOT_FOUND; } } c99_options opts; c99_options_default(&opts); backend back = create_c99_backend(&opts); ecode = back.begin(&back, stdout); FATAL_IF_ERROR(ecode, "Backend preamble generation"); tokeniser *t = tokeniser_setup(f); CHECK_ALLOCATION(t, "Tokeniser setup"); while (1) { token tok; int error = tokeniser_next(t, &tok); if (IS_ERROR(error)) { fprintf(stderr, "Tokenisation error detected: %d.\n", error); return ERROR_TOKENISATION; } if (tok == token_eof) break; if (IS_ERROR(back.emit(&back, stdout, (token) tok))) { fprintf(stderr, "Failure encountered when translating token: %s\n", token_name((token) tok)); } } ecode = back.end(&back, stdout); FATAL_IF_ERROR(ecode, "Backend could not finish") return 0; }
static Pointer readForm(Tokeniser* t) { if (tokeniser_eof(t)) { return nil_make(); } Pointer ret = tokeniser_token(t); // If ret is a string, it's ready to return if (ret.type == Type_symbol) { const char* token = symbol_get(ret); int intValue; if (util_streq(token, "(")) { tokeniser_next(t); // consume the '(', read the list and return readList(t); // return immediately to avoid hitting the // tokeniser_next() below } else if (util_streq(token, "nil")) { ret = nil_make(); } else if (util_streq(token, "true")) { ret = boolean_make(1); } else if (util_streq(token, "false")) { ret = boolean_make(0); } else if (readInteger(token, &intValue)) { ret = integer_make(intValue); } else { // Insert the symbol into the symbol table. We may or may not get // the same symbol back. ret = symtab_insert(ret); } } PUSH(ret); tokeniser_next(t); return POP(); }
int parseterm() { int lhs = parsefactor(); if (token == TOK_ERR) { return 0; } if (token == TOK_MUL) { token = tokeniser_next(); int rhs = parsefactor(); if (token == TOK_ERR) { return 0; } return lhs * rhs; } if (token == TOK_DIV) { token = tokeniser_next(); int rhs = parsefactor(); if (token == TOK_ERR) { return 0; } return lhs / rhs; } return lhs; }
static Pointer readList(Tokeniser* t) { if (tokeniser_eof(t)) { THROW("Expected ), got EOF"); } Pointer token = tokeniser_token(t); if ((token.type == Type_symbol) && util_streq(symbol_get(token), ")")) { tokeniser_next(t); return nil_make(); } StackIndex carIndex = PUSH(readForm(t)); StackIndex cdrIndex = PUSH(readList(t)); Pointer ret = pair_make(carIndex, cdrIndex); DROP(2); return ret; }
int runline(char* line, int* pc) { tokeniser_setup(line); token = tokeniser_next(); switch (token) { case TOK_PRINT:// STRING|EXPR (, STRING|EXPR) do { token = tokeniser_next(); if (token == TOK_EOL || token == TOK_ERR) { break; } if (token == TOK_STRING) { printf("%s ", tokeniser_string()); token = tokeniser_next(); } else { printf("%d ", parseexpression()); } if (token != TOK_COMMA && token != TOK_EOL) { printf("expected ','\n"); return 0; } } while (token != TOK_EOL && token != TOK_ERR); printf("\n"); break; case TOK_LET:// VAR = EXPR token = tokeniser_next(); if (token != TOK_VAR) { printf("expected variable name\n"); return 0; } char* varName = tokeniser_string(); token = tokeniser_next(); if (token != TOK_EQ) { printf("expected = after variable name\n"); return 0; } token = tokeniser_next(); int val = parseexpression(); if (token == TOK_ERR) { return 0; } setvariable(varName, token); break; } (*pc)++; return 1; }