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