Пример #1
0
        public static bool IsApplicable([CanBeNull] this ZilObject zo, [NotNull] Context ctx)
        {
            if (zo == null)
            {
                return(false);
            }

            return(zo is IApplicable || ctx.GetApplyTypeDelegate(zo.GetTypeAtom(ctx)) != null);
        }
Пример #2
0
        public static IApplicable AsApplicable([CanBeNull] this ZilObject zo, [NotNull] Context ctx)
        {
            if (zo == null)
            {
                return(null);
            }

            var del = ctx.GetApplyTypeDelegate(zo.GetTypeAtom(ctx));

            if (del != null)
            {
                return(new ApplicableWrapper(zo, del));
            }

            return(zo as IApplicable);
        }
Пример #3
0
        public static ZilObject TYPE_P([NotNull] Context ctx, [NotNull] ZilObject value, [NotNull][Required] ZilAtom[] types)
        {
            var type = value.GetTypeAtom(ctx);

            foreach (var candidate in types)
            {
                if (candidate == type)
                {
                    return(candidate);
                }

                // Special case for LVAL/GVAL
                if (candidate.StdAtom == StdAtom.LVAL && value.IsLVAL(out _) ||
                    candidate.StdAtom == StdAtom.GVAL && value.IsGVAL(out _))
                {
                    return(candidate);
                }
            }

            return(ctx.FALSE);
        }
Пример #4
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);
            }
        }
Пример #5
0
        public static bool Check([NotNull] Context ctx, [NotNull] ZilObject value, [NotNull] ZilObject pattern,
                                 bool ignoreErrors = false)
        {
            switch (pattern)
            {
            case ZilAtom atom:
                // ReSharper disable once SwitchStatementMissingSomeCases
                switch (atom.StdAtom)
                {
                case StdAtom.ANY:
                    return(true);

                case StdAtom.APPLICABLE:
                    return(value.IsApplicable(ctx));

                case StdAtom.STRUCTURED:
                    return(value is IStructure);

                case StdAtom.TUPLE:
                    // special case
                    return(value.StdTypeAtom == StdAtom.LIST);

                default:
                    // arbitrary atoms can be type names...
                    if (ctx.IsRegisteredType(atom))
                    {
                        var typeAtom = value.GetTypeAtom(ctx);

                        if (typeAtom == atom)
                        {
                            return(true);
                        }

                        // special cases: a raw TABLE value can substitute for a TABLE-based type, or VECTOR
                        return(typeAtom.StdAtom == StdAtom.TABLE &&
                               (atom.StdAtom == StdAtom.VECTOR || ctx.GetTypePrim(atom) == PrimType.TABLE));
                    }

                    // ...or aliases
                    if (IsNonCircularAlias(ctx, atom, out var aliased))
                    {
                        return(Check(ctx, value, aliased, ignoreErrors));
                    }

                    // special cases for GVAL and LVAL
                    // ReSharper disable once SwitchStatementMissingSomeCases
                    switch (atom.StdAtom)
                    {
                    case StdAtom.GVAL:
                        return(value.IsGVAL(out _));

                    case StdAtom.LVAL:
                        return(value.IsLVAL(out _));

                    default:
                        return(ignoreErrors
                                        ? false
                                        : throw new InterpreterError(
                                   InterpreterMessages.Unrecognized_0_1,
                                   "atom in DECL pattern",
                                   atom));
                    }
                }

            case ZilSegment seg:
                return(CheckFormOrSegment(ctx, value, seg.Form, true, ignoreErrors));

            case ZilForm form:
                return(CheckFormOrSegment(ctx, value, form, false, ignoreErrors));

            default:
                if (ignoreErrors)
                {
                    return(false);
                }

                throw new InterpreterError(
                          InterpreterMessages.Unrecognized_0_1,
                          "value in DECL pattern",
                          pattern.ToStringContext(ctx, false));
            }
        }
Пример #6
0
 public static ZilObject TYPE([NotNull] Context ctx, [NotNull] ZilObject value)
 {
     return(value.GetTypeAtom(ctx));
 }