private Operand ParseOperand()
{
var t = tokens[pos];
var pointer = false;
if (t.Type == TokenType.OpenBracket)
{
pointer = true;
pos++;
}
try
{
var offset = false;
var offsetRegister = Register.R0;
if (tokens[pos].Type == TokenType.Register && tokens[pos + 1].Type == TokenType.Plus)
{
Enum.TryParse(tokens[pos].Value, true, out offsetRegister);
if (!pointer)
{
throw new AssemblerException(string.Format("Offset should only be used for pointers on line {0}", tokens[pos].Line));
}
if (offsetRegister > Register.RF)
{
throw new AssemblerException(string.Format("IP or SP used in offset on line {0}", tokens[pos].Line));
}
offset = true;
pos += 2;
}
t = tokens[pos++];
if (t.Type == TokenType.Register)
{
Register register;
Enum.TryParse(t.Value, true, out register);
return(Operand.FromRegister(register, pointer, offset, offsetRegister));
}
if (t.Type == TokenType.Word)
{
var prefix = "";
if (t.Value.StartsWith("."))
{
prefix = parentLabel;
}
return(Operand.FromLabel(prefix + t.Value, t.Line, pointer, offset, offsetRegister));
}
if (t.Type == TokenType.Number)
{
return(Operand.FromNumber(short.Parse(t.Value), pointer, offset, offsetRegister));
}
throw new AssemblerException(string.Format("Expected operand on line {0}", t.Line));
}
finally
{
if (pointer)
{
Require(TokenType.CloseBracket);
}
}
}