private void Parse()
{
var t = tokens[pos];
while (t.Type != TokenType.EndOfFile)
{
if (t.Type == TokenType.Label)
{
var prefix = "";
if (t.Value.StartsWith("."))
{
if (parentLabel == null)
{
throw new AssemblerException(string.Format("Local label with no parent on line {0}", t.Line));
}
prefix = parentLabel;
}
else
{
if (t.Value.Contains("."))
{
throw new AssemblerException(string.Format("Period used in global label declaration on line {0}", t.Line));
}
parentLabel = t.Value;
}
var label = prefix + t.Value;
if (labels.ContainsKey(label))
{
throw new AssemblerException(string.Format("Duplicate label '{0}' on line {1}", label, t.Line));
}
labels.Add(label, new Label(label, instructions.Count));
pos++;
}
else if (t.Type == TokenType.Opcode)
{
instructions.Add(ParseInstruction());
}
else if (t.Type == TokenType.Word && t.Value.ToLower() == "dat")
{
t = tokens[++pos];
var data = new DataInstruction();
while (t.Type == TokenType.Number)
{
short value;
short.TryParse(t.Value, out value);
data.Add(value);
pos++;
if (tokens[pos].Type == TokenType.Comma)
{
t = tokens[++pos];
continue;
}
break;
}
instructions.Add(data);
}
else if (t.Type == TokenType.Word && t.Value.ToLower() == "resv")
{
t = tokens[++pos];
if (t.Type != TokenType.Number)
{
throw new AssemblerException(string.Format("Expected Number on line {0}", t.Line));
}
var data = new DataInstruction();
var count = short.Parse(t.Value);
for (var i = 0; i < count; i++)
{
data.Add(0);
}
pos++;
instructions.Add(data);
}
else
{
throw new AssemblerException(string.Format("Unexpected {0} on line {1}", t.Type, t.Line));
}
t = tokens[pos];
}
}