Example #1
0
        /// <summary>
        /// Обрабатывает команду. В случае, если команда некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, содержащая команду процессора.</param>
        /// <param name="env">Текущее окружение компилятора, в которое записывается команда.</param>
        public void HandleCommand(string line, CompilerEnvironment env)
        {
            string command;

            string[] args;

            line = line.Trim();

            int firstSpaceIndex = line.IndexOf(" ");

            if (firstSpaceIndex == -1)
            {
                command = line;
                args    = new string[0];
            }
            else
            {
                command = line.Substring(0, firstSpaceIndex);
                args    = line.Substring(firstSpaceIndex + 1).Split(',').Select(x => x.Trim()).ToArray();
            }

            command = command.ToLower();
            if (!_commandProcessors.ContainsKey(command))
            {
                throw new CompilationErrorExcepton("Неверная команда", env.GetCurrentLine());
            }
            _commandProcessors[command](args, env);
        }
        /// <summary>
        /// Функция, начинающая обработку кода и содержащая базовую логику прохождения по нему и вызова обработчиков.
        /// </summary>
        private void StartCompile(object sender, DoWorkEventArgs e)
        {
            List <string> lines = PrepareCode(_code);
            var           env   = new CompilerEnvironment();

            for (short i = 0; i < lines.Count; i++)
            {
                if (lines[i].Length == 0)
                {
                    env.IncrementLine();
                    continue;
                }
                if (lines[i][0] == '/')
                {
                    HandleDirective(lines[i], env);
                    env.IncrementLine();
                    continue;
                }
                string line      = HandleLabelAndReturnLine(lines[i], env);
                bool   isSuccess = TryToGetVariable(line, env);
                if (!isSuccess)
                {
                    HandleCommand(line, env);
                }
                env.IncrementLine();
            }
            var commandWithoutLabel = env.FirstCommandWithoutLabel();

            if (commandWithoutLabel.HasValue)
            {
                throw new CompilationErrorExcepton($"Метка {commandWithoutLabel.Value.Value} не определена", commandWithoutLabel.Value.Key);
            }
            e.Result = env;
        }
Example #3
0
        /// <summary>
        /// Пытается достать из строки объявление переменной.
        /// Если в строке нет слова eql, то возвращает false,
        /// Если есть и строка имеет формат *идетификатор* eql *адрес*, то пытается сохранить адрес за идентификатором
        /// Если есть, но строка не подходит по формату, выбрасывает исключение <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода для обработки.</param>
        /// <param name="env">Окружение компилятора.</param>
        /// <returns>True, если в строке присутствовала переменная, false, если нет.</returns>
        public bool TryToGetVariable(string line, CompilerEnvironment env)
        {
            if (!line.Contains(" eql "))
            {
                return(false);
            }
            var args = line.Split(' ').Select(x => x.ToLower().Trim()).ToArray();

            if (args.Length != 3 || !args[1].Equals("eql", StringComparison.OrdinalIgnoreCase))
            {
                throw new CompilationErrorExcepton("Объявление переменной должно соответствовать формату *имя переменной* eql *адрес*.", env.GetCurrentLine());
            }

            bool isIdentifierCorrect = CompilerSupport.CheckIdentifierName(args[0]);

            if (!isIdentifierCorrect)
            {
                throw new CompilationErrorExcepton("Имя переменной должно содержать только латиские буквы, цифры знаки тире и подчеркивания и начинаться с буквы.", env.GetCurrentLine());
            }

            int address = CompilerSupport.ConvertToInt(args[2]);

            if (address > 255)
            {
                throw new CompilationErrorExcepton("Адрес не может превышать 255", env.GetCurrentLine());
            }
            if (env.IsIdentifierExist(args[0]))
            {
                throw new CompilationErrorExcepton($"Идентификатор с именем {args[0]} уже существует.", env.GetCurrentLine());
            }
            env.AddVariable(args[0], address);
            return(true);
        }
