private object FuncBody(SeparatedSyntaxList <ParameterSyntax> ps, BlockSyntax body, params object[] args) { var vf = new VarFrame(Vars); for (int i = 0; i < ps.Count; i++) { vf.SetValue($"{ps[i].Identifier}", HybInstance.Object(args[i])); } RunBlock(body as BlockSyntax, vf); if (Halt == HaltType.Return) { Halt = HaltType.None; } return(Ret.Unwrap()); }
private HybInstance RunParenthesizedLambda(ParenthesizedLambdaExpressionSyntax node) { // Detects the lambda is `Func` or `Action`. var hasReturn = node.DescendantNodes() .Any(x => x is ReturnStatementSyntax); var ps = node.ParameterList.Parameters; var retType = TypeDeduction.GetReturnType(Resolver, node.Body); MethodInfo converter = null; object body = null; // `Func` if (hasReturn) { converter = GetConverterF(ps.Count); var genericArgs = new Type[ps.Count + 1]; for (int i = 0; i < ps.Count; i++) { if (ps[i].Type == null) { throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented."); } genericArgs[i] = Resolver .GetType($"{ps[i].Type}") .Unwrap(); } genericArgs[genericArgs.Length - 1] = retType.Unwrap(); converter = converter .MakeGenericMethod(genericArgs); if (ps.Count == 0) { body = new Func <object>(() => { RunBlock(node.Body as BlockSyntax); if (Halt == HaltType.Return) { Halt = HaltType.None; } return(Ret.Unwrap()); }); } else if (ps.Count == 1) { body = new Func <object, object>((a) => { return(FuncBody(ps, node.Body as BlockSyntax, a)); }); } else if (ps.Count == 2) { body = new Func <object, object, object>((a, b) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b)); }); } else if (ps.Count == 3) { body = new Func <object, object, object, object>((a, b, c) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b, c)); }); } else if (ps.Count == 4) { body = new Func <object, object, object, object, object>((a, b, c, d) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d)); }); } else if (ps.Count == 5) { body = new Func <object, object, object, object, object, object>((a, b, c, d, e) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e)); }); } else if (ps.Count == 6) { body = new Func <object, object, object, object, object, object, object>((a, b, c, d, e, f) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f)); }); } else if (ps.Count == 7) { body = new Func <object, object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => { return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g)); }); } } // `Action` else { converter = GetConverterA(ps.Count); var genericArgs = new Type[ps.Count]; for (int i = 0; i < ps.Count; i++) { if (ps[i].Type == null) { throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented."); } genericArgs[i] = Resolver .GetType($"{ps[i].Type}") .Unwrap(); } if (ps.Count > 0) { converter = converter .MakeGenericMethod(genericArgs); } if (ps.Count == 0) { body = new Action(() => { RunBlock(node.Body as BlockSyntax); if (Halt == HaltType.Return) { Halt = HaltType.None; } }); } else if (ps.Count == 1) { body = new Action <object>((a) => { ActionBody(ps, node.Body as BlockSyntax, a); }); } else if (ps.Count == 2) { body = new Action <object, object>((a, b) => { ActionBody(ps, node.Body as BlockSyntax, a, b); }); } else if (ps.Count == 3) { body = new Action <object, object, object>((a, b, c) => { ActionBody(ps, node.Body as BlockSyntax, a, b, c); }); } else if (ps.Count == 4) { body = new Action <object, object, object, object>((a, b, c, d) => { ActionBody(ps, node.Body as BlockSyntax, a, b, c, d); }); } else if (ps.Count == 5) { body = new Action <object, object, object, object, object>((a, b, c, d, e) => { ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e); }); } else if (ps.Count == 6) { body = new Action <object, object, object, object, object, object>((a, b, c, d, e, f) => { ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f); }); } else if (ps.Count == 7) { body = new Action <object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => { ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g); }); } } var convertedDelegate = converter.Invoke( null, new object[] { body }); return(new HybInstance( HybTypeCache.GetHybType(convertedDelegate.GetType()), convertedDelegate)); }