internal static void Definition(Tokenizer tokenizer) { var wlb = new WordListBuilder(); string currentDefWord = tokenizer.NextToken().ToLower(); Evaluable execute = null; while (true) { var word = tokenizer.NextToken().ToLower(); if (word == "does>") { execute = wlb.Realize(true, currentDefWord); wlb.Clear(); continue; } if (word == ";") { if (execute == null) { Vocabulary.CurrentVocabulary.AddDefinition(currentDefWord, wlb.Realize(true, currentDefWord)); } else { var run = wlb.Realize(true, currentDefWord); var compile = execute; Vocabulary.CurrentVocabulary.AddDefinition(currentDefWord, new DoesWord(compile, run)); } Session.LastDefinedWord = null; return; } var evaluable = Interpreter.ParseWord(word); if (evaluable == null) { // TODO: get more robust error handling throw new NfException($"Couldn't locate word {word}"); } if (evaluable.IsImmediate) { evaluable.Eval(tokenizer, wlb); continue; } wlb.Add(evaluable); } }
internal static void Begin(Tokenizer tokenizer, WordListBuilder wlbParent) { var wlbBegin = new WordListBuilder(); Evaluable evalCond = null; while (true) { var word = tokenizer.NextToken().ToLower(); switch (word) { case "again": wlbParent.Add(new BeginPrim(wlbBegin.Realize())); return; case "until": wlbParent.Add(new BeginPrim(wlbBegin.Realize(), true)); return; case "while": evalCond = wlbBegin.Realize(); wlbBegin.Clear(); continue; case "repeat" when evalCond == null: throw new NfException("\"begin...repeat\" with no while"); case "repeat": wlbParent.Add(new BeginPrim(wlbBegin.Realize(), false, evalCond)); return; } var evaluable = Interpreter.ParseWord(word); if (evaluable == null) { // TODO: get more robust error handling throw new NfException($"Couldn't locate word {word}"); } if (evaluable.IsImmediate) { // Only runs at compile time so no need to supply a parent here. evaluable.Eval(tokenizer, wlbBegin); continue; } wlbBegin.Add(evaluable); } }
internal static void Do(Tokenizer tokenizer, WordListBuilder wlbParent, bool isQuestDo) { var _wlbDo = new WordListBuilder(); while (true) { var word = tokenizer.NextToken().ToLower(); if (word == "loop") { wlbParent.Add(new DoPrim(_wlbDo.Realize(), false, isQuestDo)); return; } if (word == "+loop") { wlbParent.Add(new DoPrim(_wlbDo.Realize(), true, isQuestDo)); return; } var evaluable = Interpreter.ParseWord(word); if (evaluable == null) { // TODO: get more robust error handling throw new NfException($"Couldn't locate word {word}"); } if (evaluable.IsImmediate) { evaluable.Eval(tokenizer, _wlbDo); continue; } _wlbDo.Add(evaluable); } }
internal static void If(Tokenizer tokenizer, WordListBuilder wlbParent) { var wlbThenClause = new WordListBuilder(); var wlbElseClause = (WordListBuilder)null; while (true) { var word = tokenizer.NextToken().ToLower(); // ReSharper disable once SwitchStatementMissingSomeCases switch (word) { case "then": wlbParent.Add(new IfPrim(wlbThenClause.Realize(), wlbElseClause?.Realize())); return; case "else": wlbElseClause = wlbThenClause; wlbThenClause = new WordListBuilder(); continue; } var evaluable = Interpreter.ParseWord(word); if (evaluable == null) { // TODO: get more robust error handling throw new NfException($"Couldn't locate word {word}"); } if (evaluable.IsImmediate) { evaluable.Eval(tokenizer, wlbThenClause); continue; } wlbThenClause.Add(evaluable); } }