private static string GetFunctionMarkdown(FunctionSymbol function, FunctionCallSyntax functionCall, SemanticModel model)
        {
            var buffer = new StringBuilder();

            buffer.Append($"```bicep\nfunction ");
            buffer.Append(function.Name);
            buffer.Append('(');

            const string argumentSeparator = ", ";

            foreach (FunctionArgumentSyntax argumentSyntax in functionCall.Arguments)
            {
                var argumentType = model.GetTypeInfo(argumentSyntax);
                buffer.Append(argumentType);

                buffer.Append(argumentSeparator);
            }

            // remove trailing argument separator (if any)
            if (functionCall.Arguments.Length > 0)
            {
                buffer.Remove(buffer.Length - argumentSeparator.Length, argumentSeparator.Length);
            }

            buffer.Append("): ");
            buffer.Append(model.GetTypeInfo(functionCall));
            buffer.Append("\n```");

            return(buffer.ToString());
        }
Beispiel #2
0
        void ProcessCallExpression_throw_when_param_number_not_match()
        {
            var scope = new SymbolScope();

            var name = new IdentifierToken("print", default);

            var funcSymbol = new FunctionSymbol(name.Value, DataType.Long, new DataType[] { DataType.Long });

            scope.AddSymbol(funcSymbol);

            var param1        = new Mock <ExpressionAst>().Object;
            var param2        = new Mock <ExpressionAst>().Object;
            var callParamList = new CallParamListAst(new[] { param1, param2 });

            var ast = new CallExpressionAst(
                name, new OperatorToken(Operator.LeftParen, default), callParamList,
                new OperatorToken(Operator.RightParen, default));

            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(param1)).Returns(DataType.Long);
                mock.Setup(p => p.ProcessExpression(param2)).Returns(DataType.Long);
            });

            Assert.Throws <SemanticException>(() => generator.ProcessCallExpression(ast));
        }
Beispiel #3
0
        public FuncCallExpression(FunctionSymbol symbol, Expression[] parameters) : base(symbol.ReturnType)
        {
            this.symbol     = symbol;
            this.parameters = parameters;

            // TODO : Check parameter types against function signature.
        }
Beispiel #4
0
        void ProcessCallExpression_returns_returnType_when_ok()
        {
            var scope = new SymbolScope();

            var name = new IdentifierToken("print", default);

            var funcSymbol = new FunctionSymbol(name.Value, DataType.Long,                            // return
                                                new DataType[] { DataType.Double, DataType.Double }); // need

            scope.AddSymbol(funcSymbol);

            var param1        = new Mock <ExpressionAst>().Object;
            var param2        = new Mock <ExpressionAst>().Object;
            var callParamList = new CallParamListAst(new[] { param1, param2 });

            var ast = new CallExpressionAst(
                name, new OperatorToken(Operator.LeftParen, default), callParamList,
                new OperatorToken(Operator.RightParen, default));

            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(param1)).Returns(DataType.Double); // provide
                mock.Setup(p => p.ProcessExpression(param2)).Returns(DataType.Double); // provide
            });

            Assert.Equal(DataType.Long, generator.ProcessCallExpression(ast));
        }
Beispiel #5
0
        public static BoundBlockStatement Flatten(FunctionSymbol function, BoundStatement node)
        {
            var builder = ImmutableArray.CreateBuilder <BoundStatement>();
            var stack   = new Stack <BoundStatement>();

            stack.Push(node);

            while (stack.Count > 0)
            {
                var current = stack.Pop();
                if (current is BoundBlockStatement block)
                {
                    foreach (var s in block.Statements.Reverse())
                    {
                        stack.Push(s);
                    }
                }
                else
                {
                    builder.Add(current);
                }
            }
            if (function.ReturnType == TypeSymbol.Void)
            {
                if (builder.Count == 0 || CanFallThrough(builder.Last()))
                {
                    builder.Add(new BoundReturnStatement(null, true));
                }
            }

            return(new BoundBlockStatement(builder.ToImmutable(), node.IsValid));
        }
Beispiel #6
0
        public static BoundBlockStatement Lower(FunctionSymbol function, BoundStatement body)
        {
            var lowerer = new Lowerer();
            var res     = lowerer.RewriteStatement(body);

            return(RemoveDeadCode(Flatten(function, res)));
        }
