In order to implement an expression evaluator, I have a two-pass compilation that first uses a magic resolver to find external name references, and then compiles the actual code to get a function back. This cut-down version of it showcases a strange phenomenon:
//Magic resolver. Any symbol at all can be resolved; it'll come through as 0, but the name //will be retained. Used in the precompilation stage to capture external references. multiset(string) symbols; mixed resolv(string symbol, string fn, object handler) {symbols[symbol] = 1;} void calc(string formula) { //Precompile to get a list of used symbols symbols = (<>); //Note: As of Pike 8.1, p must be retained or the compile() call will be optimized out. program p = compile("mixed _ = " + formula + ";", this); //Compile the formula calculator itself. function f1 = compile(sprintf( "int _(mapping data) {%{int %s = (int)data->%<s;\n%}return %s;}", (array)symbols,formula ))()->_; write("Successfully compiled %O\n", formula); }
int main() { calc("STR - 2"); calc("4 ** STR"); calc("4 ** (STR + 2)"); calc("4 ** (STR - 2)"); }
Everything works fine (using Pike from master branch, c5decfee5) except the very last one, which complains that soft-casting an mpq object to int isn't valid. Other variants of this issue exhibit themselves as saying that "void" is invalid in some context.
Any idea where to look for this?
ChrisA
4^-2 is not an integer. It's 0.0625 (or 1/16, if expressed as a fraction, which seems to be what 8.1 has chosen here).
pike-devel@lists.lysator.liu.se