private static void ParseDeclaration(ParseState state, QuipCompiler Compiler) { var Type = QuipType.Questioning; bool Repeatable = false; bool Restrictive = false; while (!state.AtEnd() && (state.Next() == '@' || state.Next() == '+' || state.Next() == '?' || state.Next() == '*')) { if (state.Next() == '+') Repeatable = true; if (state.Next() == '?') Restrictive = true; if (state.Next() == '*') Type = QuipType.NpcDirected; state.Advance(1); } var ID = ""; var Name = ""; if (!IsWhitespace(state.Next())) ParseToken(out ID, state); ParseRestOfLine(out Name, state); Name = Name.Trim(); if (String.IsNullOrEmpty(Name)) throw new InvalidOperationException("Quip declared with no name"); if (Type != QuipType.NpcDirected) { var lastChar = Name[Name.Length - 1]; if (lastChar == '?') { Name = Name.Substring(0, Name.Length - 1); Type = QuipType.Questioning; } else if (lastChar == '.') { Name = Name.Substring(0, Name.Length - 1); Type = QuipType.Informative; } else if (lastChar == '!') { Name = Name.Substring(0, Name.Length - 1); Type = QuipType.Performative; } else if (lastChar == '$') { Name = Name.Substring(0, Name.Length - 1); Type = QuipType.NpcDirected; } } Compiler.BeginQuip(ID, Name, Type, Repeatable, Restrictive); }
private static void DevourWhitespace(ParseState state) { while (!state.AtEnd() && " \t\r\n".Contains(state.Next())) state.Advance(); }
private static void ParseList(List<String> into, ParseState state) { DevourSpaces(state); while (!state.AtEnd() && state.Next() != '\r' && state.Next() != '\n' && state.Next() != '{' && state.Next() != '}') { var token = ""; ParseToken(out token, state); into.Add(token); DevourSpaces(state); } }
private static void DevourSpaces(ParseState state) { while (!state.AtEnd() && " \t".Contains(state.Next())) state.Advance(); }
private static void ParseLines(ParseState state, QuipCompiler Compiler) { while (true) { DevourWhitespace(state); if (state.AtEnd()) return; if (state.Next() == '}') { Compiler.EndBlock(); state.Advance(1); return; } if (state.Next() == '@' || state.Next() == '+' || state.Next() == '?' || state.Next() == '*') ParseDeclaration(state, Compiler); else if (state.Next() == '#') ParseDirective(state, Compiler); else if (state.MatchNext("follows")) ParseFollowsBlock(state, Compiler); else if (state.MatchNext("supplies")) ParseSuppliesBlock(state, Compiler); else if (state.MatchNext("directly")) ParseDirectlyBlock(state, Compiler); else if (state.MatchNext("//")) ParseComment(state); else throw new InvalidOperationException("Unknown line type"); } }