Example #4
0
            private static DataResponse GetBitArrays(string[] args, CompilerEnvironment env)
            {
                int register = CompilerSupport.ConvertToInt(args[0]);

                if (register < 0 || register > 127)
                {
                    throw new CompilationErrorExcepton("Номер регистра должен быть числом от 0 до 127", env.GetCurrentLine());
                }
                int bit = CompilerSupport.ConvertToInt(args[1]);

                if (bit < 0 || bit > 7)
                {
                    throw new CompilationErrorExcepton("Номер бита должен быть числом от 0 до 7", env.GetCurrentLine());
                }
                var dataResponse = new DataResponse {
                    lowBitArray  = new BitArray(8),
                    highBitArray = new BitArray(8)
                    {
                        [7] = true,
                        [5] = true
                    }
                };

                CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, register, 7);
                CompilerSupport.FillBitArray(null, dataResponse.highBitArray, bit, 3);
                return(dataResponse);
            }
Example #5
0
            private static void POP(string[] args, CompilerEnvironment env)
            {
                if (args.Length != 1)
                {
                    throw new CompilationErrorExcepton("Оператор POP должен принимать 1 аргумент.", env.GetCurrentLine());
                }
                var r = CompilerSupport.ConvertToRegister(args[0]);

                if (!r.HasValue)
                {
                    throw new CompilationErrorExcepton("Аргументом должен быть регистр.", env.GetCurrentLine());
                }
                var registr = r.Value;

                if (!registr.IsDirect)
                {
                    throw new CompilationErrorExcepton("Адресация регистра должна быть прямой.", env.GetCurrentLine());
                }
                var highBitArray = new BitArray(8)
                {
                    [6] = true,
                    [4] = true,
                    [3] = true,
                    [2] = true,
                    [0] = true
                };
                var lowBitArray = new BitArray(8);

                CompilerSupport.FillBitArray(null, lowBitArray, registr.Number, 4);

                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }
Example #6
0
            private static DataResponse GetBitArrays(string[] args, CompilerEnvironment env)
            {
                var dataResponse = new DataResponse {
                    lowBitArray  = new BitArray(8),
                    highBitArray = new BitArray(8)
                    {
                        [5] = true,
                        [6] = true
                    }
                };

                if (args[0][0] == '#')
                {
                    int num = CompilerSupport.ConvertToInt(args[0].Substring(1));
                    CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, num, Constants.ShortAddressBitsCount);
                    dataResponse.highBitArray[4] = true;
                    return(dataResponse);
                }

                int address = CompilerSupport.ConvertVariableToAddress(args[0], env);

                if (address == -1)
                {
                    throw new CompilationErrorExcepton($"Переменной с именем {args[0]} не существует.", env.GetCurrentLine());
                }
                CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, address, Constants.ShortAddressBitsCount);
                return(dataResponse);
            }
Example #7
0
 /// <summary>
 /// Приводит переданную строку к полному, 10-битовому адресу.
 /// Если введен слишком большой адрес или строка не является меткой,
 /// будет сгенерированно исключение <see cref="CompilerEnvironment"/>.
 /// </summary>
 /// <param name="label">Строка-метка или адрес в памяти.</param>
 /// <param name="env">Текущее окружение компилятора.</param>
 /// <returns>Адресс, на который ссылается метка или который был записан как число, или -1, если использована несуществующая метка.</returns>
 public static int ConvertLabelToFarAddress(string label, CompilerEnvironment env)
 {
     try {
         if (label[0] >= '0' && label[0] <= '9')
         {
             int address = ConvertToInt(label);
             if (address > MaxFarAddress)
             {
                 throw new OverflowException();
             }
             return(address);
         }
         else
         {
             int address = env.GetLabelAddress(label);
             return(address);
         }
     } catch (OverflowException) {
         throw new CompilationErrorExcepton($"Адрес не должен превышать {MaxFarAddress}", env.GetCurrentLine());
     } catch (FormatException) {
         throw new CompilationErrorExcepton("Некорректный адрес метки", env.GetCurrentLine());
     } catch (Exception e) {
         throw new CompilationErrorExcepton("Непредвиденная ошибка при обработке метки", env.GetCurrentLine(), e);
     }
 }
