iigs-sprite-compiler/SpriteCompiler/Problem/Register.cs

108 lines
3.0 KiB
C#

namespace SpriteCompiler.Problem
{
using System;
public sealed class Register : IEquatable<Register>
{
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);
}
public static Register Constant(int value)
{
return new Register(value, DataType.LITERAL);
}
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()
{
switch (Tag)
{
default:
case DataType.UNINITIALIZED:
return " ----";
case DataType.SCREEN_OFFSET:
return "*" + Value.ToString("X4");
case DataType.LITERAL:
return " " + Value.ToString("X4");
}
}
public override int GetHashCode()
{
return Value.GetHashCode() + Tag.GetHashCode();
}
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));
}
}
}