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 ParseDirective(ParseState state, QuipCompiler Compiler) { state.Advance(1); //skip opening '#'. var Command = ""; if (!IsWhitespace(state.Next())) ParseToken(out Command, state); if (String.IsNullOrEmpty(Command) || Command == "comment" || Command == "response" || Command == "nag") { var Text = ""; ParseRestOfLine(out Text, state); if (Command == "comment") Compiler.CommentDirective(Text); else if (Command == "response") Compiler.ResponseDirective(Text); else if (Command == "nag") Compiler.NagDirective(Text); else Compiler.BlankDirective(Text); } else if (Command == "follows") { var TokenList = new List<String>(); ParseList(TokenList, state); Compiler.FollowsDirective(TokenList); } else if (Command == "directly") { var TokenList = new List<String>(); ParseList(TokenList, state); Compiler.DirectlyDirective(TokenList); } else if (Command == "supplies") { var TokenList = new List<String>(); ParseList(TokenList, state); Compiler.SuppliesDirective(TokenList); } else if (Command == "unavailable") { var Text = ""; ParseRestOfLine(out Text, state); Text = Text.Trim(); if (!String.IsNullOrEmpty(Text)) Compiler.UnavailableDirective(Text); } else { throw new InvalidOperationException("Unknown directive: " + Command); } }
private static void ParseSuppliesBlock(ParseState state, QuipCompiler Compiler) { var token = ""; ParseToken(out token, state); //Skip the word 'follows'. var TokenList = new List<String>(); ParseList(TokenList, state); Compiler.BeginSuppliesBlock(TokenList); DevourWhitespace(state); if (state.Next() != '{') throw new InvalidOperationException("Expected {"); state.Advance(1); ParseLines(state, Compiler); }
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"); } }
public static void Parse(System.IO.StreamReader Stream, QuipCompiler Compiler) { var file = Stream.ReadToEnd(); var state = new ParseState { start = 0, end = file.Length, source = file, filename = "" }; ParseLines(state, Compiler); }
static void Main(string[] args) { String inFile = null; String outFile = null; int quipBase = 0; #region Parse switches if (args.Length == 0) { Help(); return; } for (var i = 0; i < args.Length; ++i) { if (args[i] == "-in") { if (i + 1 < args.Length) { inFile = args[i + 1]; ++i; } else { Help(); return; } } else if (args[i] == "-out") { if (i + 1 < args.Length) { outFile = args[i + 1]; ++i; } else { Help(); return; } } else if (args[i] == "-b") { if (i + 1 < args.Length) { quipBase = Int32.Parse(args[i + 1]); ++i; } else { Help(); return; } } else { if (inFile == null) inFile = args[i]; else if (outFile == null) outFile = args[i]; else { Help(); return; } } } #endregion var source = System.IO.File.OpenText(inFile); var Compiler = new QuipCompiler(quipBase); Parser.Parse(source, Compiler); source.Close(); var destination = System.IO.File.OpenWrite(outFile); Compiler.Emit(new System.IO.StreamWriter(destination)); destination.Flush(); destination.Close(); }