public void SetValue(Romulus.StringSection name, LiteralValue value, bool isFixed, out Error error) { error = Error.None; if (assembler.CurrentPass == null) { throw new InvalidOperationException("Can only access variables when assembler is running a pass."); } bool isDollar = Romulus.StringSection.Compare(name, "$", true) == 0; if (isDollar) { assembler.CurrentPass.SetAddress(value.Value); } string nameString = name.ToString(); //assembler.CurrentPass.Values.Remove(nameString); //assembler.CurrentPass.Values.Add(nameString, value); bool fixedValueError; assembler.CurrentPass.Values.SetValue(nameString, value, isFixed, out fixedValueError); if (fixedValueError) { // Todo: replace this with assembler value, or return fixedValueError somehow. //throw new Exception("Attempted to assign to a fixed value. This exception should be replaced with an appropriate assembler error."); error = new Error(ErrorCode.Value_Already_Defined, string.Format(Error.Msg_ValueAlreadyDefined_name, nameString)); } }
public ParsedInstruction(byte opcode, LiteralValue operandValue, int sourceLine) { this.opcode = opcode; this.operandValue = operandValue; this.operandExpression = null; this.sourceLine = sourceLine; }
public ParsedInstruction(byte opcode, string operandExpression, int sourceLine) { this.opcode = opcode; this.operandValue = new LiteralValue(); this.operandExpression = operandExpression; this.sourceLine = sourceLine; }
public bool TryGetValue(Romulus.StringSection name, out LiteralValue result) { bool isDollar = Romulus.StringSection.Compare(name, "$", true) == 0; if (isDollar) { result = new LiteralValue((ushort)assembler.CurrentPass.CurrentAddress, false); return(true); } var value = assembler.CurrentPass.Values.TryGetValue(name.ToString()); result = value.HasValue ? value.Value : default(LiteralValue); return(value.HasValue); }
bool ParseOperand(StringSection operand, out LiteralValue value, out string expression) { if (ExpressionEvaluator.TryParseLiteral(operand, out value)) { expression = null; return(true); } else if (operand.Length > 0) { value = default(LiteralValue); expression = operand.ToString(); return(true); } else { value = default(LiteralValue); expression = null; return(false); } }
public void SetValue(string name, LiteralValue value, bool isFixed, out bool valueIsFixedError) { PassValue existingValue; bool exists = Values.TryGetValue(name, out existingValue); if (exists) { if (existingValue.isFixed) { valueIsFixedError = true; return; } else { Values.Remove(name); } } Values.Add(name, new PassValue(value, isFixed)); valueIsFixedError = false; }
private void EmitData(Pass pass, ref Error error, LiteralValue value) { switch (dataType) { case DataType.Bytes: pass.CurrentAddress += 1; pass.CurrentOutputOffset += 1; if (pass.EmitOutput) { if (value.IsByte) { pass.WriteByte((byte)value.Value); } else { error = new Error(ErrorCode.Type_Mismatch, Error.Msg_ValueNotByte, SourceLine); } } break; case DataType.Words: pass.CurrentAddress += 2; pass.CurrentOutputOffset += 2; if (pass.EmitOutput) { // if (value.IsByte) { // error = new Error(ErrorCode.Type_Mismatch, Error.Msg_ValueNotWord, SourceLine); //} else { pass.WriteByte((byte)value.Value); // Low pass.WriteByte((byte)(value.Value >> 8)); // High //} } break; case DataType.Implicit: if (value.IsByte) { pass.CurrentAddress += 1; pass.CurrentOutputOffset += 1; if (pass.EmitOutput) { pass.WriteByte((byte)value.Value); } } else { pass.CurrentAddress += 2; pass.CurrentOutputOffset += 2; if (pass.EmitOutput) { pass.WriteByte((byte)value.Value); // Low pass.WriteByte((byte)(value.Value >> 8)); // High } } break; default: System.Diagnostics.Debug.Fail("Invalid case"); break; } }
public AsmValue(string expression) { Literal = new LiteralValue(); Expression = expression; }
public AsmValue(LiteralValue value) { this.Literal = value; Expression = null; }
public PassValue(LiteralValue value, bool isFixed) { this.value = value; this.isFixed = isFixed; }
private bool ParseInstruction(StringSection instruction, StringSection operand, int iSourceLine, out Error error) { error = Error.None; if (operand.Length > 0 && operand[0] == '@') { } var addressing = ParseAddressing(ref operand); int opcodeVal = FindOpcode(instruction, addressing); // Some instructions only support zero-page addressing variants of certain addressing modes if ((OpcodeError)opcodeVal == OpcodeError.InvalidAddressing) { var newAddressing = addressing; if (TryZeroPageEqivalent(ref newAddressing)) { opcodeVal = FindOpcode(instruction, newAddressing); if (opcodeVal >= 0) { addressing = newAddressing; // Keep the zero-page addressing } } } if (opcodeVal < 0) { // We don't throw an error if 'instruction' isn't an instruction (the line could be anything else other than instruction) if ((OpcodeError)opcodeVal == OpcodeError.UnknownInstruction) { return(false); } else { SetOpcodeError(iSourceLine, instruction.ToString(), addressing, opcodeVal, out error); return(true); } } if (addressing != Opcode.addressing.implied) { LiteralValue operandValue = new LiteralValue(); string operandExpression = null; // Todo: consider method(s) such as assembly.AddInstruction if (ExpressionEvaluator.TryParseLiteral(operand, out operandValue)) { assembly.ParsedInstructions.Add(new ParsedInstruction((byte)opcodeVal, operandValue, iSourceLine)); } else if (operand.Length > 0) { assembly.ParsedInstructions.Add(new ParsedInstruction((byte)opcodeVal, operand.Trim().ToString(), iSourceLine)); } else { assembly.ParsedInstructions.Add(new ParsedInstruction((byte)opcodeVal, default(LiteralValue), iSourceLine)); } } else { assembly.ParsedInstructions.Add(new ParsedInstruction((byte)opcodeVal, default(LiteralValue), iSourceLine)); } return(true); }