Пример #1
0
        public override ParseResult Resolve(AssemblyRow row)
        {
            if (row.Operands == null || row.Operands.Count == 0)
            {
                return(new ParseResult(ParseResultCode.Error, 0, $" Az {row.Instruction.Mnemonic} utasításnak szüksége van operandusra. Az operandus egy vagy több két byte-os érték lehet vesszővel elválasztva!"));
            }

            bool rowContainsFutureSymbol = false;

            foreach (Operand operand in row.Operands)
            {
                if (SymbolTable.Any(s => s.Value.Name.Equals(operand.Value)))
                {
                    operand.State = OperandState.FutureSymbol;
                }

                if (operand.Info.DataType != OperandType.Decimal && operand.Info.DataType != OperandType.Word &&
                    operand.Info.DataType != OperandType.Byte && operand.Info.DataType != OperandType.Expression)
                {
                    if (operand.State != OperandState.Valid &&
                        operand.State != OperandState.FutureSymbol)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0,
                                               $"Az operandus adat típusa({operand.Info.DataType}) a {row.Instruction.Mnemonic} utasításban nem támogatott!"));
                    }
                }

                if (operand.Info.DataType == OperandType.Expression ||
                    operand.State == OperandState.FutureSymbol)
                {
                    var expressionParser = new ExpressionParser(operand.Value, SymbolTable);
                    var result           = expressionParser.Parse();
                    if (result.ResultCode == ParseResultCode.Error)
                    {
                        return(result);
                    }

                    InstructionBytes.Add((byte)(result.ResultValue & 0xFF));
                    InstructionBytes.Add((byte)(result.ResultValue >> 8));
                    if (result.ResultCode == ParseResultCode.ContainsFutureSymbol)
                    {
                        rowContainsFutureSymbol = true;
                    }
                }
                else
                {
                    ushort value    = operand.ToString().ResolveUshortConstant();
                    byte   highByte = (byte)(value >> 8);
                    byte   lowByte  = (byte)(value & 0xFF);
                    InstructionBytes.Add(lowByte);
                    InstructionBytes.Add(highByte);
                }
            }

            return(new ParseResult(rowContainsFutureSymbol? ParseResultCode.ContainsFutureSymbol : ParseResultCode.Ok));
        }
        public override ParseResult Resolve(AssemblyRow row)
        {
            if (row.Operands == null || row.Operands.Count == 0)
            {
                return(new ParseResult(ParseResultCode.Error, 0, $"A {row.Instruction.Mnemonic} utasításnak szüksége van operandusa!"));
            }

            foreach (Operand operand in row.Operands)
            {
                if (operand.Info.DataType != OperandType.Byte && operand.Info.DataType != OperandType.Character &&
                    operand.Info.DataType != OperandType.Literal && operand.Info.DataType != OperandType.Decimal &&
                    operand.Info.DataType != OperandType.Expression)
                {
                    Symbol symbol = SymbolTable.Where(s => s.Key.Equals(operand.Value)).Select(s => s.Value).FirstOrDefault();
                    if (symbol == null)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"A(z) {operand} operandus típusa({operand.Info.DataType}) a {row.Instruction.Mnemonic} utasításban nem támogatott!"));
                    }

                    if (symbol.State == SymbolState.Unresolved)
                    {
                        return(new ParseResult(ParseResultCode.ContainsFutureSymbol));
                    }
                    if (symbol.Value > 0xff)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"Az operandusként megadott szimbúlum '{symbol.Name}' értéke nem fér el egy byte-on!"));
                    }

                    InstructionBytes.Add((byte)symbol.Value);
                    continue;
                }

                switch (operand.Info.DataType)
                {
                case OperandType.Byte:
                    InstructionBytes.Add(operand.ToString().ResolveByteConstant());
                    break;

                case OperandType.Character:
                    InstructionBytes.AddRange(operand.Value.ToTvcAsciiBytes());
                    break;

                case OperandType.Decimal:
                {
                    ushort v = operand.ToString().ResolveUshortConstant();
                    if (v > 0xFF)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"Helytelen decimális érték '{operand}' a {row.Instruction.Mnemonic} utasításban! Az értéknek 0 és 255 közé kell esnie!"));
                    }
                    InstructionBytes.Add((byte)v);
                }
                break;

                case OperandType.Expression:
                {
                    var expressionParser = new ExpressionParser(operand.Value, SymbolTable);
                    var result           = expressionParser.Parse();
                    if (result.ResultCode == ParseResultCode.Error || result.ResultCode == ParseResultCode.ContainsFutureSymbol)
                    {
                        return(result);
                    }

                    if (result.ResultValue > 0xff)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"A kifejezés '{operand}' eredménye nem fért el egy byte-on!"));
                    }

                    InstructionBytes.Add((byte)result.ResultValue);
                }
                break;

                case OperandType.Literal:
                    InstructionBytes.AddRange(operand.Value.ToTvcAsciiBytes());
                    break;

                default:
                    return(new ParseResult(ParseResultCode.Error, 0, $"A(z) {operand} operandus típusa({operand.Info.DataType}) a {row.Instruction.Mnemonic} utasításban nem támogatott!"));
                }
            }

            return(new ParseResult(ParseResultCode.Ok));
        }