예제 #1
0
파일: LocalSymbol.cs 프로젝트: arlm/MixEmul
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            if (!IsLocalSymbol(text))
            {
                return(null);
            }

            char       localSymbolChar = text[0];
            SymbolBase symbol          = status.Symbols[new string(localSymbolChar, 1)];

            if (symbol == null)
            {
                symbol = new LocalSymbol(localSymbolChar - '0');
                status.Symbols.Add(symbol);
            }

            if (!(symbol is LocalSymbol))
            {
                status.ReportParsingError(sectionCharIndex, 1, "non-local symbol named " + localSymbolChar + " already defined, unable to refer to it");
                return(symbol);
            }

            if (IsDefinitionChar(text[1]))
            {
                status.ReportParsingError(sectionCharIndex + 1, 1, "local symbol definition found where reference was expected");
                return(symbol);
            }

            return(new Reference((LocalSymbol)symbol, IsForwardReferenceChar(text[1]) ? Reference.Directions.Forwards : Reference.Directions.Backwards));
        }
예제 #2
0
파일: LocalSymbol.cs 프로젝트: arlm/MixEmul
        public static SymbolBase ParseDefinition(string text, int sectionCharIndex, ParsingStatus status)
        {
            if (!IsLocalSymbol(text))
            {
                return(null);
            }

            if (!IsDefinitionChar(text[1]))
            {
                status.ReportParsingError(sectionCharIndex + 1, 1, "local symbol reference found where definition was expected");
            }

            char       localSymbolChar = text[0];
            SymbolBase symbol          = status.Symbols[localSymbolChar.ToString()];

            if (symbol == null)
            {
                return(new LocalSymbol(localSymbolChar - '0'));
            }

            if (!(symbol is LocalSymbol))
            {
                status.ReportParsingError(sectionCharIndex, 1, "non-local symbol named " + localSymbolChar + " already defined");
            }

            return(symbol);
        }
예제 #3
0
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            // an empty index is equal to 0
            if (text.Length == 0)
            {
                return(new NumberValue(0L));
            }

            // it can only be an index if it starts with a comma
            if (text[0] == TagCharacter)
            {
                // the actual fieldspec can be any expression...
                var expression = ExpressionValue.ParseValue(text.Substring(1), sectionCharIndex + 1, status);

                if (expression == null)
                {
                    return(null);
                }

                var value = expression.GetValue(status.LocationCounter);

                // ... as long as it is within the range of valid MIX byte values
                if (value >= MixByte.MinValue && value <= MixByte.MaxValue)
                {
                    return(expression);
                }

                status.ReportParsingError(sectionCharIndex, text.Length, "index value invalid");
            }

            return(null);
        }
예제 #4
0
파일: FPartValue.cs 프로젝트: arlm/MixEmul
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            // an empty fieldspec means we use the default
            if (text.Length == 0)
            {
                return(new NumberValue(Default));
            }

            // it can only be a fieldspec if it starts and ends with brackets
            if (text.Length >= 2 && text[0] == TagCharacter && text[text.Length - 1] == ')')
            {
                // the actual fieldspec can be any expression...
                var expression = ExpressionValue.ParseValue(text.Substring(1, text.Length - 2), sectionCharIndex + 1, status);

                if (expression == null)
                {
                    return(null);
                }

                var value = expression.GetValue(status.LocationCounter);

                // ... as long as it is within the range of valid MIX byte values
                if (value >= MixByte.MinValue && value <= MixByte.MaxValue)
                {
                    return(expression);
                }

                status.ReportParsingError(sectionCharIndex, text.Length, "field value invalid");
            }

            return(null);
        }
예제 #5
0
        /// <summary>
        /// Creates an instance of this class by parsing the address field of a MIX instruction.
        /// </summary>
        /// <param name="instruction">MixInstruction to parse the address field for. This method will throw an exception if this parameter is of a different instruction type.</param>
        /// <param name="addressField">The address field to parse.</param>
        /// <param name="status">ParsingStatus object reflecting the current state of the parse process</param>
        /// <returns></returns>
        public static IInstructionParameters ParseAddressField(InstructionBase instruction, string addressField, ParsingStatus status)
        {
            var indexCharIndex   = addressField.IndexOf(',');
            var sectionCharIndex = addressField.IndexOf('(', Math.Max(indexCharIndex, 0));

            if (sectionCharIndex == -1)
            {
                sectionCharIndex = addressField.Length;
            }

            if (indexCharIndex == -1)
            {
                indexCharIndex = sectionCharIndex;
            }

            var address = APartValue.ParseValue(addressField.Substring(0, indexCharIndex), 0, status);

            if (address == null)
            {
                status.ReportParsingError(0, indexCharIndex, "unable to parse address");
                return(null);
            }

            var index = IPartValue.ParseValue(addressField.Substring(indexCharIndex, sectionCharIndex - indexCharIndex), indexCharIndex, status);

            if (index == null)
            {
                status.ReportParsingError(indexCharIndex, sectionCharIndex - indexCharIndex, "unable to parse index");
                return(null);
            }

            var field = FPartValue.ParseValue(addressField.Substring(sectionCharIndex), sectionCharIndex, status);

            if (field == null)
            {
                status.ReportParsingError(sectionCharIndex, addressField.Length - sectionCharIndex, "unable to parse field");
                return(null);
            }

            return(new MixInstructionParameters(address, indexCharIndex, index, sectionCharIndex, field, addressField.Length));
        }
