public override Structure CallWithArgsPushedAlready() { int throwAway = OpcodeCall.StaticExecute(Cpu, true, Name, true); // throwAway will be -1 for cases where it's a builtin function. // and the return value will be left atop the stack by StaticExecute. return(new KOSPassThruReturn()); }
public override Structure Call() { int absoluteJumpTo = OpcodeCall.StaticExecute(Cpu, false, "", true); if (absoluteJumpTo >= 0) { Cpu.InstructionPointer = absoluteJumpTo - 1; // -1 because it increments by 1 automatically between instructions. } // Remember this is just a special flag telling OpcodeCall to never place // this suffix's C# delegate return value on the stack. It's like saying // "even more void that void", because normally even a void suffix gets a // dummy return value. This says to not even do that - just offload the // responsibility for pushing a return value onto the user code that is // about to be jumped into. return(new KOSPassThruReturn()); }
/// <summary> /// Do the work for function calls. /// </summary> /// <param name="node">parse node for the function term of the parse tree.</param> /// <param name="isDirect">true if it should make an OpcodeCall that is Direct, false if it should make an indirect one. /// See the documentation for OpcodeCall.Direct for the full explanation of the difference. If isDirect is true, then /// the name to the left of the parentheses will be the name of the function call. If isDirect is false, then it will /// ignore the name to the left of the parentheses and presume the function name, delegate, or branch index was /// already placed atop the stack by other parts of this compiler.</param> /// <param name="directName">In the case where it's a direct function, what's the name of it? In the case /// where it's not direct, this argument doesn't matter.</param> private void VisitActualFunction(ParseNode node, bool isDirect, string directName = "") { NodeStartHousekeeping(node); ParseNode trailerNode = node; // the function_trailer rule is here. // Need to tell OpcodeCall where in the stack the bottom of the arg list is. // Even if there are no arguments, it still has to be TOLD that by showing // it the marker atop the stack with nothing above it. AddOpcode(new OpcodePush(new KOSArgMarkerType())); if (trailerNode.Nodes[1].Token.Type == TokenType.arglist) { bool remember = identifierIsSuffix; identifierIsSuffix = false; VisitNode(trailerNode.Nodes[1]); identifierIsSuffix = remember; } if (isDirect) { if (options.FuncManager.Exists(directName)) // if the name is a built-in, then add the "()" after it. directName += "()"; AddOpcode(new OpcodeCall(directName)); } else { var op = new OpcodeCall(string.Empty) { Direct = false }; AddOpcode(op); } }