CiMacro ParseMacro()
{
CiMacro macro = new CiMacro();
macro.Name = ParseId();
Expect(CiToken.LeftParenthesis);
List<string> paramz = new List<string>();
if (See(CiToken.Id)) {
do {
string name = ParseId();
if (paramz.Contains(name))
throw new ParseException("Duplicate macro parameter {0}", name);
paramz.Add(name);
} while (Eat(CiToken.Comma));
}
Expect(CiToken.RightParenthesis);
macro.Params = paramz.ToArray();
StringBuilder sb = new StringBuilder();
this.CopyTo = sb;
try {
if (See(CiToken.LeftParenthesis)) {
sb.Append('(');
ParseBody(CiToken.LeftParenthesis, CiToken.RightParenthesis);
}
else if (See(CiToken.LeftBrace)) {
ParseBody(CiToken.LeftBrace, CiToken.RightBrace);
Trace.Assert(sb[sb.Length - 1] == '}');
sb.Length--;
macro.IsStatement = true;
}
else
throw new ParseException("Macro definition must be wrapped in parentheses or braces");
}
finally {
this.CopyTo = null;
}
macro.Body = sb.ToString();
NextToken();
return macro;
}