Example #8
0
            private static void NOT(string[] args, CompilerEnvironment env)
            {
                var dataResponse = GetBitArrays(args, "NOT", env);

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
Example #9
0
            private static DataResponse GetBitArrays(string[] args, CompilerEnvironment env)
            {
                var dataResponse = new DataResponse {
                    lowBitArray  = new BitArray(8),
                    highBitArray = new BitArray(8)
                    {
                        [7] = true
                    }
                };

                int address = CompilerSupport.ConvertVariableToAddress(args[0], env);

                if (address == -1)
                {
                    throw new CompilationErrorExcepton($"Переменной с именем {args[0]} не существует.", env.GetCurrentLine());
                }
                CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, address, Constants.ShortAddressBitsCount);

                int bit = CompilerSupport.ConvertToInt(args[1]);

                if (bit >= 1 << 3 || bit < 0)
                {
                    throw new CompilationErrorExcepton("Номер бита не должен превышать 7", env.GetCurrentLine());
                }
                CompilerSupport.FillBitArray(null, dataResponse.highBitArray, bit, 3);

                return(dataResponse);
            }
Example #10
0
            private static void CMP(string[] args, CompilerEnvironment env)
            {
                var dataResponse = GetBitArrays(args, "CMP", env);

                dataResponse.highBitArray[3] = true;

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
Example #11
0
            private static void CB(string[] args, CompilerEnvironment env)
            {
                Validate(args, "CB", env.GetCurrentLine());

                var dataResponse = GetBitArrays(args, env);

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
            private static void RET(string[] args, CompilerEnvironment env)
            {
                ValidateNoAddressCommand(args, "RET", env.GetCurrentLine());
                var array = new ExtendedBitArray()
                {
                    [1] = true
                };

                env.SetByte(array);
                env.SetByte(new ExtendedBitArray());
            }
Example #13
0
            private static void EI(string[] args, CompilerEnvironment env)
            {
                ValidateNoAddressCommand(args, "EI", env.GetCurrentLine());
                var array = new BitArray(8)
                {
                    [2] = true
                };

                env.SetByte(array);
                env.SetByte(new BitArray(8));
            }
Example #14
0
            private static void XOR(string[] args, CompilerEnvironment env)
            {
                var dataResponse = GetBitArrays(args, "XOR", env);

                dataResponse.highBitArray[0] = true;
                dataResponse.highBitArray[1] = true;
                dataResponse.highBitArray[2] = true;

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
Example #15
0
            private static void SBISC(string[] args, CompilerEnvironment env)
            {
                Validate(args, "SBISC", env.GetCurrentLine());
                var dataResponse = GetBitArrays(args, env);

                dataResponse.highBitArray[3] = true;
                dataResponse.highBitArray[4] = true;

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
Example #16
0
            private static void CALL(string[] args, CompilerEnvironment env)
            {
                Validate(args, "CALL", env.GetCurrentLine());

                var highBitArray = new BitArray(8);
                var lowBitArray  = new BitArray(8);

                highBitArray[3] = true;
                highBitArray[6] = true;

                FillAddressAndSetCommand(highBitArray, lowBitArray, args[0], env);
            }
Example #17
0
            private static void JNZ(string[] args, CompilerEnvironment env)
            {
                Validate(args, "JNZ", env.GetCurrentLine());

                var lowBitArray  = new BitArray(8);
                var highBitArray = new BitArray(8)
                {
                    [5] = true
                };

                FillAddressAndSetCommand(highBitArray, lowBitArray, args[0], env);
            }
            private static void JC(string[] args, CompilerEnvironment env)
            {
                Validate(args, "JC", env.GetCurrentLine());

                var lowBitArray  = new ExtendedBitArray();
                var highBitArray = new ExtendedBitArray()
                {
                    [2] = true,
                    [4] = true,
                    [5] = true
                };

                FillAddressAndSetCommand(highBitArray, lowBitArray, args[0], env);
            }
Example #19
0
            private static void DJRNZ(string[] args, CompilerEnvironment env)
            {
                if (args.Length != 2)
                {
                    throw new CompilationErrorExcepton("Оператор DJRNZ должен принимать ровно 2 аргумента.", env.GetCurrentLine());
                }

                var R = CompilerSupport.ConvertToRegister(args[0]);

                if (!R.HasValue)
                {
                    throw new CompilationErrorExcepton("Первым аргументом должен быть регистр.", env.GetCurrentLine());
                }
                var register = R.Value;

                if (!register.IsDirect)
                {
                    throw new CompilationErrorExcepton("В этой команде нельзя использовать косвенную адерсацию.", env.GetCurrentLine());
                }
                if (register.Number > 3)
                {
                    throw new CompilationErrorExcepton("В этой команде можно использовать только первые 4 регистра.", env.GetCurrentLine());
                }
                string L       = args[1];
                int    address = CompilerSupport.ConvertLabelToFarAddress(L, env);

                var lowBitArray  = new BitArray(8);
                var highBitArray = new BitArray(8)
                {
                    [2] = (register.Number & 1) != 0,
                    [3] = (register.Number & 2) != 0,
                    [4] = true
                };

                if (address == -1)
                {
                    var memoryForLabel = new CompilerEnvironment.MemoryForLabel {
                        HighBitArray = highBitArray,
                        LowBitArray  = lowBitArray,
                        Address      = env.CurrentAddress
                    };
                    env.SetCommandWithoutLabel(memoryForLabel, L);
                    return;
                }

                CompilerSupport.FillBitArray(highBitArray, lowBitArray, address, Constants.FarAddressBitsCount);
                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }
Example #20
0
        /// <summary>
        /// Обрабатывает директиву процессора, и изменяет окружение в соответствии с ней.
        /// В случае, если директива некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, из которой извлекается директива.</param>
        /// <param name="env">Текущее окружение компилятора, которое изменяется в соответствии с директивой.</param>
        public void HandleDirective(string line, CompilerEnvironment env)
        {
            if (line[1] == 'n' || line[1] == 'N')
            {
                string[] components = line.Split(' ');
                if (components.Length != 2)
                {
                    throw new CompilationErrorExcepton("После /n должно следовать одно число через пробел.", env.GetCurrentLine());
                }

                try {
                    int address = CompilerSupport.ConvertToInt(components[1]);
                    if (address > 255 || address < 0)
                    {
                        throw new Exception();
                    }
                    env.CurrentAddress = address;
                } catch (Exception) {
                    throw new CompilationErrorExcepton("Некорректная директива процессора. Адрес должен быть числом в диапазоне от 0 до 255.", env.GetCurrentLine());
                }
            }
            else if (line[1] == 'C' || line[1] == 'c')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultCodeSegment = segment;
            }
            else if (line[1] == 'S' || line[1] == 's')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultStackSegment = segment;
            }
            else if (line[1] == 'D' || line[1] == 'd')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultDataSegment = segment;
            }
            else
            {
                throw new CompilationErrorExcepton("Некорректная директива процессора.", env.GetCurrentLine());
            }
        }
Example #21
0
        /// <summary>
        /// Проверяет, присутствует ли в строке метка, и если она есть, добавляет метку в окружение и удаляет ее из строки.
        /// Если имя метки некорректно или занято, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, которая проверяется на наличие метки.</param>
        /// <param name="env">Текущее окружение компилятора, в которое добавляется метка.</param>
        /// <returns>Строка, из которой была удалена метка, если она существовала ранее.</returns>
        public string HandleLabelAndReturnLine(string line, CompilerEnvironment env)
        {
            int colon = line.IndexOf(':');

            if (colon == -1)
            {
                return(line);
            }
            string label = line.Substring(0, colon);

            if (!CompilerSupport.CheckIdentifierName(label))
            {
                throw new CompilationErrorExcepton($"Имя метки {label} некорректно", env.GetCurrentLine());
            }
            if (env.IsIdentifierExist(label))
            {
                throw new CompilationErrorExcepton($"Идентификатор с именем {label} уже существует.", env.GetCurrentLine());
            }
            env.AddAddressLabelToNewCommand(label);
            return(line.Substring(colon + 1));
        }
Example #22
0
            private static void IN(string[] args, CompilerEnvironment env)
            {
                if (args.Length == 0)
                {
                    var array = new BitArray(8)
                    {
                        [4] = true
                    };
                    env.SetByte(array);
                    env.SetByte(new BitArray(8));
                    return;
                }
                if (args.Length > 0)
                {
                    throw new CompilationErrorExcepton("Команда IN не может принимать более 1 аргумента.", env.GetCurrentLine());
                }

                var dataResponse = GetBitArrays(args, env);

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
Example #23
0
            private static void SUBB(string[] args, CompilerEnvironment env)
            {
                var dataResponse = GetBitArrays(args, "SUBB", env);

                if (dataResponse.highBitArray[5])
                {
                    dataResponse.highBitArray[1] = true;
                    dataResponse.highBitArray[2] = true;
                    dataResponse.highBitArray[3] = true;
                }
                else
                {
                    //Если команда регистровая
                    dataResponse.highBitArray[7] = true;
                    dataResponse.highBitArray[6] = true;
                    dataResponse.highBitArray[5] = true;
                    dataResponse.highBitArray[4] = true;
                    dataResponse.highBitArray[0] = true;
                }

                env.SetByte(dataResponse.lowBitArray);
                env.SetByte(dataResponse.highBitArray);
            }
            private static DataResponse GetBitArrays(string[] args, string op, CompilerEnvironment env)
            {
                if (args.Length != 1)
                {
                    throw new CompilationErrorExcepton($"Команда {op} принимает 1 агрумент.", env.GetCurrentLine());
                }
                var dataResponse = new DataResponse {
                    lowBitArray  = new ExtendedBitArray(),
                    highBitArray = new ExtendedBitArray()
                };

                var r = CompilerSupport.ConvertToRegister(args[0]);

                if (r.HasValue)
                {
                    if (r.Value.Number > 7)
                    {
                        throw new CompilationErrorExcepton($"Номер регистра не может быть больше 7.", env.GetCurrentLine());
                    }
                    return(DataResponseFromRegister(args, op, env, dataResponse, r.Value));
                }

                dataResponse.highBitArray[6] = true;
                dataResponse.highBitArray[5] = true;
                if (args[0][0] == '#')
                {
                    int num = CompilerSupport.ConvertToInt(args[0].Substring(1));
                    CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, num, Constants.ShortAddressBitsCount);
                    dataResponse.highBitArray[4] = true;
                }
                else
                {
                    var address = CompilerSupport.ConvertVariableToAddress(args[0], env);
                    CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, address, 8);
                }
                return(dataResponse);
            }
