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); } }