Beispiel #1
0
        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));
            }
        }
Beispiel #2
0
 public ParsedInstruction(byte opcode, LiteralValue operandValue, int sourceLine)
 {
     this.opcode            = opcode;
     this.operandValue      = operandValue;
     this.operandExpression = null;
     this.sourceLine        = sourceLine;
 }
Beispiel #3
0
 public ParsedInstruction(byte opcode, string operandExpression, int sourceLine)
 {
     this.opcode            = opcode;
     this.operandValue      = new LiteralValue();
     this.operandExpression = operandExpression;
     this.sourceLine        = sourceLine;
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
     }
 }
Beispiel #6
0
            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;
            }
Beispiel #7
0
        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;
            }
        }
Beispiel #8
0
 public AsmValue(string expression)
 {
     Literal    = new LiteralValue();
     Expression = expression;
 }
Beispiel #9
0
 public AsmValue(LiteralValue value)
 {
     this.Literal = value;
     Expression   = null;
 }
Beispiel #10
0
 public PassValue(LiteralValue value, bool isFixed)
 {
     this.value   = value;
     this.isFixed = isFixed;
 }
Beispiel #11
0
        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);
        }