/// <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.Parsers.Position args, PHP.Core.Parsers.Position 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.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 PHP.Core.AST.Literal CreateLiteral(PHP.Core.Parsers.Position position) { if (IsBinary) { return(new PHP.Core.AST.BinaryStringLiteral(position, new PhpBytes(BinaryBuilder.ToArray()))); } else { return(new PHP.Core.AST.StringLiteral(position, UnicodeBuilder.ToString())); } }