using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Sloth
{
public class MultipleLabelDefinitionsException : InterpreterException
{
public MultipleLabelDefinitionsException(String message, Int32 lineNumber) : base(message, lineNumber) { }
}
public class Preprocessor
{
public TokenList Output { get; private set; }
public Preprocessor()
{
this.
Output = new TokenList
();
}
public void Process(TokenList rawTokens)
{
Dictionary
<String, TokenList
> substitutions
= new Dictionary
<String, TokenList
>();
Int32 lineNumber = 1;
for (Int32 i = 0; i < rawTokens.Count - 2; i++)
{
if ((rawTokens[i].Type == TokenType.Label) &&
(rawTokens[i + 1].Type == TokenType.Identifier) &&
(rawTokens[i + 1].Lexeme.ToUpper() == "EQU"))
{
String label = rawTokens[i].Lexeme.TrimEnd(':');
if (substitutions.ContainsKey(label))
throw new MultipleLabelDefinitionsException
(String.
Format("La label '{0}' è stata definita più volte.", label
), lineNumber
);
TokenList substitution
= new TokenList
();
for (Int32 j = i + 2; (j < rawTokens.Count) && (rawTokens[j].Type != TokenType.NewLine); j++)
substitution.Add(rawTokens[j]);
substitutions.Add(label, substitution);
rawTokens.RemoveRange(i, substitution.Count + 2);
}
if (rawTokens[i].Type == TokenType.NewLine)
lineNumber++;
}
this.Output.Clear();
foreach(Token token in rawTokens)
if ((token.Type == TokenType.Identifier) &&
(substitutions.ContainsKey(token.Lexeme)))
this.Output.AddRange(substitutions[token.Lexeme]);
else
this.Output.Add(token);
}
}
}