void ReportInstanceErrors(AssemblingStatus status, MixInstruction.Instance instance) { var errorArray = instance.Validate(); if (errorArray != null) { int causeStartIndex = 0; int causeLength = 0; foreach (InstanceValidationError error in errorArray) { switch (error.Source) { case InstanceValidationError.Sources.Address: causeStartIndex = 0; causeLength = mIndexPartCharIndex; break; case InstanceValidationError.Sources.Index: causeStartIndex = mIndexPartCharIndex; causeLength = mFieldPartCharIndex - mIndexPartCharIndex; break; case InstanceValidationError.Sources.FieldSpec: causeStartIndex = mFieldPartCharIndex; causeLength = mTextLength - mFieldPartCharIndex; break; } status.ReportError(LineSection.AddressField, causeStartIndex, causeLength, error); } } }
MixByte GetFieldSpecValue(AssemblingStatus status, MixInstruction mixInstruction) { var fieldValue = mField.GetValue(status.LocationCounter); switch (mixInstruction.MetaFieldSpec.Presence) { case MetaFieldSpec.Presences.Forbidden: if (fieldValue == long.MinValue) { return(mixInstruction.FieldSpec.MixByteValue); } status.ReportParsingError(LineSection.AddressField, mFieldPartCharIndex, mTextLength - mFieldPartCharIndex, "fieldspec forbidden for this instruction"); return(null); case MetaFieldSpec.Presences.Optional: if (fieldValue == long.MinValue) { return(mixInstruction.MetaFieldSpec.DefaultFieldSpec.MixByteValue); } return((int)fieldValue); case MetaFieldSpec.Presences.Mandatory: if (fieldValue != long.MinValue) { return((int)fieldValue); } status.ReportParsingError(LineSection.AddressField, mFieldPartCharIndex, mTextLength - mFieldPartCharIndex, "fieldspec mandatory for this instruction"); return(null); } return(null); }
/// <summary> /// Create a MIX instruction instance with the parameters contained in this object. /// </summary> /// <param name="instruction">MixInstruction to create an instance of. This method will throw an exception if this parameter is of a different instruction type.</param> /// <param name="status">AssemblingStatus object reflecting the current state of the assembly process</param> /// <returns></returns> public InstructionInstanceBase CreateInstance(InstructionBase instruction, AssemblingStatus status) { if (!(instruction is MixInstruction)) { throw new ArgumentException("instruction must be a MixInstruction", nameof(instruction)); } var mixInstruction = (MixInstruction)instruction; if (!AreValuesDefined(status)) { return(null); } var addressMagnitude = mAddress.GetMagnitude(status.LocationCounter); var word = new Word(MixInstruction.AddressByteCount); if (addressMagnitude > word.MaxMagnitude) { status.ReportError(LineSection.AddressField, 0, mIndexPartCharIndex, new MixAssembler.Finding.ParsingError("address value " + addressMagnitude + " invalid", (int)-word.MaxMagnitude, (int)word.MaxMagnitude)); return(null); } word.MagnitudeLongValue = addressMagnitude; var fieldSpecValue = GetFieldSpecValue(status, mixInstruction); if (fieldSpecValue == null) { return(null); } var instructionWord = new FullWord { Sign = mAddress.GetSign(status.LocationCounter) }; for (int i = 0; i < word.ByteCount; i++) { instructionWord[i] = word[i]; } instructionWord[MixInstruction.IndexByte] = (int)mIndex.GetValue(status.LocationCounter); instructionWord[MixInstruction.FieldSpecByte] = fieldSpecValue; instructionWord[MixInstruction.OpcodeByte] = mixInstruction.Opcode; var instance = mixInstruction.CreateInstance(instructionWord); ReportInstanceErrors(status, instance); return(instance); }
/// <summary> /// Create a loader instruction instance with the parameters contained in this object. /// </summary> /// <param name="instruction">LoaderInstruction to create an instance of. This method will throw an exception if this parameter is of a different instruction type.</param> /// <param name="status">AssemblingStatus object reflecting the current state of the assembly process</param> /// <returns></returns> public InstructionInstanceBase CreateInstance(InstructionBase instruction, AssemblingStatus status) { if (!(instruction is LoaderInstruction)) { throw new ArgumentException("instruction must be a LoaderInstruction", nameof(instruction)); } var loaderInstruction = (LoaderInstruction)instruction; if (!mValue.IsValueDefined(status.LocationCounter)) { status.ReportParsingError(LineSection.AddressField, 0, mTextLength, "value is not defined"); return(null); } return(new LoaderInstruction.Instance(loaderInstruction, mValue.GetSign(status.LocationCounter), mValue.GetMagnitude(status.LocationCounter))); }
bool AreValuesDefined(AssemblingStatus status) { if (!mAddress.IsValueDefined(status.LocationCounter)) { status.ReportParsingError(LineSection.AddressField, 0, mIndexPartCharIndex, "address value undefined"); return(false); } if (!mIndex.IsValueDefined(status.LocationCounter)) { status.ReportParsingError(LineSection.AddressField, mIndexPartCharIndex, mFieldPartCharIndex - mIndexPartCharIndex, "index value undefined"); return(false); } if (!mAddress.IsValueDefined(status.LocationCounter)) { status.ReportParsingError(LineSection.AddressField, mFieldPartCharIndex, mTextLength - mFieldPartCharIndex, "field value undefined"); return(false); } return(true); }
public InstructionInstanceBase CreateInstance(AssemblingStatus status) => Parameters.CreateInstance(Instruction, status);