예제 #6
0
        /// <summary>
        /// Creates an instance of this class by parsing the address field of a loader instruction.
        /// </summary>
        /// <param name="instruction">LoaderInstruction to parse the address field for. This method will throw an exception if this parameter is of a different instruction type.</param>
        /// <param name="addressField">The address field to parse.</param>
        /// <param name="status">ParsingStatus object reflecting the current state of the parse process</param>
        /// <returns></returns>
        public static IInstructionParameters ParseAddressField(InstructionBase instruction, string addressField, ParsingStatus status)
        {
            if (!(instruction is LoaderInstruction))
            {
                throw new ArgumentException("instruction must be a LoaderInstruction", nameof(instruction));
            }

            var    loaderInstruction = (LoaderInstruction)instruction;
            IValue address           = loaderInstruction.Alphanumeric ? CharacterConstantValue.ParseValue(addressField, 0, status) : WValue.ParseValue(addressField, 0, status);

            if (address == null)
            {
                status.ReportParsingError(0, addressField.Length, "unable to parse value");
                return(null);
            }

            return(new LoaderInstructionParameters(address, addressField.Length));
        }
예제 #7
0
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            IValue value = null;

            value = NumberValue.ParseValue(text, sectionCharIndex, status);

            if (value == null)
            {
                value = LocationCounterValue.ParseValue(text, sectionCharIndex, status);
                if (value != null)
                {
                    return(value);
                }

                value = ValueSymbol.ParseValue(text, sectionCharIndex, status);
                if (value != null && !value.IsValueDefined(status.LocationCounter))
                {
                    status.ReportParsingError(sectionCharIndex, text.Length, "symbol " + text + " not defined");
                }
            }

            return(value);
        }
예제 #8
0
파일: WValue.cs 프로젝트: arlm/MixEmul
        public static IValue ParseValue(string text, int sectionCharIndex, ParsingStatus status)
        {
            // split the text to parse in its W-value components
            var textParts    = text.Split(new char[] { ',' });
            int currentIndex = 0;

            var register = new FullWordRegister();
            var word     = new FullWord(0);

            // parse and apply each component to the word that contains the result
            foreach (string part in textParts)
            {
                // parse the address part...
                var braceIndex = part.IndexOf('(');
                var address    = ExpressionValue.ParseValue((braceIndex == -1) ? part : part.Substring(0, braceIndex), sectionCharIndex + currentIndex, status);
                if (address == null)
                {
                    return(null);
                }

                // ... and check if it is valid
                var addressSign      = address.GetSign(status.LocationCounter);
                var addressMagnitude = address.GetMagnitude(status.LocationCounter);
                if (addressMagnitude > register.MaxMagnitude)
                {
                    status.ReportParsingError(sectionCharIndex + currentIndex, (braceIndex == -1) ? part.Length : braceIndex, "W-value field value invalid");
                    return(null);
                }

                register.MagnitudeLongValue = addressMagnitude;
                register.Sign = addressSign;
                int fieldValue = FullWord.ByteCount;

                // if a fieldspec part is present...
                if (braceIndex >= 0)
                {
                    // ... parse its value...
                    var field = FPartValue.ParseValue(part.Substring(braceIndex), (sectionCharIndex + currentIndex) + braceIndex, status);
                    if (field == null)
                    {
                        return(null);
                    }

                    // ... and check if it is valid
                    if (field.GetValue(status.LocationCounter) != FPartValue.Default)
                    {
                        fieldValue = (int)field.GetValue(status.LocationCounter);
                    }
                }

                // use the fieldspec value to create and check an actual fieldspec
                var fieldSpec = new FieldSpec(fieldValue);
                if (!fieldSpec.IsValid)
                {
                    status.ReportParsingError((sectionCharIndex + currentIndex) + braceIndex, part.Length - braceIndex, "field must be a fieldspec");
                    return(null);
                }

                // apply the component to the word that will contain the end result
                WordField.LoadFromRegister(fieldSpec, register).ApplyToFullWord(word);
                currentIndex += part.Length + 1;
            }

            return(new NumberValue(word.Sign, word.MagnitudeLongValue));
        }