Beispiel #7
0
 public BoundCallExpression(FunctionSymbol function, ImmutableArray <BoundExpression> arguments, string @namespace, ClassSymbol inClass = null)
 {
     Function  = function;
     Arguments = arguments;
     Namespace = @namespace;
     InClass   = inClass;
 }
        public override bool Execute()
        {
            FunctionSymbol functionSymbol = GlobalSymbolTable.table.GetFunctionSymbol(_functionName);

            if (functionSymbol.Arguments.Count != _arguments.Count)
            {
                throw new Exception("Incorrect number of arguments passed to function: Expecting " + functionSymbol.Arguments.Count + " passed " + _arguments.Count);
            }

            //Checks that arguments passed to function are what the function is expecting
            for (int i = 0; i < _arguments.Count; i++)
            {
                //Incorrect type passed to the function
                if (_arguments[i].Value.Type != functionSymbol.Arguments[i].Value.Type)
                {
                    throw new Exception("Incorrect type passed to function: Expecting " + functionSymbol.Arguments[i].Value.Type + " passed " + _arguments[i].Value.Type);
                }

                //Creates every argument as a variable for the function to use
                VariableDeclerationStatement variable = new VariableDeclerationStatement(_arguments[i].Value.Type, functionSymbol.Arguments[i].ArgumentName, _arguments[i].Value);
                variable.Execute();
            }

            //Executes all function statements
            foreach (Statement statement in functionSymbol.Statements)
            {
                statement?.Execute();
            }

            return(true);
        }
Beispiel #9
0
        /// <summary>
        ///		Inserts the given instruction at the given index.
        /// </summary>
        /// <param name="index">Index to insert instruction at.</param>
        /// <param name="insertInstruction">Instruction to insert.</param>
        private void InsertInstruction(int index, Instruction insertInstruction)
        {
            // Update the instruction index's of the instruction index operands.
            foreach (Instruction instruction in _instructionList)
            {
                for (int i = 0; i < instruction.OperandCount; i++)
                {
                    Operand operand = instruction[i];
                    if (operand.OpType == OperandType.InstrIndex && operand.InstrIndex > index)
                    {
                        operand.InstrIndex++;
                    }
                }
            }

            // Update the entry points of the functions.
            foreach (Symbol symbol in _symbolList)
            {
                if (symbol.Type == SymbolType.Function)
                {
                    FunctionSymbol functionSymbol = (FunctionSymbol)symbol;
                    if (functionSymbol.EntryPoint > index && functionSymbol.IsImport == false)
                    {
                        functionSymbol.EntryPoint++;
                    }
                }
            }

            _instructionList.Insert(index, insertInstruction);
            _instructionIndex += 1;
        }
Beispiel #10
0
        /**
         * 네이티브 라이브러리를 심볼 테이블에 로드한다.
         *
         * @param symbolTable
         */
        public void load(SymbolTable symbolTable)
        {
            // 클래스 입력
            foreach (int i in Enumerable.Range(0, classes.Count))
            {
                symbolTable.classes.Add(new ClassSymbol(classes[i].className));
            }

            // 함수 입력
            foreach (int i in Enumerable.Range(0, functions.Count))
            {
                List <VariableSymbol> parameters = new List <VariableSymbol>();

                // 파라미터 처리
                foreach (int j in Enumerable.Range(0, functions[i].parameters.Count))
                {
                    parameters.Add(new VariableSymbol("native_arg_" + j.ToString(), functions[i].parameters[j]));
                }

                // 함수 심볼 객체 생성
                FunctionSymbol functn = new FunctionSymbol(functions[i].functionName, functions[i].returnType, parameters);

                functn.isNative       = true;
                functn.nativeFunction = functions[i];

                symbolTable.functions.Add(functn);
            }
        }
Beispiel #11
0
        private FunctionSymbol MatchCompatibleOverload(ExpressionNode node, FunctionSymbol candidate, Expression[] arguments, out Expression[] convertedArguments)
        {
            var parameters = candidate.Parameters.ToArray();

            if (arguments.Length != parameters.Length)
            {
                convertedArguments = null;
                return(null);
            }

            convertedArguments = new Expression[arguments.Length];

            for (var i = 0; i < arguments.Length; i++)
            {
                var argument  = arguments[i];
                var parameter = parameters[i];

                var conversionExpression = BindConversion(node, argument, parameter.Type, allowExplicit: false, noDiagnostics: true);
                if (conversionExpression is InvalidExpression)
                {
                    return(null);
                }

                convertedArguments[i] = conversionExpression;
            }

            return(candidate);
        }
