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); }); }
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 ); }); }