Example #25
0
            private static DataResponse GetBitArrays(string[] args, string op, CompilerEnvironment env)
            {
                if (args.Length < 0 || args.Length > 2)
                {
                    throw new CompilationErrorExcepton($"Команда {op} принимает 1 или 2 агрумента.", env.GetCurrentLine());
                }
                var dataResponse = new DataResponse {
                    lowBitArray  = new BitArray(8),
                    highBitArray = new BitArray(8)
                };

                var r = CompilerSupport.ConvertToRegister(args[0]);

                if (r.HasValue)
                {
                    return(DataResponseFromRegister(args, op, env, dataResponse, r.Value));
                }
                if (args.Length == 2)
                {
                    throw new CompilationErrorExcepton($"При работе с оперативной памятью команда {op} принимает только 1 аргумент", env.GetCurrentLine());
                }

                dataResponse.highBitArray[6] = true;
                dataResponse.highBitArray[5] = true;
                if (args[0][0] == '#')
                {
                    int num = CompilerSupport.ConvertToInt(args[0].Substring(1));
                    CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, num, Constants.ShortAddressBitsCount);
                    dataResponse.highBitArray[4] = true;
                }
                else
                {
                    var address = CompilerSupport.ConvertVariableToAddress(args[0], env);
                    CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, address, 8);
                }
                return(dataResponse);
            }
