private void VisitElement(AssemblyElement element) { if (element is ParamLessInstruction) { var typeName = element.GetType().Name; _buildAcc += $"{typeName}\n"; } else if (element is Call callElement) { _buildAcc += $"call {callElement.Symbol.Name}\n"; } else if (element is PushVar pushVarElement) { _buildAcc += $"PushVar {pushVarElement.Symbol.Name}\n"; } else if (element is PushArrayVar pushArrVarElement) { _buildAcc += $"PushArrVar {pushArrVarElement.Symbol.Name}[{pushArrVarElement.Index}]\n"; } else if (element is SetInstance setInstanceElement) { _buildAcc += $"SetInstance {setInstanceElement.Symbol.Name}\n"; } else if (element is IfBlockStatementContext context) { var ifBlock = context.IfBlock; var elseIfBlocks = context.ElseIfBlocks; var elseInstructions = context.ElseBlock.Body; var ifStatementEndLabel = GetLabel(); var nextJumpLabel = ifStatementEndLabel; //TODO make sure that this code works good, not tested :( foreach (var item in ifBlock.Condition) { VisitElement(item); } if (elseIfBlocks.Count > 0 || elseInstructions.Count > 0) { nextJumpLabel = GetLabel(); } VisitElement(new JumpIfToLabel(nextJumpLabel)); foreach (var item in ifBlock.Body) { VisitElement(item); } VisitElement(new JumpIfToLabel(ifStatementEndLabel)); if (elseIfBlocks.Count > 0) { foreach (var block in elseIfBlocks) { VisitElement(new AssemblyLabel(nextJumpLabel)); nextJumpLabel = GetLabel(); foreach (var item in block.Condition) { VisitElement(item); } foreach (var item in block.Body) { VisitElement(item); } VisitElement(new JumpIfToLabel(ifStatementEndLabel)); } } if (elseInstructions.Count > 0) { VisitElement(new AssemblyLabel(nextJumpLabel)); foreach (var item in elseInstructions) { VisitElement(item); } } else { ifStatementEndLabel = nextJumpLabel; } VisitElement(new AssemblyLabel(ifStatementEndLabel)); } else if (element is AssemblyLabel label) { _buildAcc += $"{label.Label}:\n"; } else if (element is JumpIfToLabel labelIfJump) { _buildAcc += $"JumpIfToLabel {labelIfJump.Label}\n"; } else if (element is JumpToLabel labelJump) { _buildAcc += $"JumpToLabel {labelJump.Label}\n"; } else if (element is PushInt pushint) { _buildAcc += $"PushInt {pushint.Value}\n"; } }
private List <DatToken> GetTokens(BlockSymbol blockSymbol) { List <DatToken> tokens = new List <DatToken>(); foreach (AssemblyElement it in blockSymbol.Instructions) { AssemblyElement instruction = it; if (instruction is AssemblyLabel) { continue; } int? intParam = null; byte?byteParam = null; switch (instruction) { case Call call: { intParam = ((BlockSymbol)call.Symbol).FirstTokenAddress; break; } case PushArrayVar pushArrVar: { intParam = pushArrVar.Symbol.Index; byteParam = (byte)pushArrVar.Index; break; } case JumpToLabel jumpToLabel: { intParam = blockSymbol.Label2Address[jumpToLabel.Label]; break; } case SymbolInstruction symbolInstruction: { intParam = symbolInstruction.Symbol.Index; break; } case ValueInstruction valueInstruction: { intParam = (int)valueInstruction.Value; break; } case AddressInstruction addressInstruction: { intParam = addressInstruction.Address; break; } case PushNullInstance _: intParam = 0; break; } string tokenName = instruction.GetType().Name; if (instruction is JumpToLabel) { tokenName = tokenName.Substring(0, tokenName.Length - "ToLabel".Length); } DatTokenType datTokenType = Enum.Parse <DatTokenType>(tokenName); tokens.Add(new DatToken { TokenType = datTokenType, IntParam = intParam, ByteParam = byteParam }); } return(tokens); }