/// <exception cref="CompilerError">Malformed WORD-FLAGS-LIST.</exception> public void BuildLateSyntaxTables(BuildLateSyntaxTablesHelpers helpers) { var actionsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.ATBL)); var preactionsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.PATBL)); helpers.GetGlobal(ctx.GetStdAtom(StdAtom.ACTIONS)).DefaultValue = actionsTable; helpers.GetGlobal(ctx.GetStdAtom(StdAtom.PREACTIONS)).DefaultValue = preactionsTable; // word flag table if (ctx.GetCompilationFlagOption(StdAtom.WORD_FLAGS_IN_TABLE)) { var wordFlagsListObj = ctx.GetGlobalVal(ctx.GetStdAtom(StdAtom.WORD_FLAGS_LIST)) ?? new ZilList(null, null); if (!(wordFlagsListObj is ZilListoidBase wordFlagsList && wordFlagsList is ZilList)) { throw new CompilerError(CompilerMessages.GVAL_Of_0_Must_Be_1, "WORD-FLAGS-LIST", "a list"); } var wordFlagTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.WORD_FLAG_TABLE)); Debug.Assert(wordFlagTable != null); // WORD-FLAGS-LIST may contain duplicates: (W?FOO 96 W?BAR 1 W?FOO 32) // only the first appearance of each word will be kept var seen = new HashSet <ZilObject>(); var filtered = new List <IOperand>(); while (!wordFlagsList.IsEmpty) { if (!wordFlagsList.StartsWith(out ZilObject vword, out ZilObject flags)) { throw new CompilerError(CompilerMessages.WORDFLAGSLIST_Must_Have_An_Even_Number_Of_Elements); } if (!seen.Add(vword)) { continue; } var nw = NewParserWord.FromVword(ctx, (ZilHash)vword); var atom = nw.Atom; var word = ctx.ZEnvironment.Vocabulary[atom]; var zword = helpers.Vocabulary[word]; filtered.Add(zword); filtered.Add(helpers.CompileConstant(flags)); wordFlagsList = wordFlagsList.GetRest(2); Debug.Assert(wordFlagsList != null); } wordFlagTable.AddShort((short)filtered.Count); foreach (var operand in filtered) { wordFlagTable.AddShort(operand); } } }
public void BuildLateSyntaxTables(BuildLateSyntaxTablesHelpers helpers) { var prepositionsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.PRTBL)); var actionsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.ATBL)); var preactionsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.PATBL)); var verbsTable = (ITableBuilder)helpers.CompileConstant(ctx.GetStdAtom(StdAtom.VTBL)); Debug.Assert(prepositionsTable != null); Debug.Assert(actionsTable != null); Debug.Assert(preactionsTable != null); Debug.Assert(verbsTable != null); helpers.GetGlobal(ctx.GetStdAtom(StdAtom.PREPOSITIONS)).DefaultValue = prepositionsTable; helpers.GetGlobal(ctx.GetStdAtom(StdAtom.ACTIONS)).DefaultValue = actionsTable; helpers.GetGlobal(ctx.GetStdAtom(StdAtom.PREACTIONS)).DefaultValue = preactionsTable; helpers.GetGlobal(ctx.GetStdAtom(StdAtom.VERBS)).DefaultValue = verbsTable; // preposition table var compactVocab = ctx.GetGlobalOption(StdAtom.COMPACT_VOCABULARY_P); // map all relevant preposition word builders to the preposition ID constants var query = from pair in helpers.Vocabulary let word = pair.Key where IsPreposition(word) && (compactVocab || !IsSynonym(word)) let builder = pair.Value let prAtom = ZilAtom.Parse("PR?" + word.Atom.Text, ctx) let prConstant = helpers.CompileConstant(prAtom) let prepValue = GetPrepositionValue(word) group new { builder, prConstant } by prepValue into g let constant = g.First(w => w.prConstant != null).prConstant from prep in g select new { prep.builder, constant }; var prepositions = query.ToArray(); // build the table prepositionsTable.AddShort((short)prepositions.Length); foreach (var p in prepositions) { prepositionsTable.AddShort(p.builder); if (compactVocab) { prepositionsTable.AddByte(p.constant); } else { prepositionsTable.AddShort(p.constant); } } }