Esempio n. 1
0
        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);
        }