Пример #1
0
        public IOperand CompileConstant([NotNull] ZilObject expr, AmbiguousConstantMode mode)
        {
            switch (expr.Unwrap(Context))
            {
            case ZilFix fix:
                return(Game.MakeOperand(fix.Value));

            case ZilHash hash when hash.StdTypeAtom == StdAtom.BYTE && hash.GetPrimitive(Context) is ZilFix fix:
                return(Game.MakeOperand(fix.Value));

            case ZilWord word:
                return(CompileConstant(word.Value));

            case ZilString str:
                return(Game.MakeOperand(TranslateString(str, Context)));

            case ZilChar ch:
                return(Game.MakeOperand((byte)ch.Char));

            case ZilAtom atom:
                if (atom.StdAtom == StdAtom.T)
                {
                    return(Game.One);
                }
                if (Routines.TryGetValue(atom, out var routine))
                {
                    return(routine);
                }
                if (Objects.TryGetValue(atom, out var obj))
                {
                    return(obj);
                }
                if (Constants.TryGetValue(atom, out var operand))
                {
                    return(operand);
                }

                if (mode == AmbiguousConstantMode.Optimistic && Globals.TryGetValue(atom, out var global))
                {
                    Context.HandleError(new CompilerError((ISourceLine)null,
                                                          CompilerMessages.Bare_Atom_0_Interpreted_As_Global_Variable_Index, atom));
                    return(global);
                }
                return(null);

            case ZilFalse _:
                return(Game.Zero);

            case ZilTable table:
                if (Tables.TryGetValue(table, out var tb))
                {
                    return(tb);
                }

                tb = Game.DefineTable(table.Name, true);
                Tables.Add(table, tb);
                return(tb);

            case ZilConstant constant:
                return(CompileConstant(constant.Value));

            case ZilForm form:
                return(form.IsGVAL(out var globalAtom) ? CompileConstant(globalAtom, AmbiguousConstantMode.Pessimistic) : null);

            case ZilHash hash when hash.StdTypeAtom == StdAtom.VOC && hash.GetPrimitive(Context) is ZilAtom primAtom:
                var wordAtom = ZilAtom.Parse("W?" + primAtom.Text, Context);
                if (Constants.TryGetValue(wordAtom, out operand))
                {
                    return(operand);
                }
                return(null);

            default:
                var primitive = expr.GetPrimitive(Context);
                if (primitive != expr && primitive.GetTypeAtom(Context) != expr.GetTypeAtom(Context))
                {
                    return(CompileConstant(primitive));
                }
                return(null);
            }
        }