/// <summary> /// Gets a string which is used as a fill in the code to be parsed in order to maintain /// correct token positioning. /// </summary> /// <param name="args">A position of string literal holding source code for lambda function arguments.</param> /// <param name="body">A position of string literal holding source code for the body.</param> /// <returns>A string containing spaces and end-of-line characters '\n'.</returns> private static string GetInlinedLambdaCodeFill(PHP.Core.Text.TextSpan args, PHP.Core.Text.TextSpan body) { int delta_lines = body.FirstLine - args.LastLine; if (delta_lines == 0) { // ....args.......'_____,_______________'.......body..... // ...............)_________fill________{................ return(new String(' ', body.FirstColumn - args.LastColumn - 1)); } else { // source: // .....args.....'_____\r\n // _________,_____\r\n // ____________'......body..... // code to parse: // .....args....'\n // \n // ____fill____{.....body...... // the same number of lines as it is in the source file + leading columns: return(new System.Text.StringBuilder(delta_lines + body.FirstColumn). Append('\n', delta_lines).Append(' ', body.FirstColumn).ToString()); } }
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); var pos_args = new PHP.Core.Text.TextSpan(analyzer.SourceUnit.LineBreaks, callSignature.Parameters[0].Span); var pos_body = new PHP.Core.Text.TextSpan(analyzer.SourceUnit.LineBreaks, callSignature.Parameters[1].Span); // function __XXXXXX(<args>){<fill><body>} string fill = GetInlinedLambdaCodeFill(pos_args, pos_body); string code = String.Concat(prefix2, fill, body, "}"); // parses function source code: // 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) var counter = new PHP.Core.Parsers.Parser.ReductionsCounter(); var ast = analyzer.BuildAst(pos_args.Start.Position - prefix1.Length + 1, 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), }); }
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); var pos_args = new PHP.Core.Text.TextSpan(analyzer.SourceUnit.LineBreaks, callSignature.Parameters[0].Span); var pos_body = new PHP.Core.Text.TextSpan(analyzer.SourceUnit.LineBreaks, callSignature.Parameters[1].Span); // function __XXXXXX(<args>){<fill><body>} string fill = GetInlinedLambdaCodeFill(pos_args, pos_body); string code = String.Concat(prefix2, fill, body, "}"); // parses function source code: // 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) var counter = new PHP.Core.Parsers.Parser.ReductionsCounter(); var ast = analyzer.BuildAst(pos_args.Start.Position - prefix1.Length + 1, 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), }; }