Example #26
0
            private static void MOV(string[] args, CompilerEnvironment env)
            {
                if (args.Length != 2)
                {
                    throw new CompilationErrorExcepton("Оператор MOV должен принимать 2 аргументa.", env.GetCurrentLine());
                }
                var r1 = CompilerSupport.ConvertToRegister(args[0]);
                var r2 = CompilerSupport.ConvertToRegister(args[1]);

                if (!r1.HasValue || !r2.HasValue)
                {
                    throw new CompilationErrorExcepton("Аргументом должен быть регистр.", env.GetCurrentLine());
                }
                var registr1 = r1.Value;
                var registr2 = r2.Value;

                if (!registr1.IsDirect || !registr2.IsDirect)
                {
                    throw new CompilationErrorExcepton("Адресация регистра должна быть прямой.", env.GetCurrentLine());
                }
                var highBitArray = new BitArray(8)
                {
                    [6] = true,
                    [4] = true,
                    [3] = true,
                    [2] = true,
                    [1] = true,
                    [0] = true
                };
                var lowBitArray = new BitArray(8);

                CompilerSupport.FillBitArray(null, lowBitArray, (registr2.Number << 4) + registr1.Number, 8);

                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }
Example #27
0
        /// <summary>
        /// Обрабатывает директиву процессора, и изменяет окружение в соответствии с ней.
        /// В случае, если директива некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, из которой извлекается директива.</param>
        /// <param name="env">Текущее окружение компилятора, которое изменяется в соответствии с директивой.</param>
        public void HandleDirective(string line, CompilerEnvironment env)
        {
            if (line.Substring(1).ToLower().StartsWith("org"))
            {
                string[] components = line.Split(' ');
                if (components.Length != 2)
                {
                    throw new CompilationErrorExcepton("После /org должно следовать одно число через пробел.", env.GetCurrentLine());
                }

                try {
                    int address = CompilerSupport.ConvertToInt(components[1]);
                    if (address > 255 || address < 0)
                    {
                        throw new Exception();
                    }
                    env.CurrentAddress = address;
                } catch (Exception) {
                    throw new CompilationErrorExcepton("Некорректная директива процессора. Адрес должен быть числом в диапазоне от 0 до 255.", env.GetCurrentLine());
                }
            }
            else if (line[1] == 'C' || line[1] == 'c')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultCodeSegment = segment;
            }
            else if (line[1] == 'S' || line[1] == 's')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultStackSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && line[2] != 'B' && line[2] != 'b' && line[2] != 'W' && line[2] != 'w')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultDataSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'B' || line[2] == 'b'))                 //работа дерективы .db
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string value   = i.Trim();
                    int    address = CompilerSupport.ConvertLabelToFarAddress(value, env);
                    if (address != -1)
                    {
                        address = address & 0xFF;

                        env.SetByte(new ExtendedBitArray(address));
                    }
                    else
                    {
                        env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel {
                            HighBitArray = new ExtendedBitArray(),
                            LowBitArray  = new ExtendedBitArray(),
                            Address      = env.CurrentAddress,
                            SingleByte   = true
                        }, value);
                    }
                }
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'W' || line[2] == 'w'))             //работа дерективы .dw
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string        value      = i.Trim();
                    List <string> parameters = new List <string>();
                    if (value.StartsWith("0x") && value.Length > 4)                    //если адрес формата 0xFFFF или 0xFFF, раскладываем на 2 байта
                    {
                        parameters.Add("0x" + value.Substring(value.Length - 2));
                        parameters.Add(value.Substring(0, value.Length - 2));
                    }
                    else if (value.StartsWith("0b") && value.Length > 10)                    //если 0b11..11 (больше 1 байта)
                    {
                        parameters.Add("0b" + value.Substring(value.Length - 8));
                        parameters.Add(value.Substring(0, value.Length - 8));
                    }
                    else
                    {
                        parameters.Add(value);                        //если 0xFF, 0b11111111 или Метка
                        parameters.Add("0x00");
                    }
                    foreach (var p in parameters)
                    {
                        int address = CompilerSupport.ConvertLabelToFarAddress(p, env);
                        if (address != -1)
                        {
                            address = address & 0xFF;
                            env.SetByte(new ExtendedBitArray(address));
                        }
                        else
                        {
                            env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel
                            {
                                HighBitArray = new ExtendedBitArray(),
                                LowBitArray  = new ExtendedBitArray(),
                                Address      = env.CurrentAddress,
                                SingleByte   = true
                            }, p);
                        }
                    }
                }
            }
            else
            {
                throw new CompilationErrorExcepton("Некорректная директива процессора.", env.GetCurrentLine());
            }
        }
