/* evaluate an expression factor, eval_err will indicate it any expression evaluation occurs */ static struct eval_value_t /* value of factor */ factor(struct eval_state_t *es) /* expression evaluator */ { enum eval_token_t tok; struct eval_value_t val; tok = peek_next_token(es); switch (tok) { case tok_oparen: (void)get_next_token(es); val = expr(es); if (eval_error) return err_value; tok = peek_next_token(es); if (tok != tok_cparen) { eval_error = ERR_UPAREN; return err_value; } (void)get_next_token(es); break; case tok_minus: /* negation operator */ (void)get_next_token(es); val = factor(es); if (eval_error) return err_value; val = f_neg(val); break; case tok_ident: (void)get_next_token(es); /* evaluate the identifier in TOK_BUF */ val = es->f_eval_ident(es); if (eval_error) return err_value; break; case tok_const: (void)get_next_token(es); val = constant(es); if (eval_error) return err_value; break; default: eval_error = ERR_NOTERM; return err_value; } return val; }
/* evaluate an expression, eval_err will indicate it any expression evaluation occurs */ static struct eval_value_t /* value of the expression */ expr(struct eval_state_t *es) /* expression evaluator */ { enum eval_token_t tok; struct eval_value_t val; val = term(es); if (eval_error) return err_value; tok = peek_next_token(es); switch (tok) { case tok_plus: (void)get_next_token(es); val = f_add(val, expr(es)); if (eval_error) return err_value; break; case tok_minus: (void)get_next_token(es); val = f_sub(val, expr(es)); if (eval_error) return err_value; break; default:; } return val; }
void run(){ tree symbolTable; tree localVar; //dummy local variable funcS funcSymbolTable; peek_next_token(); // creates and executes an image of the whole program doVector* mainbody = mainStatmentOp(symbolTable, localVar, funcSymbolTable); evaluateMain("main" , *mainbody, symbolTable, localVar, funcSymbolTable); delete mainbody; }
Call::Call() : Token(true) { read_next_token(); function_name = next_token(); read_next_token(); // "(" token String args_terminator = ")"; while (args_terminator != peek_next_token()) { ParseTree* tree = new ParseTree(); tree->buildTree(); args_list.push_back(tree); } read_next_token(); // args terminator }
/* evaluate an expression term, eval_err will indicate it any expression evaluation occurs */ static struct eval_value_t /* value to expression term */ term(struct eval_state_t *es) /* expression evaluator */ { enum eval_token_t tok; struct eval_value_t val, val1; val = factor(es); if (eval_error) return err_value; tok = peek_next_token(es); switch (tok) { case tok_mult: (void)get_next_token(es); val = f_mult(val, term(es)); if (eval_error) return err_value; break; case tok_div: (void)get_next_token(es); val1 = term(es); if (eval_error) return err_value; if (f_eq_zero(val1)) { eval_error = ERR_DIV0; return err_value; } val = f_div(val, val1); break; default:; } return val; }
Node Parser::Parse(const std::vector<token> &ntokens) { std::vector<token> tokens = ntokens; Node root; root.kind = NODE_PROGRAM; _current = &tokens.front(); while (_current->kind != TOKEN_EOF) { if (_current->kind == TOKEN_WORD) { std::string definition_name = _current->word; if (peek_next_token()->kind == TOKEN_OPENING_PAREN) root.next.push_back(parse_function_definition()); else root.next.push_back(parse_constant_definition()); } else { error("Unexpected top level token, expected word"); } } return root; }
doVector* statmentOp(tree& symbolTable, tree& localVar, funcS& funcTable){ doVector* ifStatments; ifStatments = new doVector(20);// 20 default starting capacity opNode exp; read_next_token(); if(String (next_token()) == "nufed"){return 0;} doVector::statment loop; while(String (next_token()) != "fi" || String(next_token()) != "od" || String (next_token()) != "nufed"){ String next(next_token()); if(next == "output"){ loop.c = output; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "set"){ loop.c = set; read_next_token(); loop.text = String (next_token()); exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "var"){ loop.c = var; read_next_token(); loop.text = String (next_token()); loop.text = String (next_token()); exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "text"){ loop.c = text; read_next_token(); loop.text = String (next_token()); ifStatments->push_back(loop); }else if(next == "do"){ loop.c = dos; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); loop.block = statmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); }else if(next == "else"){ loop.c = elses; loop.block = elseStatmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); }else if(next == "if"){ loop.c = ifs; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); loop.block = statmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); }else if(next == "call"){ loop.c = call; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "return"){ loop.c = returns; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "defun"){ loop.c = func; peek_next_token(); loop.text = String (next_token()); ifStatments->push_back(loop); functionHandler(symbolTable, tempFunc); } peek_next_token(); if(String (next_token()) == "fi" || String (next_token()) == "od" || String (next_token()) == "nufed" || next_token_type == END){ read_next_token(); break;}else{ read_next_token(); } } return ifStatments; }
doVector* elseStatmentOp(tree& symbolTable, tree& localVar, funcS& funcTable){ doVector* ifStatments; ifStatments = new doVector(20);// 20 default starting capacity opNode exp; read_next_token(); doVector::statment loop;// temporary place holder of the elements to be pushed to the vector while(String (next_token()) != "fi"){ String next(next_token()); if(next == "output"){ loop.c = output; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "set"){ loop.c = set; read_next_token(); loop.text = String (next_token()); exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "var"){ loop.c = var; read_next_token(); loop.text = String (next_token()); exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "text"){ loop.c = text; read_next_token(); loop.text = String (next_token()); ifStatments->push_back(loop); }else if(next == "do"){ loop.c = dos; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); loop.block = statmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); }else if(next == "else"){ loop.c = elses; loop.block = statmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); }else if(next == "if"){ loop.c = ifs; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); loop.block = statmentOp(symbolTable, localVar, funcTable); ifStatments->push_back(loop); loop.c = call; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "return"){ loop.c = returns; exp.parseOperateTemp(String (next_token()), 0, symbolTable, loop.operate); ifStatments->push_back(loop); }else if(next == "defun"){ loop.c = func; peek_next_token(); loop.text = String (next_token()); ifStatments->push_back(loop); functionHandler(symbolTable, tempFunc); } peek_next_token(); if(String (next_token()) == "fi"){ break;}else{ read_next_token(); } } return ifStatments; }
static void load_database (const char *filename) { FILE *fp = fopen (filename, "r"); char buf[2048]; unsigned n_people = 0; unsigned people_alloced = 32; unsigned line_no; Foo__Person *people = xmalloc (sizeof (Foo__Person) * people_alloced); if (fp == NULL) die ("error opening %s: %s", filename, strerror (errno)); line_no = 0; while (fgets (buf, sizeof (buf), fp) != NULL) { line_no++; if (buf[0] == '#') continue; if (is_whitespace (buf)) continue; chomp_trailing_whitespace (buf); if (isspace (buf[0])) { Foo__Person *person; char *start = buf + 1; if (n_people == 0) die ("error on %s, line %u: line began with a space, but no person's name preceded it", filename, line_no); person = people + (n_people - 1); while (*start && isspace (*start)) start++; if (starts_with (start, "id ")) person->id = atoi (peek_next_token (start)); else if (starts_with (start, "email ")) person->email = xstrdup (peek_next_token (start)); else if (starts_with (start, "mobile ") || starts_with (start, "home ") || starts_with (start, "work ")) { Foo__Person__PhoneNumber *pn = xmalloc (sizeof (Foo__Person__PhoneNumber)); Foo__Person__PhoneNumber tmp = FOO__PERSON__PHONE_NUMBER__INIT; tmp.has_type = 1; tmp.type = start[0] == 'm' ? FOO__PERSON__PHONE_TYPE__MOBILE : start[0] == 'h' ? FOO__PERSON__PHONE_TYPE__HOME : FOO__PERSON__PHONE_TYPE__WORK; tmp.number = xstrdup (peek_next_token (start)); person->phone = xrealloc (person->phone, sizeof (Foo__Person__PhoneNumber*) * (person->n_phone+1)); *pn = tmp; person->phone[person->n_phone++] = pn; } else die ("error on %s, line %u: unrecognized field starting with %s", filename, line_no, start); } else { Foo__Person *person; if (n_people == people_alloced) { people_alloced *= 2; people = xrealloc (people, people_alloced * sizeof (Foo__Person)); } person = people + n_people++; foo__person__init (person); person->name = xstrdup (buf); } } if (n_people == 0) die ("empty database: insufficiently interesting to procede"); qsort (people, n_people, sizeof (Foo__Person), compare_persons_by_name); database = people; database_size = n_people; fclose (fp); }