Beispiel #12
0
        private FunctionSymbol BindFunctionDeclaration(FunctionDeclarationNode node)
        {
            var seenParameterNames = new HashSet <string>();

            var parameters = new List <ParameterSymbol>();

            foreach (var parameterNode in node.ParametersDeclaration.Parameters)
            {
                var parameterName = parameterNode.MainToken.Text;
                var parameterType = BindTypeClause(parameterNode.Type);
                if (seenParameterNames.Add(parameterName))
                {
                    var parameter = new ParameterSymbol(parameterName, parameterType);
                    parameters.Add(parameter);
                }
                else
                {
                    diagnostics.ReportParameterAlreadyDeclared(parameterNode.MainToken, parameterName);
                }
            }

            var type = BindTypeClause(node.ReturnType) ?? BuiltinTypes.Void;

            var function = new FunctionSymbol(node.FunctionName.Text, parameters, type, node);

            if (Scope.TryDeclareFunction(function))
            {
                return(function);
            }

            diagnostics.ReportSymbolAlreadyDeclared(node.FunctionName, function.Name, "Function");
            return(null);
        }
Beispiel #13
0
        private static void WriteFunctionTo(FunctionSymbol symbol, TextWriter writer)
        {
            writer.WriteKeyword(SyntaxKind.FuncKeyword);
            writer.WriteSpace();
            writer.WriteIdentifier(symbol.Name);
            writer.WritePunctuation(SyntaxKind.OpenParenToken);

            for (var i = 0; i < symbol.Parameters.Length; i++)
            {
                if (i > 0)
                {
                    writer.WritePunctuation(SyntaxKind.CommaToken);
                }

                writer.WriteSpace();
                symbol.Parameters[i].WriteTo(writer);
                writer.WriteSpace();
            }

            writer.WritePunctuation(SyntaxKind.CloseParenToken);
            writer.WriteSpace();
            writer.WritePunctuation(SyntaxKind.ColonToken);
            writer.WriteSpace();
            symbol.ReturnType.WriteTo(writer);
        }
Beispiel #14
0
        public static BoundBlockStatement Lower(FunctionSymbol function, BoundStatement statement)
        {
            var lowerer = new Lowerer();
            var result  = lowerer.RewriteStatement(statement);

            return(Flatten(function, result));
        }
Beispiel #15
0
        private void BuildParameter(ParameterDeclarationNode parameterDeclarationNode, bool buildArray = false)
        {
            if (parameterDeclarationNode.ParentNode is FunctionDefinitionNode functionDefinitionNode)
            {
                FunctionSymbol functionSymbol    = (FunctionSymbol)functionDefinitionNode.Symbol;
                string         parameterName     = parameterDeclarationNode.NameNode.Value;
                string         parameterTypeName = parameterDeclarationNode.TypeNameCapitalized;

                ParameterSymbol parameterSymbol;
                if (functionSymbol.IsExternal)
                {
                    parameterSymbol = buildArray
                        ? new ExternalParameterArraySymbol(functionSymbol, parameterTypeName, parameterName, parameterDeclarationNode)
                        : new ExternalParameterSymbol(functionSymbol, parameterTypeName, parameterName, parameterDeclarationNode);
                }
                else
                {
                    parameterSymbol = buildArray
                        ? new ParameterArraySymbol(functionSymbol, parameterTypeName, parameterName, parameterDeclarationNode)
                        : new ParameterSymbol(functionSymbol, parameterTypeName, parameterName, parameterDeclarationNode);
                }
                AddSymbol(parameterSymbol);
            }
            else
            {
                throw new Exception();
            }
        }
Beispiel #16
0
        private void OutputFunctionBody(FunctionSymbol symbol, BoundBlock body)
        {
            builder.AddFragment(new OutputFragment("Function ", StatementColour));
            builder.AddFragment(new OutputFragment(symbol.Name, FunctionNameColour));
            builder.AddFragment(new OutputFragment(DelimeterString, DefaultColour));
            builder.AddFragment(new OutputFragment(symbol.ReturnType.Name, TypeColour));
            builder.NewLine();

            var paramCount = symbol.Parameters.Length;

            if (paramCount > 0)
            {
                builder.AddFragment(new OutputFragment("Parameters ", StatementColour));

                for (int index = 0; index < paramCount - 1; index++)
                {
                    builder.AddFragment(new OutputFragment(symbol.Parameters[index].Name, VariableColour));
                    builder.AddFragment(new OutputFragment(DelimeterString, DefaultColour));
                    builder.AddFragment(new OutputFragment(symbol.Parameters[index].ValueType.Name, TypeColour));
                    builder.AddFragment(new OutputFragment(", ", StatementColour));
                }

                builder.AddFragment(new OutputFragment(symbol.Parameters[paramCount - 1].Name, VariableColour));
                builder.AddFragment(new OutputFragment(DelimeterString, DefaultColour));
                builder.AddFragment(new OutputFragment(symbol.Parameters[paramCount - 1].ValueType.Name, TypeColour));
                builder.NewLine();
            }

            OutputStatements(body.Statements, IndentString);
        }
