/* * Compiles a lambda down to a function and returns the function to caller. */ static Tuple <object, bool> CompileLambda <TContext>(IEnumerator <string> en) { // Compiling body, and retrieving functions. var tuples = CompileStatements <TContext>(en); var functions = tuples.Item1; /* * Creating a function that evaluates every function sequentially, and * returns the result of the last function evaluation to the caller. */ FunctionAsync <TContext> function = new FunctionAsync <TContext>(async(ctx, binder, arguments) => { object result = null; foreach (var ix in functions) { if (ix is FunctionAsync <TContext> ) { result = await((FunctionAsync <TContext>)ix)(ctx, binder, null); } else { result = ((Function <TContext>)ix)(ctx, binder, null); } var r = result as ReturnValue; if (r != null) { return(r); } } return(result); }); /* * Making sure the body becomes evaluated lazy. * * Notice! * A body is the only thing that is "by default" evaluated as "lazy" in * Lizzie, and does not require the '@' character to accomplish "lazy * evaluation". */ var lazyFunction = new Function <TContext>((ctx2, binder2, arguments2) => { return(function); }); return(new Tuple <object, bool>(lazyFunction, tuples.Item2 || !en.MoveNext())); }
public async Task SymbolicallyReferencedFunctionInvocationReturningInteger() { var code = "foo()"; var tokenizer = new Tokenizer(new LizzieTokenizer()); var function = Compiler.Compile <LambdaCompiler.Nothing>(tokenizer, code); var ctx = new LambdaCompiler.Nothing(); var binder = new Binder <LambdaCompiler.Nothing>(); binder["foo"] = new FunctionAsync <LambdaCompiler.Nothing>((ctx2, binder2, arguments) => { return(Task.FromResult((object)57)); }); var result = await function(ctx, binder); Assert.AreEqual(57, result); }
/* * Binds a Lizzie function "deeply", to make it possible to create a * delegate that is able to invoke methods in super classes * as Lizzie functions. * * Useful in for instance IoC (Dependency Injection) and similar scenarios * where you don't have access to the implementing bound type through its * generic argument. */ void BindDeepMethod(MethodInfo method, string functionName, TContext context) { SanityCheckSignature(method, functionName); /* * Wrapping our "deep" delegate invocation inside a "normal" function invocation. * Excactly how, depends upon whether or not the bound method is static or not. */ if (!method.IsStatic) { var lateBound = CreateInstanceFunction(method); _staticBinder[functionName] = new FunctionAsync <TContext>(async(ctx, binder, arguments) => { return(await lateBound(ctx, new object[] { binder, arguments })); }); } else { var lateBound = CreateStaticFunction(method); _staticBinder[functionName] = new FunctionAsync <TContext>(async(ctx, binder, arguments) => { return(await lateBound(new object[] { ctx, binder, arguments })); }); } }
/* * Compiles a constant string down to a symbol and returns to caller. */ static Tuple <object, bool> CompileString <TContext>(IEnumerator <string> en) { // Storing type of string literal quote. var quote = en.Current; // Sanity checking tokenizer's content. if (!en.MoveNext()) { throw new LizzieParsingException($"Unexpected EOF after {quote}."); } // Retrieving actual string constant, and discarding closing quote character. var stringConstant = en.Current; en.MoveNext(); // Returning a function that evaluates to the actual string's constant value. var function = new FunctionAsync <TContext>(async(ctx, binder, arguments) => { return(stringConstant); }); return(new Tuple <object, bool>(function, !en.MoveNext())); }
public async void StartAll(FunctionAsync f) { await Task.Run(() => f()); }