public EvaluationCallback Create(Node node)
{
var compilerstate = new CompilerState
{
FunctionState = Exp.Parameter(typeof(Character), "state"),
ErrorVariable = Exp.Parameter(typeof(bool), "error")
};
var result = Make(compilerstate, node);
if (result.Type == typeof(bool))
{
result = ToInteger(result);
}
if (result.Type == typeof(int) || result.Type == typeof(float))
{
// int or float convert to number
var constructor = typeof(Number).GetConstructor(new[] { result.Type });
result = Exp.New(constructor, new[] { result });
// wrap the evaluation in a try..catch
var exceptionParameter = Exp.Parameter(typeof(Exception), "e");
var writeLineMethod = typeof(Console).GetMethod(nameof(Console.WriteLine), new Type[] { typeof(string) });
var toStringMethod = typeof(Exception).GetMethod(nameof(Exception.ToString));
var catchBody = Exp.Block(
Exp.Call(null, writeLineMethod, Exp.Call(exceptionParameter, toStringMethod)),
Exp.Constant(new Number(0)));
result = Exp.TryCatch(result, Exp.Catch(exceptionParameter, catchBody));
// create lambda
var func = Exp.Lambda <Func <Character, bool, Number> >(result, compilerstate.FunctionState, compilerstate.ErrorVariable).Compile();
return(new EvaluationCallback(o => func(o, false)));
}
throw new Exception();
}