using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using num = System.Single;
using AddressingMode = System.Int32;
namespace Twiggery
{
/// <summary>
/// AST node abstract base class
/// </summary>
public abstract class Twig
{
#region Variables
/// <summary>
/// Lex elements list, syntax head
/// </summary>
protected List<LexiconSplitter.Element> contextHead = null;
/// <summary>
/// Lex elements list, syntax body
/// </summary>
protected List<LexiconSplitter.Element> contextBody = null;
/// <summary>
/// Lex elements list, syntax tail
/// </summary>
protected List<LexiconSplitter.Element> contextTail = null;
/// <summary>
/// Current layer sub element of the syntax tree, syntax head
/// </summary>
protected Twig subTwigHead = null;
/// <summary>
/// Current layer sub element of the syntax tree, syntax body list
/// </summary>
protected List<Twig> subTwigBody = null;
/// <summary>
/// Current layer sub element of the syntax tree, syntax tail
/// </summary>
protected Twig subTwigTail = null;
#endregion
#region Helper
/// <summary>
/// Get body string of a Twig
/// </summary>
/// <param name="t">Head Twig</param>
/// <returns>Result string</returns>
public static string GetHeadText(Twig t)
{
string s = "";
foreach (LexiconSplitter.Element e in t.contextHead)
s += e.Text;
return s;
}
/// <summary>
/// Get body string of a Twig
/// </summary>
/// <param name="t">Body Twig</param>
/// <returns>Result string</returns>
public static string GetBodyText(Twig t)
{
string s = "";
foreach (LexiconSplitter.Element e in t.contextBody)
s += e.Text;
return s;
}
/// <summary>
/// Get tail string of a Twig
/// </summary>
/// <param name="t">Tail Twig</param>
/// <returns>Result string</returns>
public static string GetTailText(Twig t)
{
string s = "";
foreach (LexiconSplitter.Element e in t.contextTail)
s += e.Text;
return s;
}
#endregion
#region Parse
/// <summary>
/// Parse head
/// </summary>
protected virtual void parseHead()
{
int f = SyntaxChecker.GetInstance().FirstIndexOf(contextHead, "(");
int l = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextHead, f + 1, "(", ")");
contextHead.RemoveRange(0, 2);
contextHead.RemoveAt(contextHead.Count - 1);
Twig t = new TwigFormula();
t.Parse(ref contextHead);
subTwigHead = t;
}
/// <summary>
/// The last processed one
/// </summary>
private string lastElem = string.Empty;
/// <summary>
/// Parse body
/// </summary>
protected virtual void parseBody()
{
subTwigBody = new List<Twig>();
while (contextBody.Count > 0)
{
LexiconSplitter.Element elem = contextBody[0];
Twig t;
if (elem.Text == "if")
{
t = new TwigIf();
}
else if (elem.Text == "elseif")
{
t = new TwigElseif();
}
else if (elem.Text == "else")
{
t = new TwigElse();
}
else if (elem.Text == "for")
{
t = new TwigFor();
}
else if (elem.Text == "while")
{
t = new TwigWhile();
}
else if (elem.Text == "do")
{
t = new TwigDoWhile();
}
else if (elem.Text == "break")
{
t = new TwigBreak();
}
else if (elem.Text == "continue")
{
t = new TwigContinue();
}
else if (elem.Text == "return")
{
t = new TwigReturn();
}
else
{
t = new TwigFormula();
}
t.Parse(ref contextBody);
subTwigBody.Add(t);
lastElem = elem.Text;
}
}
/// <summary>
/// Parse syntax tail
/// </summary>
protected virtual void parseTail()
{
int f = SyntaxChecker.GetInstance().FirstIndexOf(contextTail, "(");
int l = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextTail, f + 1, "(", ")");
contextTail.RemoveRange(0, 2);
contextTail.RemoveAt(contextTail.Count - 1);
Twig t = new TwigFormula();
t.Parse(ref contextTail);
subTwigTail = t;
}
/// <summary>
/// Parse lex elements to AST
/// </summary>
/// <param name="context">Lex elements list</param>
/// <param name="headString">Syntax head string</param>
protected virtual void parseKeyword(ref List<LexiconSplitter.Element> context, string headString)
{
// Skip comments
List<int> commentLines = new List<int>();
for (int i = 0; i < context.Count; i++)
{
if (LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.COMMENT == context[i].ElementType)
commentLines.Add(i);
}
for (int i = commentLines.Count - 1; i >= 0; i--)
{
context.RemoveAt(commentLines[i]);
}
contextHead = new List<LexiconSplitter.Element>();
contextBody = new List<LexiconSplitter.Element>();
contextTail = new List<LexiconSplitter.Element>();
contextHead.Add(context[0]);
context.RemoveAt(0);
// Split
int t =0;
if (headString == "if" || headString == "elseif" || headString == "while")
{
t = SyntaxChecker.GetInstance().FirstIndexOf(context, "(");
t = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, t + 1, "(", ")");
}
else
{
t = SyntaxChecker.GetInstance().FirstIndexOf(context, ")");
}
int f = 0;
int l = 0;
bool withBrackets = true;
if (headString == "else" && context[0].Text != "{")
{
f = 0;
l = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
withBrackets = false;
}
else if (context[t + 1].Text == "{" || (headString == "else" && context[0].Text == "{"))
{
f = SyntaxChecker.GetInstance().FirstIndexOf(context, "{");
l = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, f + 1, "{", "}");
}
else if (headString == "do")
{
f = SyntaxChecker.GetInstance().FirstIndexOf(context, "{");
l = SyntaxChecker.GetInstance().GetCloseBracketIndex(context, f + 1, "{", "}");
}
else
{
f = t + 1;
l = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
withBrackets = false;
}
for (int i = 0; i < f; i++)
{
contextHead.Add(context[0]);
context.RemoveAt(0);
}
List<LexiconSplitter.Element> tail = new List<LexiconSplitter.Element>();
int end = context.Count + f - 1;
for (int i = l; i < end; i++)
{
tail.Insert(0, context[context.Count - 1]);
context.RemoveAt(context.Count - 1);
}
if (withBrackets)
{
context.RemoveAt(0);
context.RemoveAt(context.Count - 1);
}
foreach (LexiconSplitter.Element elem in context)
{
contextBody.Add(elem);
}
if (headString == "do")
{
int _df = SyntaxChecker.GetInstance().FirstIndexOf(tail, "(");
int _dl = SyntaxChecker.GetInstance().GetCloseBracketIndex(tail, _df + 1, "(", ")");
_df--;
_dl++;
contextTail.AddRange(tail.GetRange(_df, _dl - _df));
tail.RemoveRange(_df, _dl - _df);
}
context = tail;
}
#endregion
/// <summary>
/// Parse lex elements to AST
/// </summary>
/// <param name="context">Lex elements list</param>
public virtual void Parse(ref List<LexiconSplitter.Element> context)
{
}
/// <summary>
/// Process if-elseif-else
/// </summary>
/// <param name="twig">The twig which sub twig is to be processed</param>
public void ProcessIfElse(Twig twig)
{
int pie = 0; // Process with If-Else :)
for (int i = 0; i < twig.subTwigBody.Count; i++)
{
Twig t = twig.subTwigBody[i];
if (0 == pie && t is TwigIf)
{
// Begining of an 'if' twig
pie++;
}
else if (1 == pie && t is TwigElseif)
{
// 'if' - 'elseif'
pie++;
}
else if (2 == pie && !(t is TwigElseif) && !(t is TwigElse))
{
// Add an 'else'
pie = 0;
Twig te = new TwigElse();
twig.subTwigBody.Insert(twig.subTwigBody.IndexOf(t), te);
i = twig.subTwigBody.IndexOf(te);
}
else if (1 == pie && (t is TwigElse))
{
// End of an 'if' twig
pie = 0;
}
else if (2 == pie && (t is TwigElse))
{
// End of an 'if' twig
pie = 0;
}
}
if (2 == pie)
{
Twig te = new TwigElse();
twig.subTwigBody.Add(te);
}
}
/// <summary>
/// Compile from an AST to instructions and push them into a TASM instruction stack
/// </summary>
/// <param name="vm">TASM instruction stack</param>
public virtual void PushAsm(ref TVM vm)
{
if (null != subTwigBody)
{
ProcessIfElse(this);
foreach (Twig t in subTwigBody)
{
t.PushAsm(ref vm);
}
}
}
}
/// <summary>
/// "function" Twig
/// </summary>
public class TwigFunction : Twig
{
private string functionName = null;
private List<string> functionArguments = null;
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "function");
parseBody();
functionName = contextHead[1].Text;
// Arguments
functionArguments = new List<string>();
if (contextHead[3].Text != ")")
{
for (int i = 3; i < contextHead.Count - 1; i += 2)
{
string id = contextHead[i].Text;
if (ScriptCommon.IsNumber(id))
{
throw new ScriptException("Invalid function argument identifier " + id);
}
functionArguments.Add(id);
SymbolTable.GetInstance().GetVariableIndex(id);
}
}
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockBeginFunction(ref vm);
TVM.Asm hal = new TVM.HAL();
vm.AsmPush(hal);
base.PushAsm(ref vm);
TVM.Asm hlt = new TVM.HLT();
vm.AsmPush(hlt);
BrokenTwig.GetInstance().BlockEndFunction(ref vm);
int varCount = SymbolTable.GetInstance().GetVariableCount();
vm[0].Operand[0] = varCount;
}
}
/// <summary>
/// "if" Twig
/// </summary>
public class TwigIf : Twig
{
/// <summary>Without 'elseif' or 'else'</summary>
private bool withoutElseifOrElse = true;
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "if");
if (context.Count > 0)
{
withoutElseifOrElse = (context[0].Text != "elseif" && context[0].Text != "else");
}
parseHead();
parseBody();
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockBeginIfElseFalse(ref vm);
if (!withoutElseifOrElse)
{
BrokenTwig.GetInstance().BlockBeginIfElseTrue(ref vm);
}
// Condition
{
subTwigHead.PushAsm(ref vm);
AddressingMode am1 = TVM.AM_IMD;
AddressingMode am2 = TVM.AM_STK;
AddressingMode am = TVM.CombineAddressingMode(am1, am2);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm ce = new TVM.CE();
ce.Operand[0] = 0;
ce.Operand[1] = 0;
vm.AsmPush(ce);
BrokenTwig.GetInstance().JumpIfElseFalse(vm.AsmCount);
TVM.Asm jt = new TVM.JF();
vm.AsmPush(jt);
}
// Body
base.PushAsm(ref vm);
// End
if (!withoutElseifOrElse)
{
BrokenTwig.GetInstance().JumpIfElseTrue(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
else
{
BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
}
}
}
/// <summary>
/// "elseif" Twig
/// </summary>
public class TwigElseif : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "elseif");
parseHead();
parseBody();
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
BrokenTwig.GetInstance().BlockBeginIfElseFalse(ref vm);
// Condition
{
subTwigHead.PushAsm(ref vm);
AddressingMode am1 = TVM.AM_IMD;
AddressingMode am2 = TVM.AM_STK;
AddressingMode am = TVM.CombineAddressingMode(am1, am2);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm ce = new TVM.CE();
ce.Operand[0] = 0;
ce.Operand[1] = 0;
vm.AsmPush(ce);
BrokenTwig.GetInstance().JumpIfElseFalse(vm.AsmCount);
TVM.Asm jt = new TVM.JF();
vm.AsmPush(jt);
}
// Body
base.PushAsm(ref vm);
// End
BrokenTwig.GetInstance().JumpIfElseTrue(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
}
/// <summary>
/// "else" Twig
/// </summary>
public class TwigElse : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "else");
parseBody();
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockEndIfElseFalse(ref vm, vm.AsmCount);
base.PushAsm(ref vm);
BrokenTwig.GetInstance().BlockEndIfElseTrue(ref vm, vm.AsmCount);
}
}
/// <summary>
/// "for" Twig
/// </summary>
public class TwigFor : Twig
{
/// <summary>Loop variable</summary>
private string id = "";
/// <summary>Start value</summary>
private string from = "";
/// <summary>End value</summary>
private string to = "";
/// <summary>Step value</summary>
private string step = "";
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "for");
parseBody();
id = contextHead[2].Text;
from = contextHead[4].Text;
to = contextHead[6].Text;
if (8 == contextHead.Count) // Default step
{
step = "1";
}
else
{
step = contextHead[8].Text;
}
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
num ii = SymbolTable.GetInstance().GetVariableIndex(id);
num si = num.Parse(step);
// Initialized value
{
AddressingMode am1 = ScriptCommon.IsNumber(from) ? TVM.AM_IMD : TVM.AM_RAM;
AddressingMode am = TVM.CombineAddressingMode(am1, TVM.AM_RAM);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
num start = (am1 == TVM.AM_IMD) ? num.Parse(from) : SymbolTable.GetInstance().GetVariableIndex(from);
TVM.Asm assign = new TVM.MOV();
assign.Operand[0] = start;
assign.Operand[1] = ii;
vm.AsmPush(assign);
}
// Condition
int labelCondition = vm.AsmCount;
{
AddressingMode am2 = ScriptCommon.IsNumber(to) ? TVM.AM_IMD : TVM.AM_RAM;
AddressingMode am = TVM.CombineAddressingMode(TVM.AM_RAM, am2);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
num end = (am2 == TVM.AM_IMD) ? num.Parse(to) : SymbolTable.GetInstance().GetVariableIndex(to);
TVM.Asm compare = null;
if (si >= 0)
{
compare = new TVM.CLE();
}
else
{
compare = new TVM.CGE();
}
compare.Operand[0] = ii;
compare.Operand[1] = end;
vm.AsmPush(compare);
BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
TVM.Asm jnt = new TVM.JT();
jnt.Operand[0] = 0;
vm.AsmPush(jnt);
}
// Body
base.PushAsm(ref vm);
// Step
{
AddressingMode am = TVM.CombineAddressingMode(TVM.AM_RAM, TVM.AM_IMD);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm add = new TVM.ADD();
add.Operand[0] = ii;
add.Operand[1] = si;
vm.AsmPush(add);
am = TVM.CombineAddressingMode(TVM.AM_STK, TVM.AM_RAM);
lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm mov = new TVM.MOV();
mov.Operand[0] = 0;
mov.Operand[1] = ii;
vm.AsmPush(mov);
BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
// End
int labelOutside = vm.AsmCount;
BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
}
}
/// <summary>
/// "while" Twig
/// </summary>
public class TwigWhile : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "while");
parseHead();
parseBody();
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
int labelCondition = vm.AsmCount;
// Condition
{
subTwigHead.PushAsm(ref vm);
AddressingMode am1 = TVM.AM_IMD;
AddressingMode am2 = TVM.AM_STK;
AddressingMode am = TVM.CombineAddressingMode(am1, am2);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm ce = new TVM.CE();
ce.Operand[0] = 0;
ce.Operand[1] = 0;
vm.AsmPush(ce);
BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
TVM.Asm jt = new TVM.JF();
vm.AsmPush(jt);
}
// Body
base.PushAsm(ref vm);
// End
{
TVM.Asm jmp = new TVM.JMP();
jmp.Operand[0] = labelCondition;
vm.AsmPush(jmp);
int labelOutside = vm.AsmCount;
BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
}
}
}
/// <summary>
/// "do" Twig
/// </summary>
public class TwigDoWhile : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
base.parseKeyword(ref context, "do");
parseBody();
parseTail();
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().BlockBeginLoop(ref vm);
int labelCondition = vm.AsmCount;
// Loop body
base.PushAsm(ref vm);
// Loop condition
{
subTwigTail.PushAsm(ref vm);
AddressingMode am1 = TVM.AM_IMD;
AddressingMode am2 = TVM.AM_STK;
AddressingMode am = TVM.CombineAddressingMode(am1, am2);
TVM.Asm lam = new TVM.LAM();
lam.Operand[0] = am;
vm.AsmPush(lam);
TVM.Asm cne = new TVM.CNE();
cne.Operand[0] = 0;
cne.Operand[1] = 0;
vm.AsmPush(cne);
BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
TVM.Asm jt = new TVM.JF();
vm.AsmPush(jt);
}
// Loop end
int labelOutside = vm.AsmCount;
BrokenTwig.GetInstance().BlockEndLoop(ref vm, labelCondition, labelOutside);
}
}
/// <summary>
/// formula Twig
/// </summary>
public class TwigFormula : Twig
{
// Process negative symbol
private void processNegative(ref List<LexiconSplitter.Element> contextBody)
{
if (contextBody.Count > 1 && "-" == contextBody[contextBody.Count - 2].Text)
{
if (contextBody.Count < 3 ||
(contextBody[contextBody.Count - 3].ElementType != LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.CONST &&
contextBody[contextBody.Count - 3].ElementType != LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.IDENTIFIER &&
contextBody[contextBody.Count - 3].Text != ")"))
{
contextBody.Insert(contextBody.Count - 2, new LexiconSplitter.Element("(", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR));
contextBody.Insert(contextBody.Count - 2, new LexiconSplitter.Element("0", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.CONST));
contextBody.Add(new LexiconSplitter.Element(")", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR));
}
}
}
public override void Parse(ref List<LexiconSplitter.Element> context)
{
contextBody = new List<LexiconSplitter.Element>();
int f = SyntaxChecker.GetInstance().FirstIndexOf(context, ";");
if (-1 != f)
{
for (int i = 0; i < f; i++)
{
contextBody.Add(context[0]);
context.RemoveAt(0);
processNegative(ref contextBody);
}
context.RemoveAt(0);
}
else
{
foreach (LexiconSplitter.Element e in context)
{
contextBody.Add(e);
processNegative(ref contextBody);
}
context.Clear();
}
}
public override void PushAsm(ref TVM vm)
{
List<TVM.Asm> asmList = null;
if (contextBody.Count == 1) // Single boolean
{
asmList = FormulaProcessor.GetInstance().BooleanVariable(ref contextBody);
}
else
{
if (contextBody.Count > 3 &&
contextBody[1].Text == "=" &&
contextBody[2].ElementType == LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.IDENTIFIER &&
contextBody[3].Text == "(")
{
int ilb = SyntaxChecker.GetInstance().GetCloseBracketIndex(contextBody, 4, "(", ")");
if (contextBody.Count - 1 == ilb) // Function call with '=' ahead
{
LexiconSplitter.Element elem = contextBody[0];
contextBody.RemoveRange(0, 2);
contextBody.Insert(2, elem);
if (4 != contextBody.Count)
{
LexiconSplitter.Element comma = new LexiconSplitter.Element(",", LexiconSplitter.Element.SCRIPT_ANALYSER_ELEMENT_TYPE.SEPERATOR);
contextBody.Insert(3, comma);
}
asmList = FormulaProcessor.GetInstance().FunctionCallFormula(ref contextBody);
}
else // Assign formula
{
asmList = FormulaProcessor.GetInstance().AssignFormula(ref contextBody);
}
}
else if (contextBody[1].Text == "=") // Assign formula
{
asmList = FormulaProcessor.GetInstance().AssignFormula(ref contextBody);
}
else if (contextBody[1].Text == "(" && // Function call without '=' ahead
SyntaxChecker.GetInstance().GetCloseBracketIndex(contextBody, 2, "(", ")") == contextBody.Count - 1)
{
asmList = FormulaProcessor.GetInstance().FunctionCallFormula(ref contextBody);
}
else // Boolean judgement
{
asmList = FormulaProcessor.GetInstance().BooleanFormula(ref contextBody);
}
}
foreach (TVM.Asm asm in asmList)
{
vm.AsmPush(asm);
}
}
}
/// <summary>
/// "break" Twig
/// </summary>
public class TwigBreak : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
context.RemoveRange(0, 2);
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().JumpBreak(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
}
/// <summary>
/// "continue" Twig
/// </summary>
public class TwigContinue : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
context.RemoveRange(0, 2);
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().JumpContinue(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
}
/// <summary>
/// "return" Twig
/// </summary>
public class TwigReturn : Twig
{
public override void Parse(ref List<LexiconSplitter.Element> context)
{
context.RemoveRange(0, 2);
}
public override void PushAsm(ref TVM vm)
{
BrokenTwig.GetInstance().JumpReturn(vm.AsmCount);
TVM.Asm jmp = new TVM.JMP();
vm.AsmPush(jmp);
}
}
}