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)); }
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); }
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); }
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); }
/// <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)); }
/// <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)); }
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); }
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)); }