public override void Accept(NameExpression node) { // Create the name object var name = new IodineName(node.Value); // Make the name constant var constant = Context.Module.DefineConstant(name); // Test if the name exists in the current scope if (Context.SymbolTable.FindSymbol(node.Value)) { // Load the name as local Context.Emitter.Emit( opcode: Opcode.LoadLocal, arg: constant ); // We're done here return; } // Test if the contaxt exists within a class if (Context.IsWithinClass) { // Load the name as attribute Context.Emitter.Emit( opcode: Opcode.LoadAttribute, arg: constant ); // We're done here return; } // Load the name as global Context.Emitter.Emit( opcode: Opcode.LoadGlobal, arg: constant ); }
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 ); }); }