This commit is contained in:
@@ -14,6 +14,7 @@ namespace Axiom.Interpreter
|
|||||||
private BinaryWriter outputStream; // the assigned output stream
|
private BinaryWriter outputStream; // the assigned output stream
|
||||||
private BinaryWriter activeStream; // the active stream
|
private BinaryWriter activeStream; // the active stream
|
||||||
private Stack<BinaryWriter> writeStack = new Stack<BinaryWriter>();
|
private Stack<BinaryWriter> writeStack = new Stack<BinaryWriter>();
|
||||||
|
private Stack<CapturedCode> captureStack = new Stack<CapturedCode>();
|
||||||
private bool isCapturing = false;
|
private bool isCapturing = false;
|
||||||
private bool debug = true;
|
private bool debug = true;
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ namespace Axiom.Interpreter
|
|||||||
isCapturing = true;
|
isCapturing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CapturedCode EndCapture()
|
public void EndCapture()
|
||||||
{
|
{
|
||||||
if (!isCapturing)throw new InvalidOperationException("EndCapture called without a matching BeginCapture.");
|
if (!isCapturing)throw new InvalidOperationException("EndCapture called without a matching BeginCapture.");
|
||||||
activeStream.Flush();
|
activeStream.Flush();
|
||||||
@@ -47,11 +48,16 @@ namespace Axiom.Interpreter
|
|||||||
activeStream.Dispose();
|
activeStream.Dispose();
|
||||||
activeStream = writeStack.Pop();
|
activeStream = writeStack.Pop();
|
||||||
isCapturing = writeStack.Count > 0;
|
isCapturing = writeStack.Count > 0;
|
||||||
return new CapturedCode(capturedBytes);
|
captureStack.Push(new CapturedCode(capturedBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Emit(CapturedCode code)
|
/// <summary>
|
||||||
|
/// EmitCapture - Later, for CONTINUE semantics, we can Peek() at the top of the captureStack to get the increment code without popping it.
|
||||||
|
/// </summary>
|
||||||
|
public void EmitCapture()
|
||||||
{
|
{
|
||||||
|
if(0==captureStack.Count)throw new InvalidOperationException("The CaptureList is empty.");
|
||||||
|
CapturedCode code = captureStack.Pop();
|
||||||
activeStream.Write(code.Bytes,0,code.Length);
|
activeStream.Write(code.Bytes,0,code.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,11 +246,11 @@ namespace Axiom.Interpreter
|
|||||||
DoForCondition(); // e.g., I < 10 // emit the for condition
|
DoForCondition(); // e.g., I < 10 // emit the for condition
|
||||||
codePointerFalseBranch = CodePointer(); // get the location in the stream for the defaddr2 that follows
|
codePointerFalseBranch = CodePointer(); // get the location in the stream for the defaddr2 that follows
|
||||||
Emit(Parser.ParserSymbols.defaddr2, 0L); // emit defaddr2 (jump if false) with dummy address of 0L
|
Emit(Parser.ParserSymbols.defaddr2, 0L); // emit defaddr2 (jump if false) with dummy address of 0L
|
||||||
BeginCapture(); // start a new code emit frame
|
BeginCapture(); // start a new code emit frame. This is how we implement deferred emit
|
||||||
DoForIncrement(); // emit the increment code e.g., I = I + 1
|
DoForIncrement(); // emit the increment code e.g., I = I + 1
|
||||||
CapturedCode code = EndCapture(); // end the capture and retrieve the emitted code
|
EndCapture(); // end the capture
|
||||||
DoForBlock(); // emit the BODY
|
DoForBlock(); // emit the BODY
|
||||||
Emit(code); // emit the increment
|
EmitCapture(); // emit the increment code we capture between BeginCapture and EndCapture
|
||||||
if (IsInError) { loopStack.Pop(); return; } // check error condition
|
if (IsInError) { loopStack.Pop(); return; } // check error condition
|
||||||
Emit(Parser.ParserSymbols.goto2, codePointerL1); // jump back to condition after the body
|
Emit(Parser.ParserSymbols.goto2, codePointerL1); // jump back to condition after the body
|
||||||
codePointerL2 = CodePointer(); // get the location in the stream for the L2 exit location
|
codePointerL2 = CodePointer(); // get the location in the stream for the L2 exit location
|
||||||
|
|||||||
Reference in New Issue
Block a user