public static PHP.Core.AST.DirectFcnCall.EvaluateInfo CreateFunction_Analyze( Analyzer analyzer, PHP.Core.AST.CallSignature callSignature, string args, string body) { if (analyzer.IsInsideIncompleteClass()) { return(null); // in this case, the DirectFnCall will not be Emitted. Therefore the lambda routine will not be declared and compilation will fail when emitting not fully declared lambda FunctionDecl. } // has to be a valid identifier: // actually this name is never used then string function_name = "__" + Guid.NewGuid().ToString().Replace('-', '_'); //DynamicCode.GenerateLambdaName(args, body); string prefix1, prefix2; DynamicCode.GetLamdaFunctionCodePrefixes(function_name, args, out prefix1, out prefix2); PHP.Core.Parsers.Position pos_args = callSignature.Parameters[0].Position; PHP.Core.Parsers.Position pos_body = callSignature.Parameters[1].Position; // function __XXXXXX(<args>){<fill><body>} string fill = GetInlinedLambdaCodeFill(pos_args, pos_body); string code = String.Concat(prefix2, fill, body, "}"); // the position of the first character of the parsed code: // (note that escaped characters distort position a little bit, which cannot be eliminated so easily) PHP.Core.Parsers.Position pos = PHP.Core.Parsers.Position.Initial; pos.FirstOffset = pos_args.FirstOffset - prefix1.Length + 1; pos.FirstColumn = pos_args.FirstColumn - prefix1.Length + 1; pos.FirstLine = pos_args.FirstLine; // parses function source code: var counter = new PHP.Core.Parsers.Parser.ReductionsCounter(); var ast = analyzer.BuildAst(pos, code, counter); if (ast == null || ast.Statements == null) { return(null); // the function cannot be parsed } Debug.Assert(counter.FunctionCount == 1); var decl_node = (PHP.Core.AST.FunctionDecl)ast.Statements[0]; // adds declaration to the end of the global code statement list: analyzer.AddLambdaFcnDeclaration(decl_node); // return(new PHP.Core.AST.DirectFcnCall.EvaluateInfo() { //.inlined = InlinedFunction.CreateFunction; emitDeclareLamdaFunction = true, // modify declaration: newRoutine = decl_node.ConvertToLambda(analyzer), }); }
public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo CreateFunction_Analyze( Analyzer analyzer, PHP.Core.AST.CallSignature callSignature, string args, string body) { if (analyzer.IsInsideIncompleteClass()) return null; // in this case, the DirectFnCall will not be Emitted. Therefore the lambda routine will not be declared and compilation will fail when emitting not fully declared lambda FunctionDecl. // has to be a valid identifier: // actually this name is never used then string function_name = "__" + Guid.NewGuid().ToString().Replace('-', '_'); //DynamicCode.GenerateLambdaName(args, body); string prefix1, prefix2; DynamicCode.GetLamdaFunctionCodePrefixes(function_name, args, out prefix1, out prefix2); PHP.Core.Parsers.Position pos_args = callSignature.Parameters[0].Position; PHP.Core.Parsers.Position pos_body = callSignature.Parameters[1].Position; // function __XXXXXX(<args>){<fill><body>} string fill = GetInlinedLambdaCodeFill(pos_args, pos_body); string code = String.Concat(prefix2, fill, body, "}"); // the position of the first character of the parsed code: // (note that escaped characters distort position a little bit, which cannot be eliminated so easily) PHP.Core.Parsers.Position pos = PHP.Core.Parsers.Position.Initial; pos.FirstOffset = pos_args.FirstOffset - prefix1.Length + 1; pos.FirstColumn = pos_args.FirstColumn - prefix1.Length + 1; pos.FirstLine = pos_args.FirstLine; // parses function source code: var counter = new PHP.Core.Parsers.Parser.ReductionsCounter(); var ast = analyzer.BuildAst(pos, code, counter); if (ast == null || ast.Statements == null) return null; // the function cannot be parsed Debug.Assert(counter.FunctionCount == 1); var decl_node = (PHP.Core.AST.FunctionDecl)ast.Statements[0]; // adds declaration to the end of the global code statement list: analyzer.AddLambdaFcnDeclaration(decl_node); // return new PHP.Core.Compiler.AST.FunctionCallEvaluateInfo() { //.inlined = InlinedFunction.CreateFunction; emitDeclareLamdaFunction = true, // modify declaration: newRoutine = Core.Compiler.AST.FunctionDeclCompilerHelper.ConvertToLambda(decl_node, analyzer), }; }