Пример #1
0
        void BuildLongWordTable([CanBeNull] ITableBuilder longWordTable, [CanBeNull][ItemNotNull] Queue <IWord> longWords)
        {
            if (longWords == null)
            {
                return;
            }

            Debug.Assert(longWordTable != null);

            longWordTable.AddShort((short)longWords.Count);
            while (longWords.Count > 0)
            {
                var word = longWords.Dequeue();
                var wb   = Vocabulary[word];
                longWordTable.AddShort(wb);
                longWordTable.AddShort(Game.MakeOperand(word.Atom.Text.ToLowerInvariant()));
            }
        }
Пример #2
0
        void BuildTable([NotNull] ZilTable zt, [NotNull] ITableBuilder tb)
        {
            if ((zt.Flags & TableFlags.Lexv) != 0)
            {
                var values = new IOperand[zt.ElementCount];
                zt.CopyTo(values, (zo, isWord) => CompileConstant(zo), Game.Zero, Context);

                tb.AddByte((byte)(zt.ElementCount / 3));
                tb.AddByte(0);

                for (int i = 0; i < values.Length; i++)
                {
                    if (i % 3 == 0)
                    {
                        tb.AddShort(values[i]);
                    }
                    else
                    {
                        tb.AddByte(values[i]);
                    }
                }
            }
            else
            {
                var values = new TableElementOperand?[zt.ElementCount];

                TableElementOperand?ConvertElement(ZilObject zo, bool isWord)
                {
                    // it's usually a constant value
                    var constVal = CompileConstant(zo);

                    if (constVal != null)
                    {
                        return(new TableElementOperand(constVal, isWord));
                    }

                    // but we'll also allow a global name if the global contains a table
                    if (zo is ZilAtom atom && Globals.TryGetValue(atom, out var global) && global.DefaultValue is ITableBuilder)
                    {
                        return(new TableElementOperand(global.DefaultValue, isWord));
                    }

                    return(null);
                }

                var defaultFiller = new TableElementOperand(Game.Zero, null);
                zt.CopyTo(values, ConvertElement, defaultFiller, Context);

                for (int i = 0; i < values.Length; i++)
                {
                    if (values[i] == null)
                    {
                        var rawElements = new ZilObject[zt.ElementCount];
                        zt.CopyTo(rawElements, (zo, isWord) => zo, null, Context);
                        Context.HandleError(new CompilerError(
                                                zt.SourceLine,
                                                CompilerMessages.Nonconstant_Initializer_For_0_1_2,
                                                "table element",
                                                i,
                                                rawElements[i]));
                        values[i] = defaultFiller;
                    }
                }

                bool defaultWord = (zt.Flags & TableFlags.Byte) == 0;

                for (int i = 0; i < values.Length; i++)
                {
                    Debug.Assert(values[i] != null);

                    if (values[i].Value.IsWord ?? defaultWord)
                    {
                        tb.AddShort(values[i].Value.Operand);
                    }
                    else
                    {
                        tb.AddByte(values[i].Value.Operand);
                    }
                }
            }
        }