tlang-runtime-compiler/TLang.BytecodeCompiler/Class1.cs

649 lines
31 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using TLang.Parser;
using TLang.Common;
namespace TLang.BytecodeCompiler
{
public class ByteCodeGenerator
{
private int I = 0;
public int NextNumber()
{
return I++;
}
public ByteCodeGenerator()
{
Chunks.Add(RootChunk);
}
public List<ClassNode> Classes {get;set;}=new List<ClassNode>();
public List<FunctionDeclaritionNode> Functions {get;set;}=new List<FunctionDeclaritionNode>();
public BytecodeChunk RootChunk = new BytecodeChunk();
public List<BytecodeChunk> Chunks {get;set;}=new List<BytecodeChunk>();
public static void GenerateToStream(Node node,Stream strm,TLangVersion vmVersion,TLangVersion version,params TLangDependency[] dependencies)
{
ByteCodeGenerator gen=new ByteCodeGenerator();
gen._generateFile(node,strm,vmVersion,version,dependencies);
}
private void _generateFile(Node node,Stream strm,TLangVersion vmVersion,TLangVersion version,TLangDependency[] dependencies)
{
byte[] data = new byte[]{(byte)'T',(byte)'V',(byte)'M',vmVersion.Major,vmVersion.Minor,vmVersion.Patch,vmVersion.Build,version.Major,version.Minor,version.Patch,version.Build};
strm.Write(data,0,data.Length);
WriteBigEndianInt(strm,dependencies.Length);
foreach(var item in dependencies)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(item.Name);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
byte[] dependV = new byte[]{item.Version.Major,item.Version.Minor,item.Version.Patch,item.Version.Build};
strm.Write(dependV,0,dependV.Length);
}
GenerateCode(node,RootChunk,0,0,-1,-1,true);
WriteBigEndianInt(strm,Functions.Count);
foreach(var item in Functions)
{
int closure = Chunks.Count;
BytecodeChunk _chunk = new BytecodeChunk();
_chunk.Arguments = item.ClosureNode.Arguments;
Chunks.Add(_chunk);
GenerateCode(item.ClosureNode.Node,_chunk,0,0,-1,-1,false);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(item.FunctionName);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
WriteBigEndianInt(strm,closure);
}
WriteBigEndianInt(strm,Classes.Count);
foreach(var item in Classes)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(item.Name);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
bytes = System.Text.Encoding.UTF8.GetBytes(item.InheritsFrom);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
WriteBigEndianInt(strm,item.Entries.Count);
foreach(var classEntry in item.Entries)
{
var cValue = classEntry.InitialValue as ClosureNode;
if(cValue != null)
{
byte c = 0b00000100;
if(classEntry.Abstract) { c |= 0b00001000;}
if(classEntry.Modifier == "prot") {c |= 0b00000001;}
if(classEntry.Modifier == "pub") {c |= 0b00000010;}
strm.WriteByte(c);
bytes = System.Text.Encoding.UTF8.GetBytes(classEntry.Name);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
int closure = Chunks.Count;
BytecodeChunk _chunk = new BytecodeChunk();
_chunk.Arguments = cValue.Arguments;
GenerateCode(cValue.Node,_chunk,0,0,-1,-1,false);
Chunks.Add(_chunk);
WriteBigEndianInt(strm,closure);
}
else
{
byte c = 0b00000100;
if(classEntry.Modifier == "prot") {c |= 0b00000001;}
if(classEntry.Modifier == "pub") {c |= 0b00000010;}
strm.WriteByte(c);
bytes = System.Text.Encoding.UTF8.GetBytes(classEntry.Name);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
int closure = Chunks.Count;
BytecodeChunk _chunk = new BytecodeChunk();
GenerateCode(new ReturnNode(classEntry.InitialValue),_chunk,0,0,-1,-1,false);
Chunks.Add(_chunk);
WriteBigEndianInt(strm,closure);
}
}
}
WriteBigEndianInt(strm,Chunks.Count);
foreach(var item in Chunks)
{
item.SetLabelable();
WriteBigEndianInt(strm,item.Arguments.Count);
foreach(var arg in item.Arguments)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(arg);
WriteBigEndianInt(strm,bytes.Length);
strm.Write(bytes,0,bytes.Length);
}
WriteBigEndianInt(strm,item.CurrentByteLength);
foreach(var instruction in item.Instructions)
{
instruction.WriteData(strm);
}
}
}
private void WriteBigEndianInt(Stream strm, int count)
{
byte[] data = BitConverter.GetBytes(count);
if(BitConverter.IsLittleEndian) Array.Reverse(data);
strm.Write(data,0,data.Length);
}
public void GenerateCode(Node node,BytecodeChunk chunk,int scopeIndex,int scopeBreakIndex,int _labelBeginningLoop,int _labelEndLoop,bool isRoot=false)
{
var funcDec = node as FunctionDeclaritionNode;
var chrNode = node as CharNode;
var strNode = node as StringNode;
var dblNode = node as ConstNumberNode;
var clsDec = node as ClassNode;
var addNode = node as AddNode;
var subNode = node as SubtractNode;
var timesNode = node as MultiplyNode;
var divNode = node as DivideNode;
var modNode = node as ModuloNode;
var powNode = node as PowNode;
var lshiftNode = node as LeftShiftNode;
var rshiftNode = node as RightShiftNode;
var bOrNode = node as BOrNode;
var bAndNode = node as BAndNode;
var xOrNode = node as XOrNode;
var negNode = node as NegativeNode;
var bNotNode = node as BitwiseNotNode;
var nEqNode = node as NotEqualsNode;
var eqNode = node as EqualsNode;
var lOrNode = node as LOrNode;
var lAndNode = node as LAndNode;
var ltNode = node as LessThanNode;
var lteNode = node as LessThanEqualsNode;
var gtNode = node as GreaterThanNode;
var gteNode = node as GreaterThanEqualsNode;
var notNode = node as NotNode;
var scNode = node as ScopeNode;
var retNode = node as ReturnNode;
var closureNode = node as ClosureNode;
var whileNode = node as WhileLoop;
var eachNode = node as EachLoopNode;
var forNode = node as ForLoopNode;
var ifNode = node as IfNode;
var functionCallNode = node as FunctionCallNode;
var methodCallNode = node as MethodCallNode;
var getVariableNode = node as GetVariableNode;
var getMemberNode = node as GetMemberNode;
var getArrayValue = node as GetArrayNode;
var setVariableNode = node as SetVariableNode;
if(scNode != null)
{
if(scNode.IsSwitchScope)
{
int caseNumber = NextNumber();
int labelNumEnd = NextNumber();
int caseNo2=0;
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
bool hasDefault =false;
bool beforeCase=true;
foreach(var item in scNode.Nodes)
{
var c = item as CaseNode;
var d = item as DefaultNode;
if(c != null)
{
beforeCase = false;
EqualsNode equals=new EqualsNode(scNode.SwitchCondition,c.Variable);
GenerateCode(equals,chunk,scopeIndex+1,0,_labelBeginningLoop,labelNumEnd,false);
JumpConditional unconditional = new JumpConditional($"_case{caseNumber}_{caseNo2}");
chunk.Add(unconditional);
caseNo2++;
}
if(d != null)
{
hasDefault =false;
beforeCase = false;
JumpUnconditional unconditional = new JumpUnconditional($"_default{caseNumber}");
chunk.Add(unconditional);
}
if(beforeCase)
{
GenerateCode(item,chunk,scopeIndex+1,0,_labelBeginningLoop,_labelEndLoop,isRoot);
}
}
if(!hasDefault)
{
JumpUnconditional unconditional = new JumpUnconditional($"_label{labelNumEnd}");
chunk.Add(unconditional);
}
beforeCase=true;
caseNo2=0;
foreach(var item in scNode.Nodes)
{
var c = item as CaseNode;
var d = item as DefaultNode;
if(c != null)
{
beforeCase = false;
LabelInstruction instruction = new LabelInstruction($"_case{caseNumber}_{caseNo2}");
chunk.Add(instruction);
caseNo2++;
}
if(d != null)
{
beforeCase = false;
LabelInstruction instruction = new LabelInstruction($"_default{caseNumber}");
chunk.Add(instruction);
}
if(!beforeCase && c == null && d == null)
{
GenerateCode(item,chunk,scopeIndex+1,scopeBreakIndex,_labelBeginningLoop,labelNumEnd,scNode.RootScope);
}
}
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
chunk.Add(endLabel);
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
else
{
if(!scNode.RootScope)
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
foreach(var item in scNode.Nodes)
{
GenerateCode(item,chunk,scopeIndex+1,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,scNode.RootScope);
}
if(!scNode.RootScope)
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
}
if(ifNode != null)
{
int labelNumNo = NextNumber();
int labelNumEnd = NextNumber();
GenerateCode(new NotNode(ifNode.Condition),chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
JumpConditional jc=new JumpConditional($"_label{labelNumNo}");
chunk.Add(jc);
GenerateCode(ifNode.Yes,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
JumpUnconditional ju = new JumpUnconditional($"_label{labelNumEnd}");
chunk.Add(ju);
LabelInstruction labelNo = new LabelInstruction($"_label{labelNumNo}");
chunk.Add(labelNo);
GenerateCode(ifNode.No,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
LabelInstruction labelEnd = new LabelInstruction($"_label{labelNumEnd}");
chunk.Add(labelEnd);
}
if(bNotNode != null)
{
GenerateCode(bNotNode.Node,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.BNOT));
}
if(negNode != null)
{
GenerateCode(negNode.Node,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.NEG));
}
if(notNode != null)
{
GenerateCode(notNode.Node,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LNOT));
}
if(eachNode != null)
{
int ittrVarNum = NextNumber();
int labelNum = NextNumber();
int labelNumEnd = NextNumber();
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
GetVariableNode variableNode=new GetVariableNode($"__compGen{ittrVarNum}");
var member= new GetMemberNode(eachNode.Itterator,"ittr");
SetVariableNode variableNode1=new SetVariableNode(variableNode,member);
GenerateCode(variableNode1,chunk,scopeIndex+1,0,_labelBeginningLoop,_labelEndLoop,false);
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
chunk.Add(labelNode);
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
chunk.Add(conditional);
SetVariableNode variableNode2=new SetVariableNode(eachNode.Name,new NotNode(new MethodCallNode(variableNode,"movenext")));
GenerateCode(variableNode2,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
GenerateCode(eachNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}");
chunk.Add(juC);
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
chunk.Add(endLabel);
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
if(forNode != null)
{
int labelNum = NextNumber();
int labelNumEnd = NextNumber();
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
GenerateCode(forNode.Init,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
chunk.Add(labelNode);
GenerateCode(new NotNode(forNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
chunk.Add(conditional);
GenerateCode(forNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
GenerateCode(forNode.Increment,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}");
chunk.Add(juC);
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
chunk.Add(endLabel);
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
if(whileNode != null)
{
int labelNum = NextNumber();
int labelNumEnd = NextNumber();
chunk.Add(new SimpleInstruction(Instruction.SCOPE_BEGIN));
LabelInstruction labelNode=new LabelInstruction($"_label{labelNum}");
chunk.Add(labelNode);
if(whileNode.IsDo)
{
GenerateCode(whileNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
GenerateCode(new NotNode(whileNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpConditional conditional = new JumpConditional($"_label{labelNum}");
chunk.Add(conditional);
}
else
{
GenerateCode(new NotNode(whileNode.Condition),chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpConditional conditional = new JumpConditional($"_label{labelNumEnd}");
chunk.Add(conditional);
GenerateCode(whileNode.Body,chunk,scopeIndex+1,0,labelNum,labelNumEnd,false);
JumpUnconditional juC=new JumpUnconditional($"_label{labelNum}");
chunk.Add(juC);
}
LabelInstruction endLabel = new LabelInstruction($"_label{labelNumEnd}");
chunk.Add(endLabel);
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
if(node is ContinueNode && _labelBeginningLoop >= 0)
{
for(int i = scopeBreakIndex;i>0;i--)
{
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
JumpUnconditional conditional=new JumpUnconditional($"_label{_labelBeginningLoop}");
chunk.Add(conditional);
}
if(node is BreakNode && _labelEndLoop >= 0)
{
for(int i = scopeBreakIndex;i>0;i--)
{
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
JumpUnconditional conditional=new JumpUnconditional($"_label{_labelEndLoop}");
chunk.Add(conditional);
}
if(closureNode != null)
{
BytecodeChunk _chunk = new BytecodeChunk();
_chunk.Arguments = closureNode.Arguments;
GenerateCode(closureNode.Node,_chunk,0,0,-1,-1,false);
int i = Chunks.Count;
Chunks.Add(_chunk);
chunk.Add(new PushClosureNode(i));
}
if(node is NullNode)
{
chunk.Add(new SimpleInstruction(Instruction.PUSH_NULL));
}
if(node is UndefinedNode)
{
chunk.Add(new SimpleInstruction(Instruction.PUSH_UNDEFINED));
}
if(node is TrueNode)
{
chunk.Add(new SimpleInstruction(Instruction.PUSH_TRUE));
}
if(node is FalseNode)
{
chunk.Add(new SimpleInstruction(Instruction.PUSH_FALSE));
}
if(chrNode != null)
{
chunk.Add(new PushCharNode(chrNode.Text));
}
if(strNode != null)
{
chunk.Add(new PushStringInstruction(strNode.Text));
}
if(dblNode != null)
{
chunk.Add(new PushDoubleInstruction(dblNode.Value));
}
if(funcDec != null)
{
if(isRoot)
{
Functions.Add(funcDec);
}
else
{
SetVariableNode variableNode=new SetVariableNode(new GetVariableNode(funcDec.FunctionName),funcDec.ClosureNode) {LineInfo = funcDec.LineInfo};
GenerateCode(variableNode,chunk,scopeIndex,scopeBreakIndex,-1,-1,false);
}
}
if(clsDec != null)
{
Classes.Add(clsDec);
}
if(addNode != null)
{
GenerateCode(addNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(addNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.ADD));
}
if(subNode != null)
{
GenerateCode(subNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(subNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.SUB));
}
if(timesNode != null)
{
GenerateCode(timesNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(timesNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.TIMES));
}
if(divNode != null)
{
GenerateCode(divNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(divNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.DIVIDE));
}
if(modNode != null)
{
GenerateCode(modNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(modNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.MOD));
}
if(powNode != null)
{
GenerateCode(powNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(powNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.POW));
}
if(lshiftNode != null)
{
GenerateCode(lshiftNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(lshiftNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LSHIFT));
}
if(rshiftNode != null)
{
GenerateCode(rshiftNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(rshiftNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.RSHIFT));
}
if(bOrNode != null)
{
GenerateCode(bOrNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(bOrNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.BOR));
}
if(bAndNode != null)
{
GenerateCode(bAndNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(bAndNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.BAND));
}
if(xOrNode != null)
{
GenerateCode(xOrNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(xOrNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.XOR));
}
if(nEqNode != null)
{
GenerateCode(nEqNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(nEqNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.NEQ));
}
if(eqNode != null)
{
GenerateCode(eqNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(eqNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.EQ));
}
if(lOrNode != null)
{
GenerateCode(lOrNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(lOrNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LOR));
}
if(lAndNode != null)
{
GenerateCode(lAndNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(lAndNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LAND));
}
if(ltNode != null)
{
GenerateCode(ltNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(ltNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LT));
}
if(lteNode != null)
{
GenerateCode(lteNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(lteNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.LTE));
}
if(gtNode != null)
{
GenerateCode(gtNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(gtNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.GT));
}
if(gteNode != null)
{
GenerateCode(gteNode.Left,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(gteNode.Right,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.GTE));
}
if(retNode != null)
{
GenerateCode(retNode.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
for(int i = scopeIndex;i>0;i--)
{
chunk.Add(new SimpleInstruction(Instruction.SCOPE_END));
}
chunk.Add(new SimpleInstruction(Instruction.RET));
}
if(methodCallNode != null)
{
GenerateCode(methodCallNode.Symbol,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new PushStringInstruction(methodCallNode.Name));
foreach(var arg in methodCallNode.Arguments)
{
GenerateCode(arg,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
}
chunk.Add(new PushDoubleInstruction(methodCallNode.Arguments.Count));
chunk.Add(new SimpleInstruction(Instruction.CALL_METHOD));
}
if(functionCallNode != null)
{
chunk.Add(new PushStringInstruction(functionCallNode.Name));
foreach(var arg in functionCallNode.Arguments)
{
GenerateCode(arg,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
}
chunk.Add(new PushDoubleInstruction(functionCallNode.Arguments.Count));
chunk.Add(new SimpleInstruction(Instruction.CALL_FUNC));
}
if(getVariableNode != null)
{
chunk.Add(new PushStringInstruction(getVariableNode.Name));
chunk.Add(new SimpleInstruction(Instruction.PUSH_VARIABLE_VALUE));
}
if(getMemberNode != null)
{
GenerateCode(getMemberNode.Symbol,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new PushStringInstruction(getMemberNode.Name));
chunk.Add(new SimpleInstruction(Instruction.PUSH_FIELD_VALUE));
}
if(getArrayValue != null)
{
GenerateCode(getArrayValue.Symbol,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(getArrayValue.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.PUSH_ARRAY_VALUE));
}
if(setVariableNode != null)
{
var gVN = setVariableNode.SetTo as GetVariableNode;
var gMN = setVariableNode.SetTo as GetMemberNode;
var gAN = setVariableNode.SetTo as GetArrayNode;
if(gVN != null)
{
chunk.Add(new PushStringInstruction(gVN.Name));
GenerateCode(setVariableNode.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.POP_VARIABLE_VALUE));
}
if(gMN != null)
{
GenerateCode(gMN.Symbol,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new PushStringInstruction(gMN.Name));
GenerateCode(setVariableNode.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.POP_FIELD_VALUE));
}
if(gAN != null)
{
GenerateCode(gAN.Symbol,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(gAN.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
GenerateCode(setVariableNode.Expression,chunk,scopeIndex,scopeBreakIndex,_labelBeginningLoop,_labelEndLoop,isRoot);
chunk.Add(new SimpleInstruction(Instruction.POP_ARRAY_VALUE));
}
}
}
}
}