public Assembler(ref byte[] bytes, AssemblerConfig config) { this.Config = config; this.Bytes = bytes; }
public Assembler(AssemblerConfig config) { this.Config = config; }
/// <summary> /// Determines addressing method of a line /// </summary> /// <param name="assembler"></param> public void DetermineAddressingMethod(AssemblerConfig config) { if (this.OpCode == null) { throw new InvalidOperationException("Attempt to determine addressing method of non-statement"); } if (this.RValue == null) { this.AddressingMethod = Assembly.AddressingMethod.implied; return; } //will include branches, jmp, implied, accumulator (shown as implied if (Assembly.OpcodeTable[OpCode.Value].Keys.Count == 1) { AddressingMethod = Assembly.OpcodeTable[OpCode.Value].Keys.First(); return; } //branches and jumps were already detected before this point this.RValue.ParseValue(this.OpCode.Value); var result = this.RValue.ComputedValue; var choices = RValue.LineEndingToOptions[this.RValue.ValueRight].Where( choice => Assembly.OpcodeTable[this.OpCode.Value].Keys.Contains(choice) ).ToList(); if (choices.Count == 0) { throw new SyntaxErrorException("Illegal addressing method for opcode"); } if (choices.Count == 1) { this.AddressingMethod = choices.First(); return; } if (result.Literal) { this.AddressingMethod = Assembly.AddressingMethod.immediate; return; } choices.Remove(Assembly.AddressingMethod.immediate); if (choices.Count == 0) { throw new SyntaxErrorException("Illegal addressing method for opcode"); } if (choices.Count == 1) { this.AddressingMethod = choices.First(); return; } Assembly.AddressingMethod lo = choices.Where(choice => Assembly.AddressingMethodLength[choice] == 1).First(); Assembly.AddressingMethod hi = choices.Where(choice => Assembly.AddressingMethodLength[choice] == 2).First(); switch (config.OperandLength) { case AssemblerConfig.OperandLengthOption.Longest: this.AddressingMethod = hi; return; case AssemblerConfig.OperandLengthOption.Smallest: if (result.Result > byte.MaxValue) { this.AddressingMethod = hi; return; } this.AddressingMethod = lo; return; case AssemblerConfig.OperandLengthOption.AsWritten: //Only works in binary and hex because they're the ones where one extra digit is the point where it goes from one byte to two if (result.Base == 2 || result.Base == 16) { //maximum characters before there are more characters than necessary to represent 256 int bumpLimit = result.Base == 2 ? 8 : 2; if (result.ValueString.Length > bumpLimit) { this.AddressingMethod = hi; return; } this.AddressingMethod = lo; return; } if (result.Result > byte.MaxValue) { this.AddressingMethod = hi; return; } this.AddressingMethod = lo; return; } throw new SyntaxErrorException("Unable to determine addressing method"); }