public override void Accept(FunctionDeclaration node) { // Add the function name to the scope symbolTable.AddSymbol(node.Name.Value); // Begin a new scope symbolTable.InvokeInNewScope(() => { // Iterate over the function arguments foreach (var arg in node.Arguments) { // Add the argument to the scope symbolTable.AddSymbol(arg.Name.Value); } // Visit the children of the function declaration node.VisitChildren(this); }); }
/* * 'fn' < name > < argument_list > < code_block > */ FunctionDeclaration ParseFunctionDeclaration() { var node = new FunctionDeclaration(unit.Location); // Expect the 'fn' keyword unit.Expect(TokenClass.Keyword, "fn"); // Read the name of the function node.Name = ParseName(); // Read the argument list node.Arguments.AddRange(ParseDeclarationArgumentList()); // Parse the function body node.Body = ParseBlock(); // Return the function declaration return(node); }
public virtual void Accept(FunctionDeclaration node) => Update(node);
public override void Accept(FunctionDeclaration node) { // Add the function name to the scope Context.SymbolTable.AddSymbol(node.Name.Value); // Invoke the following action within a new scope Context.SymbolTable.InvokeInNewScope(() => { // Create an emitter for the function body var body = new Emitter(); // Invoke the following action within a new context InvokeInNewContext(body, () => { // Iterate over the arguments of the function foreach (var arg in node.Arguments) { // Add the argument name to the scope Context.SymbolTable.AddSymbol(arg.Name.Value); // Test if the argument has a type hint if (arg.HasTypeHint) { // Compile the type hint arg.TypeHint.Visit(this); // Create a name object for the argument name var name = new IodineName(arg.Name.Value); // Make the name constant var constant = Context.Module.DefineConstant(name); // Perform a behavior check on the object Context.Emitter.Emit( opcode: Opcode.CastLocal, arg: constant ); } } // Visit the children of the function node.VisitChildren(this); }); // Resolve the function body body.Resolve(); // Create method flags var flags = MethodFlags.None; // TODO: Implement method flags // Iterate over the arguments of the function foreach (var arg in node.Arguments) { // Create a string object with the name of the argument var str = new IodineString(arg.Name.Value); // Make the string object constant var constant = Context.Module.DefineConstant(str); // Load the constant argument name string Context.Emitter.Emit( opcode: Opcode.LoadConst, arg: constant ); } // Build a tuple to hold [argument_count] elements Context.Emitter.Emit( opcode: Opcode.BuildTuple, arg: node.Arguments.Count ); // Enter a new scope to satisfy the C# compiler { // Make the generated byte code constant var constant = Context.Module.DefineConstant(body); // Load the generated byte code as constant Context.Emitter.Emit( opcode: Opcode.LoadConst, arg: constant ); } // Build the function Context.Emitter.Emit( opcode: Opcode.BuildFunction, arg: (int)flags ); }); }