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); }
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); }
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); }
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); } }
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)); } }
public static ZilObject TYPE([NotNull] Context ctx, [NotNull] ZilObject value) { return(value.GetTypeAtom(ctx)); }