Пример #1
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);
            }
        }
Пример #2
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);
            }
        }
Пример #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);
            }
        }
Пример #5
0
        internal static void FString(Tokenizer tokenizer, WordListBuilder wlbParent, StringType st = StringType.Forth)
        {
            var sbText       = new StringBuilder();
            var prependSpace = false;

            var done = false;

            // TODO: read tokenizer char by char to properly emulate white space
            while (!done)
            {
                var word = tokenizer.NextToken();

                if (word.EndsWith("\""))
                {
                    done = true;
                    word = word.Substring(0, word.Length - 1);
                }

                if (prependSpace)
                {
                    sbText.Append(" ");
                }

                prependSpace = true;
                sbText.Append(word);
            }

            var text       = sbText.ToString();
            int finalValue = -1;

            switch (st)
            {
            case StringType.Forth:
                var pCountedString = Memory.Allocate(text.Length * sizeof(char) + Session.StringLengthSize);
                Memory.StoreCString(pCountedString, text);
                finalValue = pCountedString;
                break;

            case StringType.DotNet:
                var index = SaveManagedObject(text);
                finalValue = index;
                break;

            case StringType.Type:
                var type = Type.GetType(text);
                if (type == null)
                {
                    throw new NfException($"Unrecognized .NET type in t\": {text}");
                }

                if (type.IsGenericType)
                {
                    var genericParameterCount = type.GetGenericArguments().Length;
                    var parmTypes             = CallAction.GetParmTypes($"Invalid types for generic type {text}", genericParameterCount);
                    type = type.MakeGenericType(parmTypes);
                }
                finalValue = SaveManagedObject(type);
                break;

            case StringType.Stack:
                var pStackString = Memory.AllocateStackString(text.Length);
                Memory.StoreString(pStackString, text);
                finalValue = pStackString;
                break;
            }
            if (wlbParent == null)
            {
                Stack.Push(finalValue);
                if (st == StringType.Stack)
                {
                    Stack.Push(text.Length);
                }
            }
            else
            {
                wlbParent.Add(new IntPrim(finalValue));
                if (st == StringType.Stack)
                {
                    wlbParent.Add(new IntPrim(text.Length));
                }
            }
        }