Beispiel #17
0
        private void PrintFunctionSymbol(FunctionSymbol symbol)
        {
            var parameters = new StringBuilder();

            parameters.Append('(');
            foreach (var parameter in symbol.Syntax.Parameters)
            {
                parameters.Append(parameter.SpecifiedType?.FullName);
                parameters.Append(", ");
            }

            if (parameters.Length > 1)
            {
                parameters.Remove(parameters.Length - 2, 2);
            }
            parameters.Append(')');
            PrintStart("Function: " + symbol.Syntax.FullName + parameters, ConsoleColor.Blue);

            if (symbol.AllChecked.Count > 1)
            {
                foreach (var checkedFunction in symbol.AllChecked)
                {
                    PrintCheckedFunction(checkedFunction);
                }
            }

            _indentationLevel--;
        }
        private void ParseFunctionDecl(SymTable symTable)
        {
            var      c            = Current;
            SymTable procSymTable = new SymTable {
                Parent = symTable
            };
            var h = ParseFunctionHeading(procSymTable);

            Require(Semicolon);
            if (symTable.Contains(h.Name))
            {
                throw new ParserException("Duplicate identifier {h.Name}", c.Line, c.Position);
            }
            var f = new FunctionSymbol
            {
                Name       = h.Name,
                Parameters = h.Parameters,
                ReturnType = h.ReturnType
            };

            symTable.Add(h.Name, f);
            var backup = CurrentReturnType;

            CurrentReturnType = f.ReturnType;
            var b = ParseBlock(procSymTable);

            CurrentReturnType = backup;
            Require(Semicolon);
            f.Block = b;
        }
Beispiel #19
0
        private void BindFunctionDeclaration(FunctionDeclarationSyntax syntax)
        {
            var parameters = ImmutableArray.CreateBuilder <ParameterSymbol>();

            var seenParameterNames = new HashSet <string>();

            foreach (var parameterSyntax in syntax.Parameters)
            {
                var parameterName = parameterSyntax.Identifier.Text;
                var parameterType = BindTypeClause(parameterSyntax.Type);
                if (!seenParameterNames.Add(parameterName))
                {
                    _diagnostics.ReportParameterAlreadyDeclared(parameterSyntax.Span, parameterName);
                }
                else
                {
                    var parameter = new ParameterSymbol(parameterName, parameterType);
                    parameters.Add(parameter);
                }
            }

            var type = BindTypeClause(syntax.Type) ?? TypeSymbol.Void;

            if (type != TypeSymbol.Void)
            {
                _diagnostics.XXX_ReportFunctionsAreUnsupported(syntax.Type.Span);
            }

            var function = new FunctionSymbol(syntax.Identifier.Text, parameters.ToImmutable(), type, syntax);

            if (!_scope.TryDeclareFunction(function))
            {
                _diagnostics.ReportSymbolAlreadyDeclared(syntax.Identifier.Span, function.Name);
            }
        }
 private static void AppendFunctionSymbolInfo(this ICollection<SymbolMarkupToken> markup, FunctionSymbol symbol)
 {
     markup.AppendType(symbol.ValueType);
     markup.AppendSpace();
     markup.AppendName(SymbolMarkupKind.FunctionName, symbol.Name);
     markup.AppendParameters(symbol.Parameters);
 }