Example #28
0
        /// <summary>
        /// Обрабатывает директиву процессора, и изменяет окружение в соответствии с ней.
        /// В случае, если директива некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, из которой извлекается директива.</param>
        /// <param name="env">Текущее окружение компилятора, которое изменяется в соответствии с директивой.</param>
        public void HandleDirective(string line, CompilerEnvironment env)
        {
            if (line.Substring(1).ToLower().StartsWith("org"))
            {
                string[] components = line.Split(' ');
                if (components.Length != 2)
                {
                    throw new CompilationErrorExcepton("После /org должно следовать одно число через пробел.", env.GetCurrentLine());
                }

                try {
                    int address = CompilerSupport.ConvertToInt(components[1]);
                    if (address > 255 || address < 0)
                    {
                        throw new Exception();
                    }
                    env.CurrentAddress = address;
                } catch (Exception) {
                    throw new CompilationErrorExcepton("Некорректная директива процессора. Адрес должен быть числом в диапазоне от 0 до 255.", env.GetCurrentLine());
                }
            }
            else if (line[1] == 'C' || line[1] == 'c')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultCodeSegment = segment;
            }
            else if (line[1] == 'S' || line[1] == 's')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultStackSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && line[2] != 'B' && line[2] != 'b')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultDataSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'B' || line[2] == 'b'))
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string value   = i.Trim();
                    int    address = CompilerSupport.ConvertLabelToFarAddress(value, env);
                    if (address != -1)
                    {
                        address = address & 0xFF;

                        env.SetByte(new ExtendedBitArray(address));
                    }
                    else
                    {
                        env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel {
                            HighBitArray = new ExtendedBitArray(),
                            LowBitArray  = new ExtendedBitArray(),
                            Address      = env.CurrentAddress,
                            SingleByte   = true
                        }, value);
                    }
                }
            }
            else
            {
                throw new CompilationErrorExcepton("Некорректная директива процессора.", env.GetCurrentLine());
            }
        }
