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); } }