Beispiel #21
0
        private static BoundBlockStatement Flatten(FunctionSymbol function, BoundStatement statement)
        {
            var builder = ImmutableArray.CreateBuilder <BoundStatement>();
            var stack   = new Stack <BoundStatement>();

            stack.Push(statement);

            while (stack.Count > 0)
            {
                var current = stack.Pop();

                if (current is BoundBlockStatement block)
                {
                    foreach (var syntax in block.Statements.Reverse())
                    {
                        stack.Push(syntax);
                    }
                }
                else
                {
                    builder.Add(current);
                }
            }

            if (function.ReturnType == BuiltinTypes.Void)
            {
                if (builder.Count == 0 || CanFallThrough(builder.Last()))
                {
                    builder.Add(new BoundReturnStatement(statement.Syntax, null));
                }
            }

            return(new BoundBlockStatement(statement.Syntax, builder.ToImmutable()));
        }
        public static bool AllPathsReturn(FunctionSymbol symbol, BoundBlockStatement body)
        {
            if (symbol.ReturnType == TypeSymbol.Void)
            {
                return(true);
            }
            if (!body.IsValid)
            {
                return(false);
            }

            var graph = Create(body);

            foreach (var toEnd in graph.End.Incoming)
            {
                if (!toEnd.From.Statements.Any())
                {
                    return(false);
                }
                if (toEnd.From.Statements.Last().Kind != BoundNodeKind.BoundReturnStatement)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #23
0
        void ExpressionStatement_generates_pop_if_expr_not_returning_void()// not correct!!!
        {
            // Arrange
            var scope = new SymbolScope();

            var expr = new Mock <ExpressionAst>().Object;

            var generator = ConfigureGenerator(scope, mock =>
            {
                mock.Setup(p => p.ProcessExpression(expr)).Returns(DataType.Long);
            });

            var ast = new ExpressionStatementAst(expr, new OperatorToken(Operator.Semicolon, default));

            var function = new FunctionSymbol("p", DataType.Void, new DataType[0]);

            generator.GlobalBuilder.RegisterFunction(function);
            generator.EnterFunctionDefination(function);

            // Act
            generator.ProcessExpressionStatement(ast);

            // Assert
            var instructions = generator.CurrentFunction.Builder.Bucket.Pop();

            Assert.Single(instructions);
            Assert.Equal("pop", instructions[0].Parts.Single());
        }
Beispiel #24
0
        public static ControlFlowGraph CreateGraph(BoundBlock block, FunctionSymbol function = null)
        {
            var blockBuilder = new BasicBlockBuilder();
            var edgeBuilder  = new GraphBuilder(function);
            var blocks       = blockBuilder.Build(block);

            return(edgeBuilder.Build(blocks));
        }
Beispiel #25
0
        public BoundFunctionPointer(FunctionSymbol function)
        {
            Function = function;

            var paramTypes = function.Parameters.Select(param => param.ValueType).ToImmutableArray();

            ValueType = new FunctionTypeSymbol(paramTypes, function.ReturnType);
        }
Beispiel #26
0
        public void EmitTree(FunctionSymbol function, TextWriter writer)
        {
            var tree = Program.Functions[function];

            function.WriteTo(writer);
            writer.WriteLine();
            tree.WriteTo(writer);
        }
Beispiel #27
0
            public GraphBuilder(FunctionSymbol function)
            {
                blockFromStatement = new Dictionary <BoundStatement, BasicBlock>();
                blockFromLabel     = new Dictionary <LabelSymbol, BasicBlock>();
                edges = new List <BasicBlockEdge>();

                start = new BasicBlock(true, function);
                end   = new BasicBlock(false, function);
            }
Beispiel #28
0
        public static BoundBlockStatement Lower(FunctionSymbol function, BoundStatement statement)
        {
            var lowerer               = new Lowerer();
            var result                = lowerer.RewriteStatement(statement);
            var flattenedResult       = Flatten(function, result);
            var removedDeadCodeResult = RemoveDeadCode(flattenedResult);

            return(removedDeadCodeResult);
        }
Beispiel #29
0
        public StandardLibraryDefinitionsStatement(SymbolTable table)
        {
            printInt   = table.PutFunc(WordToken.PrintF.Lexeme, typeof(void), new[] { typeof(int) });
            printFloat = table.PutFunc(WordToken.PrintF.Lexeme, typeof(void), new[] { typeof(float) });
            printChar  = table.PutFunc(WordToken.PrintF.Lexeme, typeof(void), new[] { typeof(char) });
            printBool  = table.PutFunc(WordToken.PrintF.Lexeme, typeof(void), new[] { typeof(bool) });

            scanF = table.PutFunc(WordToken.ScanF.Lexeme, typeof(string), new Type[0]);
        }
        private static IList <SymbolMarkupToken> GetMethodGroupPreambleParts(FunctionSymbol method)
        {
            var result = new List <SymbolMarkupToken>();

            result.AddRange(method.ToMarkup(SymbolDisplayFormat.MinimallyQualifiedWithoutParameters).Tokens);
            result.Add(new SymbolMarkupToken(SymbolMarkupKind.Punctuation, "("));

            return(result);
        }
Beispiel #31
0
 public bool TryDeclareFunction(FunctionSymbol function)
 {
     if (functions.ContainsKey(function.Name))
     {
         return(false);
     }
     functions.Add(function.Name, function);
     return(true);
 }
        private static void AppendFunctionSymbolInfo(this ICollection<SymbolMarkupToken> markup, FunctionSymbol symbol)
        {
            markup.AppendType(symbol.ReturnType, false);
            markup.AppendSpace();

            if (symbol.Parent is TypeSymbol)
            {
                markup.AppendTypeName((TypeSymbol) symbol.Parent);
                markup.AppendPunctuation(".");
            }

            if (symbol.IsNumericConstructor)
                markup.AppendKeyword(symbol.Name);
            else
                markup.AppendName(SymbolMarkupKind.FunctionName, symbol.Name);

            markup.AppendParameters(symbol.Parameters);
        }
Beispiel #33
0
 FunctionSymbol CreateFunctionDef(BuiltIns.FuncShape fn)
     {
     IType       returnType  = ConvertTypeAndNullable(fn.ReturnType);
     List<IType> formalTypes = fn.FormalTypes.ConvertAll(desc => ConvertTypeAndNullable(desc));
     //
     FunctionSymbol symFunctionDef = new FunctionSymbol(fn.Name, returnType, this.builtins);
     NadirAST nodeFunctionDef      = new NadirAST(NadirParser.FunctionDef);
     NadirAST nodeReturnType       = CreateBuiltinTypeNode(returnType);
     NadirAST nodeFormalParams     = new NadirAST(NadirParser.FormalParams);
     NadirAST nodeOptions          = new NadirAST(NadirParser.Options);
     //
     nodeFunctionDef.AddChild(CreateNameNode(fn.Name));                  // 0
     nodeFunctionDef.AddChild(nodeReturnType);                           // 1
     nodeFunctionDef.AddChild(nodeFormalParams);                         // 2
     nodeFunctionDef.AddChild(new NadirAST(NadirParser.Statements));     // 3
     nodeFunctionDef.AddChild(nodeOptions);                              // 4
     //
     for (int i = 0; i < fn.FormalNames.Count; i++)
         {
         NadirAST nodeFormalParam   = new NadirAST(NadirParser.FormalParam);
         NadirAST nodeName          = CreateNameNode(fn.FormalNames[i]);
         NadirAST nodeType          = CreateBuiltinTypeNode(formalTypes[i]);
         NadirAST nodeFormalOptions = new NadirAST(NadirParser.Options);
         nodeFormalParam.AddChild(nodeName);
         nodeFormalParam.AddChild(nodeType);
         nodeFormalParam.AddChild(nodeFormalOptions);
         //
         if (fn.FormalTypes[i].IsRef)      nodeFormalOptions.AddChild(new NadirAST(NadirParser.Ref));
         if (fn.FormalTypes[i].IsOut)      nodeFormalOptions.AddChild(new NadirAST(NadirParser.Out));
         if (i==0 && fn.IsMethod)          nodeFormalOptions.AddChild(new NadirAST(NadirParser.This));
         //
         NadirASTDefineSymbols.LinkSymbolWithDefinition(nodeFormalParam, new VariableSymbol(fn.FormalNames[i], false, null));
         NadirASTDefineTypes.SetResolvedTypeOfDefinition(nodeFormalParam, formalTypes[i]);
         //
         Debug.Assert(FormalParameter.FormalParamName(nodeFormalParam)==nodeName);
         Debug.Assert(FormalParameter.FormalParamType(nodeFormalParam)==nodeType);
         //
         nodeFormalParams.AddChild(nodeFormalParam);
         }
     //
     if (fn.IsVariadic)  nodeOptions.AddChild(new NadirAST(NadirParser.Variadic));
     if (fn.IsHoldFirst) nodeOptions.AddChild(new NadirAST(NadirParser.HoldFirst));
     if (fn.IsHoldRest)  nodeOptions.AddChild(new NadirAST(NadirParser.HoldRest));
     if (fn.IsHoldAll)   nodeOptions.AddChild(new NadirAST(NadirParser.HoldAll));
     //
     NadirASTDefineSymbols.LinkSymbolWithDefinition(nodeFunctionDef, symFunctionDef);
     NadirASTDefineTypes.SetResolvedTypeOfDefinition(nodeFunctionDef, returnType);
     //
     symFunctionDef.NoteOptions();
     //
     return symFunctionDef;
     }