2016-11-30 14:17:05 +00:00
|
|
|
|
namespace SpriteCompiler.Problem
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
|
2016-11-30 22:07:22 +00:00
|
|
|
|
public sealed class Register : IEquatable<Register>
|
2016-11-30 14:17:05 +00:00
|
|
|
|
{
|
|
|
|
|
public static readonly Register UNINITIALIZED = new Register(0, DataType.UNINITIALIZED);
|
|
|
|
|
public static readonly Register INITIAL_OFFSET = new Register(0, DataType.SCREEN_OFFSET);
|
|
|
|
|
|
|
|
|
|
public enum DataType
|
|
|
|
|
{
|
|
|
|
|
UNINITIALIZED,
|
|
|
|
|
SCREEN_OFFSET,
|
|
|
|
|
LITERAL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Register(int value, DataType tag)
|
|
|
|
|
{
|
|
|
|
|
Value = value;
|
|
|
|
|
Tag = tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Register Clone()
|
|
|
|
|
{
|
|
|
|
|
return new Register(Value, Tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Register Add(int offset)
|
|
|
|
|
{
|
|
|
|
|
if (IsUninitialized)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("Cannot add value to uninitialized registers");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Adding a value does not change the tag
|
|
|
|
|
return new Register(Value + offset, Tag);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-05 05:14:51 +00:00
|
|
|
|
public static Register Constant(int value)
|
|
|
|
|
{
|
|
|
|
|
return new Register(value, DataType.LITERAL);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 14:17:05 +00:00
|
|
|
|
public Register LoadConstant(int value)
|
|
|
|
|
{
|
|
|
|
|
return new Register(value, DataType.LITERAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsUninitialized { get { return DataType.UNINITIALIZED.Equals(Tag); } }
|
|
|
|
|
public bool IsScreenOffset { get { return DataType.SCREEN_OFFSET.Equals(Tag); } }
|
|
|
|
|
public bool IsLiteral { get { return DataType.LITERAL.Equals(Tag); } }
|
|
|
|
|
|
|
|
|
|
public DataType Tag { get; private set; }
|
|
|
|
|
public int Value { get; private set; }
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2016-12-05 05:14:51 +00:00
|
|
|
|
switch (Tag)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case DataType.UNINITIALIZED:
|
|
|
|
|
return " ----";
|
|
|
|
|
|
|
|
|
|
case DataType.SCREEN_OFFSET:
|
|
|
|
|
return "*" + Value.ToString("X4");
|
|
|
|
|
|
|
|
|
|
case DataType.LITERAL:
|
|
|
|
|
return " " + Value.ToString("X4");
|
|
|
|
|
}
|
2016-11-30 14:17:05 +00:00
|
|
|
|
}
|
2016-11-30 22:07:22 +00:00
|
|
|
|
|
2016-12-06 03:55:04 +00:00
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
|
|
|
|
return Value.GetHashCode() + Tag.GetHashCode();
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-30 22:07:22 +00:00
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
|
{
|
|
|
|
|
return Equals(obj as Register);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Equals(Register other)
|
|
|
|
|
{
|
|
|
|
|
if (other == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Unititialized is equal to unititialized. Otherwise, compare the value, too.
|
|
|
|
|
return Tag.Equals(other.Tag) && (Tag.Equals(DataType.UNINITIALIZED) || Value == other.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool operator ==(Register reg1, Register reg2)
|
|
|
|
|
{
|
|
|
|
|
if (((object)reg1) == null || ((object)reg2) == null)
|
|
|
|
|
return Object.Equals(reg1, reg2);
|
|
|
|
|
|
|
|
|
|
return reg1.Equals(reg2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool operator !=(Register reg1, Register reg2)
|
|
|
|
|
{
|
|
|
|
|
if (((object)reg1) == null || ((object)reg2) == null)
|
|
|
|
|
return ! Object.Equals(reg1, reg2);
|
|
|
|
|
|
|
|
|
|
return ! (reg1.Equals(reg2));
|
|
|
|
|
}
|
2016-11-30 14:17:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|