Example #29
0
 //Прямая - 000
 //@R     - 100
 //@R+    - 001
 //+@R    - 101
 //@R-    - 011
 //-@R    - 111
 private static DataResponse DataResponseFromRegister(string[] args, string op, CompilerEnvironment env, DataResponse dataResponse, CompilerSupport.Register register)
 {
     dataResponse.highBitArray[6] = true;
     dataResponse.highBitArray[4] = true;
     CompilerSupport.FillBitArray(null, dataResponse.lowBitArray, register.Number, 4);
     if (register.IsDirect)
     {
         //Ничего не делаем
     }
     else if (!register.IsChange)
     {
         dataResponse.lowBitArray[4] = true;
     }
     else if (register.IsPostchange && register.IsIncrement)
     {
         dataResponse.lowBitArray[6] = true;
     }
     else if (register.IsPostchange)
     {
         dataResponse.lowBitArray[5] = true;
         dataResponse.lowBitArray[6] = true;
     }
     else if (register.IsIncrement)
     {
         dataResponse.lowBitArray[6] = true;
         dataResponse.lowBitArray[4] = true;
     }
     else
     {
         dataResponse.lowBitArray[6] = true;
         dataResponse.lowBitArray[5] = true;
         dataResponse.lowBitArray[4] = true;
     }
     if (args.Length != 2)
     {
         return(dataResponse);
     }
     if (args[1] == "1")
     {
         dataResponse.lowBitArray[7] = true;
         return(dataResponse);
     }
     if (args[1] != "0")
     {
         throw new CompilationErrorExcepton($"Вторым аргументом у команды {op} может быть только 0 или 1.", env.GetCurrentLine());
     }
     return(dataResponse);
 }
Example #30
0
            private static void FillAddressAndSetCommand(BitArray highBitArray, BitArray lowBitArray, string label, CompilerEnvironment env)
            {
                int address = CompilerSupport.ConvertLabelToFarAddress(label, env);

                if (address == -1)
                {
                    var memoryForLabel = new CompilerEnvironment.MemoryForLabel {
                        HighBitArray = highBitArray,
                        LowBitArray  = lowBitArray,
                        Address      = env.CurrentAddress
                    };
                    env.SetCommandWithoutLabel(memoryForLabel, label);
                    return;
                }

                CompilerSupport.FillBitArray(highBitArray, lowBitArray, address, Constants.FarAddressBitsCount);

                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }