double Expression::Parse(const string& token, vector<vector<Expression> >& sSheet, deque<double>& terms) { if (token.length() == 0) { throw runtime_error("Parsing failed: please trim whitespace"); } else if (IsVal(token)) { return atof(token.c_str()); } else if (IsRef(token)) { return Deref(token, sSheet); } else if (IsOp(token)) { return Oper(token, terms); } else { throw runtime_error("Parsing failed with: " + token); } }
ASTNode *ASTUop::createNode(scheme_list &sl) { ASTNodeCommonData cd; ASTNode *expr = NULL; Oper op; U_ASSERT(sl[1].type == SCM_LIST && sl[2].type == SCM_LIST && sl[3].type == SCM_NUMBER); cd = dsGetASTCommonFromSList(*sl[1].internal.list); expr = dsGetASTFromSchemeList(*sl[2].internal.list); op = Oper(atol(sl[3].internal.num)); return new ASTUop(cd, op, expr); }
// Contract many <>+- to Op('+', 123) etc. std::vector<Oper> optimize(FILE* f) { std::vector<Oper> ops; for ( int c=0; c != EOF; c = fgetc(f) ) { // skip unknown ops if ( !strchr("<>+-.,[]", c) ) continue; Oper op(c, 1); if ( strchr("+-<>", c) ) { int n = fgetc(f); while ( n != EOF && n == c ) { ++op.count; n = fgetc(f); } ungetc(n, f); } ops.push_back(op); } // Special [-] ==> set current cell to zero for ( size_t n=0; n+2<ops.size(); ++n ) { Oper a = ops[n]; Oper b = ops[n+1]; Oper c = ops[n+2]; if ( a.code=='[' && b.code=='-' && b.count==1 && c.code==']' ) { ops.erase(ops.begin()+n, ops.begin()+n+3); ops.insert(ops.begin()+n, Oper('z', 0)); continue; } } return ops; }