예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }