Esempio n. 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));
        }
Esempio n. 2
0
        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 operandusra!"));
            }

            if (row.Operands.Count > 3)
            {
                return(new ParseResult(ParseResultCode.Error, 0, $"A {row.Instruction.Mnemonic} utasításnak maximum három operandusa lehet!"));
            }

            if (row.Operands[0].Info.DataType != OperandType.Literal)
            {
                return(new ParseResult(ParseResultCode.Error, 0, $"A {row.Instruction.Mnemonic} utasítás első operandusa kötelezően file név string!"));
            }

            foreach (string includeDirectory in m_IncludeDirectories)
            {
                var filePath = Path.Combine(includeDirectory, row.Operands[0].Value.Replace("\"", ""));

                if (File.Exists(filePath))
                {
                    try
                    {
                        FileInfo info   = new FileInfo(filePath);
                        var      result = ParseOperands(row, info.Length, out var position, out var count);
                        if (result.ResultCode != ParseResultCode.Ok)
                        {
                            return(result);
                        }

                        count = (int)(count == -1 || count > info.Length ? info.Length : count);
                        using (FileStream fs = new FileStream(filePath, FileMode.Open))
                        {
                            using (BinaryReader br = new BinaryReader(fs))
                            {
                                br.BaseStream.Position = position;
                                InstructionBytes.AddRange(br.ReadBytes(count));
                            }
                        }
                        return(new ParseResult(ParseResultCode.Ok));
                    }
                    catch (Exception e)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"A file '{row.Operands[0].Value}' feldolgozása sikertelen:{e.Message}"));
                    }
                }
            }

            return(new ParseResult(ParseResultCode.Error, 0, $"Nem találom a megadott file-t: '{row.Operands[0].Value}'"));
        }
        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));
        }
        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 a következő operandusai lehetnek: byte-ok száma[,alapérték]"));
            }

            byte[] initialValue = { 0x00 };
            if (row.Operands.Count == 2)
            {
                switch (row.Operands[1].Info.DataType)
                {
                case OperandType.Byte:
                    initialValue = new[] { row.Operands[1].Value.ResolveByteConstant() };
                    break;

                case OperandType.Decimal:
                {
                    ushort value = row.Operands[1].Value.ResolveUshortConstant();
                    if (value > 0xFF)
                    {
                        byte highByte = (byte)(value >> 8);
                        byte lowByte  = (byte)(value & 0xFF);
                        initialValue = new[] { lowByte, highByte };
                    }
                    else
                    {
                        initialValue = new[] { (byte)value };
                    }
                }
                break;

                case OperandType.Word:
                {
                    ushort value    = row.Operands[1].Value.ResolveUshortConstant();
                    byte   highByte = (byte)(value >> 8);
                    byte   lowByte  = (byte)(value & 0xFF);
                    initialValue = new[] { lowByte, highByte };
                }
                break;

                case OperandType.Character:
                case OperandType.Literal:
                    initialValue = row.Operands[1].Value.ToTvcAsciiBytes();
                    break;

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

                    initialValue = result.ResultValue <= 0xff ? new[] { (byte)result.ResultValue } : new[] { (byte)(result.ResultValue & 0xFF), (byte)(result.ResultValue >> 8) };
                }
                break;

                default:
                {
                    Symbol symbol = SymbolTable.Where(s => s.Key.Equals(row.Operands[1].Value)).Select(s => s.Value).FirstOrDefault();
                    if (symbol == null)
                    {
                        return(new ParseResult(ParseResultCode.Error, 0, $"A(z) {row.Operands[1]} operandus típusa({row.Operands[1].Info.DataType}) a {row.Instruction.Mnemonic} utasításban nem támogatott!"));
                    }

                    if (symbol.State == SymbolState.Unresolved)
                    {
                        return(new ParseResult(ParseResultCode.ContainsFutureSymbol));
                    }

                    initialValue = symbol.Value <= 0xff ? new[] { (byte)symbol.Value } : new[] { (byte)(symbol.Value & 0xFF), (byte)(symbol.Value >> 8) };
                    break;
                }
                }
            }

            ushort byteCount;

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

                byteCount = symbol.Value;
            }

            else if (row.Operands[0].Info.DataType == OperandType.Expression)
            {
                var expressionParser = new ExpressionParser(row.Operands[0].Value, SymbolTable);
                var result           = expressionParser.Parse();
                if (result.ResultCode == ParseResultCode.Error || result.ResultCode == ParseResultCode.ContainsFutureSymbol)
                {
                    return(result);
                }

                byteCount = result.ResultValue;
            }
            else
            {
                byteCount = row.Operands[0].ToString().ResolveUshortConstant();
            }


            for (int i = 1; i <= byteCount; i++)
            {
                InstructionBytes.AddRange(initialValue);
            }

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