static double factor() { if (follows(MT_BRA)) { next_token(); MItem* it = expression(); if (it->n >= 0) serror("invalid use of list."); if (!follows(MT_KET)) serror("')' expected."); next_token(); return it->val; } else if (follows(MT_NUMBER)) { double val = token->value; next_token(); return val; } else if (follows(MT_IDENT)) { MSymbol* sym = peek_symbol(token->text); if (sym == NULL) serror("unknown identifier '%s'.", token->text); next_token(); if (follows(MT_BRA)) { if (sym->built_in == NULL) serror("unknown function '%s'.", sym->name); next_token(); return eval_fn(sym); } else { if (sym->built_in != NULL) serror("invalid use of function."); if (sym->data->n >= 0) serror("invalid use of list."); return sym->data->val; } } else { serror("syntax error: '%s'", token->text); return 0.0; } }
static MItem* expression() { // special case: expression is a list reference if (follows(MT_IDENT)) { MSymbol* list = peek_symbol(token->text); if (list != NULL && list->built_in == NULL && list->data != NULL && list->data->n >= 0) { next_token(); // only "=", "}", ";" or "," must follow if (!follows(MT_EQUAL) && !follows(MT_END) && !follows(MT_COMMA) && !follows(MT_SEMICOL)) serror("invalid use of list."); return list->data; } } // handle unary + and - double unary = 1.0; if (follows(MT_PLUS) || follows(MT_MINUS)) { if (follows(MT_MINUS)) unary = -1.0; next_token(); } double result = unary * term(); while (follows(MT_PLUS) || follows(MT_MINUS)) { if (follows(MT_PLUS)) { next_token(); result += term(); } else { next_token(); result -= term(); } } MItem* it = new_item(); it->n = -1; it->val = result; return it; }
MSymbol* mesh_parser_find_symbol(const char* name) { return peek_symbol(name); }