blob: 99bcad757fcdc89d5c330ea95595a61e1699fdec [file] [log] [blame]
Sean Silva1b600182013-01-07 02:43:44 +00001===========================
2TableGen Language Reference
3===========================
4
Sean Silva1b600182013-01-07 02:43:44 +00005.. contents::
6 :local:
7
8.. warning::
9 This document is extremely rough. If you find something lacking, please
Tanya Lattner0d28f802015-08-05 03:51:17 +000010 fix it, file a documentation bug, or ask about it on llvm-dev.
Sean Silva1b600182013-01-07 02:43:44 +000011
12Introduction
13============
14
15This document is meant to be a normative spec about the TableGen language
16in and of itself (i.e. how to understand a given construct in terms of how
17it affects the final set of records represented by the TableGen file). If
18you are unsure if this document is really what you are looking for, please
Sean Silva397ee6e2014-04-07 22:46:40 +000019read the :doc:`introduction to TableGen <index>` first.
Sean Silva1b600182013-01-07 02:43:44 +000020
Renato Golin33f973a2014-04-01 09:51:49 +000021Notation
22========
Sean Silva1b600182013-01-07 02:43:44 +000023
Renato Golin33f973a2014-04-01 09:51:49 +000024The lexical and syntax notation used here is intended to imitate
25`Python's`_. In particular, for lexical definitions, the productions
26operate at the character level and there is no implied whitespace between
27elements. The syntax definitions operate at the token level, so there is
28implied whitespace between tokens.
Sean Silva1b600182013-01-07 02:43:44 +000029
Renato Golin33f973a2014-04-01 09:51:49 +000030.. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation
Sean Silva1b600182013-01-07 02:43:44 +000031
Renato Golin33f973a2014-04-01 09:51:49 +000032Lexical Analysis
33================
Sean Silva1b600182013-01-07 02:43:44 +000034
Renato Golin33f973a2014-04-01 09:51:49 +000035TableGen supports BCPL (``// ...``) and nestable C-style (``/* ... */``)
36comments.
Sean Silva1b600182013-01-07 02:43:44 +000037
Renato Golin33f973a2014-04-01 09:51:49 +000038The following is a listing of the basic punctuation tokens::
Sean Silva1b600182013-01-07 02:43:44 +000039
Renato Golin33f973a2014-04-01 09:51:49 +000040 - + [ ] { } ( ) < > : ; . = ? #
Sean Silva1b600182013-01-07 02:43:44 +000041
Renato Golin33f973a2014-04-01 09:51:49 +000042Numeric literals take one of the following forms:
Sean Silva1b600182013-01-07 02:43:44 +000043
Renato Golin33f973a2014-04-01 09:51:49 +000044.. TableGen actually will lex some pretty strange sequences an interpret
45 them as numbers. What is shown here is an attempt to approximate what it
46 "should" accept.
Sean Silva1b600182013-01-07 02:43:44 +000047
Renato Golin33f973a2014-04-01 09:51:49 +000048.. productionlist::
49 TokInteger: `DecimalInteger` | `HexInteger` | `BinInteger`
50 DecimalInteger: ["+" | "-"] ("0"..."9")+
51 HexInteger: "0x" ("0"..."9" | "a"..."f" | "A"..."F")+
52 BinInteger: "0b" ("0" | "1")+
Sean Silva1b600182013-01-07 02:43:44 +000053
Renato Golin33f973a2014-04-01 09:51:49 +000054One aspect to note is that the :token:`DecimalInteger` token *includes* the
55``+`` or ``-``, as opposed to having ``+`` and ``-`` be unary operators as
56most languages do.
Sean Silva1b600182013-01-07 02:43:44 +000057
Pete Cooper9b90dc72014-08-07 05:47:13 +000058Also note that :token:`BinInteger` creates a value of type ``bits<n>``
59(where ``n`` is the number of bits). This will implicitly convert to
60integers when needed.
61
Renato Golin33f973a2014-04-01 09:51:49 +000062TableGen has identifier-like tokens:
Sean Silva1b600182013-01-07 02:43:44 +000063
Renato Golin33f973a2014-04-01 09:51:49 +000064.. productionlist::
65 ualpha: "a"..."z" | "A"..."Z" | "_"
66 TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")*
67 TokVarName: "$" `ualpha` (`ualpha` | "0"..."9")*
Sean Silva1b600182013-01-07 02:43:44 +000068
Renato Golin33f973a2014-04-01 09:51:49 +000069Note that unlike most languages, TableGen allows :token:`TokIdentifier` to
70begin with a number. In case of ambiguity, a token will be interpreted as a
71numeric literal rather than an identifier.
Sean Silva1b600182013-01-07 02:43:44 +000072
Renato Golin33f973a2014-04-01 09:51:49 +000073TableGen also has two string-like literals:
Sean Silva1b600182013-01-07 02:43:44 +000074
Renato Golin33f973a2014-04-01 09:51:49 +000075.. productionlist::
76 TokString: '"' <non-'"' characters and C-like escapes> '"'
77 TokCodeFragment: "[{" <shortest text not containing "}]"> "}]"
Sean Silva1b600182013-01-07 02:43:44 +000078
Renato Golin33f973a2014-04-01 09:51:49 +000079:token:`TokCodeFragment` is essentially a multiline string literal
80delimited by ``[{`` and ``}]``.
Sean Silvacc373352014-02-09 02:43:50 +000081
Renato Golin33f973a2014-04-01 09:51:49 +000082.. note::
83 The current implementation accepts the following C-like escapes::
Sean Silva543fd7f2013-01-09 02:20:30 +000084
Renato Golin33f973a2014-04-01 09:51:49 +000085 \\ \' \" \t \n
Sean Silva543fd7f2013-01-09 02:20:30 +000086
Renato Golin33f973a2014-04-01 09:51:49 +000087TableGen also has the following keywords::
Sean Silva1b600182013-01-07 02:43:44 +000088
Renato Golin33f973a2014-04-01 09:51:49 +000089 bit bits class code dag
90 def foreach defm field in
91 int let list multiclass string
Sean Silva1b600182013-01-07 02:43:44 +000092
Renato Golin33f973a2014-04-01 09:51:49 +000093TableGen also has "bang operators" which have a
94wide variety of meanings:
Sean Silva1b600182013-01-07 02:43:44 +000095
Renato Golin33f973a2014-04-01 09:51:49 +000096.. productionlist::
97 BangOperator: one of
98 :!eq !if !head !tail !con
Joerg Sonnenberger0a537272014-09-03 13:17:03 +000099 :!add !shl !sra !srl !and
Matt Arsenault1c8d9332016-11-15 06:49:28 +0000100 :!or !empty !subst !foreach !strconcat
Nicolai Haehnled34f6842018-03-06 13:49:16 +0000101 :!cast !listconcat !size !foldl
Nicolai Haehnleb5376052018-03-09 12:24:06 +0000102 :!isa
Matt Arsenault1c8d9332016-11-15 06:49:28 +0000103
Sean Silva1b600182013-01-07 02:43:44 +0000104
Renato Golin33f973a2014-04-01 09:51:49 +0000105Syntax
106======
Sean Silva1b600182013-01-07 02:43:44 +0000107
Renato Golin33f973a2014-04-01 09:51:49 +0000108TableGen has an ``include`` mechanism. It does not play a role in the
109syntax per se, since it is lexically replaced with the contents of the
110included file.
Sean Silva1b600182013-01-07 02:43:44 +0000111
Renato Golin33f973a2014-04-01 09:51:49 +0000112.. productionlist::
113 IncludeDirective: "include" `TokString`
Sean Silva1b600182013-01-07 02:43:44 +0000114
Renato Golin33f973a2014-04-01 09:51:49 +0000115TableGen's top-level production consists of "objects".
Sean Silva1b600182013-01-07 02:43:44 +0000116
Renato Golin33f973a2014-04-01 09:51:49 +0000117.. productionlist::
118 TableGenFile: `Object`*
Nicolai Haehnlefcd65252018-03-09 12:24:42 +0000119 Object: `Class` | `Def` | `Defm` | `Defset` | `Let` | `MultiClass` |
120 `Foreach`
Sean Silva1b600182013-01-07 02:43:44 +0000121
Renato Golin33f973a2014-04-01 09:51:49 +0000122``class``\es
123------------
Sean Silva1b600182013-01-07 02:43:44 +0000124
Renato Golin33f973a2014-04-01 09:51:49 +0000125.. productionlist::
126 Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000127
Renato Golin33f973a2014-04-01 09:51:49 +0000128A ``class`` declaration creates a record which other records can inherit
129from. A class can be parametrized by a list of "template arguments", whose
130values can be used in the class body.
Sean Silva1b600182013-01-07 02:43:44 +0000131
Renato Golin33f973a2014-04-01 09:51:49 +0000132A given class can only be defined once. A ``class`` declaration is
133considered to define the class if any of the following is true:
Sean Silva1b600182013-01-07 02:43:44 +0000134
Renato Golin33f973a2014-04-01 09:51:49 +0000135.. break ObjectBody into its consituents so that they are present here?
Sean Silva1b600182013-01-07 02:43:44 +0000136
Renato Golin33f973a2014-04-01 09:51:49 +0000137#. The :token:`TemplateArgList` is present.
138#. The :token:`Body` in the :token:`ObjectBody` is present and is not empty.
139#. The :token:`BaseClassList` in the :token:`ObjectBody` is present.
Sean Silva1b600182013-01-07 02:43:44 +0000140
Renato Golin33f973a2014-04-01 09:51:49 +0000141You can declare an empty class by giving and empty :token:`TemplateArgList`
142and an empty :token:`ObjectBody`. This can serve as a restricted form of
143forward declaration: note that records deriving from the forward-declared
144class will inherit no fields from it since the record expansion is done
145when the record is parsed.
Sean Silva1b600182013-01-07 02:43:44 +0000146
Renato Golin33f973a2014-04-01 09:51:49 +0000147.. productionlist::
148 TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">"
Sean Silva1b600182013-01-07 02:43:44 +0000149
Renato Golin33f973a2014-04-01 09:51:49 +0000150Declarations
151------------
Sean Silva1b600182013-01-07 02:43:44 +0000152
Renato Golin33f973a2014-04-01 09:51:49 +0000153.. Omitting mention of arcane "field" prefix to discourage its use.
Sean Silva1b600182013-01-07 02:43:44 +0000154
Renato Golin33f973a2014-04-01 09:51:49 +0000155The declaration syntax is pretty much what you would expect as a C++
156programmer.
Sean Silva1b600182013-01-07 02:43:44 +0000157
Renato Golin33f973a2014-04-01 09:51:49 +0000158.. productionlist::
159 Declaration: `Type` `TokIdentifier` ["=" `Value`]
Sean Silva1b600182013-01-07 02:43:44 +0000160
Sylvestre Ledru7d540502016-07-02 19:28:40 +0000161It assigns the value to the identifier.
Sean Silva1b600182013-01-07 02:43:44 +0000162
Renato Golin33f973a2014-04-01 09:51:49 +0000163Types
164-----
Sean Silva1b600182013-01-07 02:43:44 +0000165
Renato Golin33f973a2014-04-01 09:51:49 +0000166.. productionlist::
167 Type: "string" | "code" | "bit" | "int" | "dag"
168 :| "bits" "<" `TokInteger` ">"
169 :| "list" "<" `Type` ">"
170 :| `ClassID`
171 ClassID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000172
Renato Golin33f973a2014-04-01 09:51:49 +0000173Both ``string`` and ``code`` correspond to the string type; the difference
174is purely to indicate programmer intention.
Renato Golinca105642014-03-20 16:08:34 +0000175
Renato Golin33f973a2014-04-01 09:51:49 +0000176The :token:`ClassID` must identify a class that has been previously
177declared or defined.
Renato Golinca105642014-03-20 16:08:34 +0000178
Renato Golin33f973a2014-04-01 09:51:49 +0000179Values
180------
Renato Golinca105642014-03-20 16:08:34 +0000181
Renato Golin33f973a2014-04-01 09:51:49 +0000182.. productionlist::
183 Value: `SimpleValue` `ValueSuffix`*
184 ValueSuffix: "{" `RangeList` "}"
185 :| "[" `RangeList` "]"
186 :| "." `TokIdentifier`
187 RangeList: `RangePiece` ("," `RangePiece`)*
188 RangePiece: `TokInteger`
189 :| `TokInteger` "-" `TokInteger`
190 :| `TokInteger` `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000191
Renato Golin33f973a2014-04-01 09:51:49 +0000192The peculiar last form of :token:`RangePiece` is due to the fact that the
193"``-``" is included in the :token:`TokInteger`, hence ``1-5`` gets lexed as
194two consecutive :token:`TokInteger`'s, with values ``1`` and ``-5``,
195instead of "1", "-", and "5".
196The :token:`RangeList` can be thought of as specifying "list slice" in some
197contexts.
Renato Golinca105642014-03-20 16:08:34 +0000198
Renato Golinca105642014-03-20 16:08:34 +0000199
Renato Golin33f973a2014-04-01 09:51:49 +0000200:token:`SimpleValue` has a number of forms:
Renato Golinca105642014-03-20 16:08:34 +0000201
Renato Golinca105642014-03-20 16:08:34 +0000202
Renato Golin33f973a2014-04-01 09:51:49 +0000203.. productionlist::
204 SimpleValue: `TokIdentifier`
Renato Golinca105642014-03-20 16:08:34 +0000205
Renato Golin33f973a2014-04-01 09:51:49 +0000206The value will be the variable referenced by the identifier. It can be one
207of:
Renato Golinca105642014-03-20 16:08:34 +0000208
Renato Golin33f973a2014-04-01 09:51:49 +0000209.. The code for this is exceptionally abstruse. These examples are a
210 best-effort attempt.
Renato Golinca105642014-03-20 16:08:34 +0000211
Renato Golin33f973a2014-04-01 09:51:49 +0000212* name of a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000213
Renato Golin33f973a2014-04-01 09:51:49 +0000214 def Bar : SomeClass {
215 int X = 5;
216 }
Renato Golinca105642014-03-20 16:08:34 +0000217
Renato Golin33f973a2014-04-01 09:51:49 +0000218 def Foo {
219 SomeClass Baz = Bar;
220 }
Renato Golinca105642014-03-20 16:08:34 +0000221
Renato Golin33f973a2014-04-01 09:51:49 +0000222* value local to a ``def``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000223
Renato Golin33f973a2014-04-01 09:51:49 +0000224 def Foo {
225 int Bar = 5;
226 int Baz = Bar;
227 }
Renato Golinca105642014-03-20 16:08:34 +0000228
Renato Golin33f973a2014-04-01 09:51:49 +0000229* a template arg of a ``class``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000230
Renato Golin33f973a2014-04-01 09:51:49 +0000231 class Foo<int Bar> {
232 int Baz = Bar;
233 }
Renato Golinca105642014-03-20 16:08:34 +0000234
Renato Golin33f973a2014-04-01 09:51:49 +0000235* value local to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000236
Renato Golin33f973a2014-04-01 09:51:49 +0000237 multiclass Foo {
238 int Bar = 5;
239 int Baz = Bar;
240 }
Renato Golinca105642014-03-20 16:08:34 +0000241
Renato Golin33f973a2014-04-01 09:51:49 +0000242* a template arg to a ``multiclass``, such as the use of ``Bar`` in::
Renato Golinca105642014-03-20 16:08:34 +0000243
Renato Golin33f973a2014-04-01 09:51:49 +0000244 multiclass Foo<int Bar> {
245 int Baz = Bar;
246 }
Renato Golinca105642014-03-20 16:08:34 +0000247
Renato Golin33f973a2014-04-01 09:51:49 +0000248.. productionlist::
249 SimpleValue: `TokInteger`
Renato Golinca105642014-03-20 16:08:34 +0000250
Renato Golin33f973a2014-04-01 09:51:49 +0000251This represents the numeric value of the integer.
Renato Golinca105642014-03-20 16:08:34 +0000252
Renato Golin33f973a2014-04-01 09:51:49 +0000253.. productionlist::
254 SimpleValue: `TokString`+
Renato Golinca105642014-03-20 16:08:34 +0000255
Renato Golin33f973a2014-04-01 09:51:49 +0000256Multiple adjacent string literals are concatenated like in C/C++. The value
257is the concatenation of the strings.
Renato Golinca105642014-03-20 16:08:34 +0000258
Renato Golin33f973a2014-04-01 09:51:49 +0000259.. productionlist::
260 SimpleValue: `TokCodeFragment`
Renato Golinca105642014-03-20 16:08:34 +0000261
Renato Golin33f973a2014-04-01 09:51:49 +0000262The value is the string value of the code fragment.
Renato Golinca105642014-03-20 16:08:34 +0000263
Renato Golin33f973a2014-04-01 09:51:49 +0000264.. productionlist::
265 SimpleValue: "?"
Renato Golinca105642014-03-20 16:08:34 +0000266
Renato Golin33f973a2014-04-01 09:51:49 +0000267``?`` represents an "unset" initializer.
Sean Silva1b600182013-01-07 02:43:44 +0000268
Renato Golin33f973a2014-04-01 09:51:49 +0000269.. productionlist::
270 SimpleValue: "{" `ValueList` "}"
271 ValueList: [`ValueListNE`]
272 ValueListNE: `Value` ("," `Value`)*
Sean Silva1b600182013-01-07 02:43:44 +0000273
Renato Golin33f973a2014-04-01 09:51:49 +0000274This represents a sequence of bits, as would be used to initialize a
275``bits<n>`` field (where ``n`` is the number of bits).
Sean Silva1b600182013-01-07 02:43:44 +0000276
Renato Golin33f973a2014-04-01 09:51:49 +0000277.. productionlist::
278 SimpleValue: `ClassID` "<" `ValueListNE` ">"
Sean Silva1b600182013-01-07 02:43:44 +0000279
Renato Golin33f973a2014-04-01 09:51:49 +0000280This generates a new anonymous record definition (as would be created by an
281unnamed ``def`` inheriting from the given class with the given template
282arguments) and the value is the value of that record definition.
Sean Silva1b600182013-01-07 02:43:44 +0000283
Renato Golin33f973a2014-04-01 09:51:49 +0000284.. productionlist::
285 SimpleValue: "[" `ValueList` "]" ["<" `Type` ">"]
Sean Silva1b600182013-01-07 02:43:44 +0000286
Renato Golin33f973a2014-04-01 09:51:49 +0000287A list initializer. The optional :token:`Type` can be used to indicate a
288specific element type, otherwise the element type will be deduced from the
289given values.
Sean Silva1b600182013-01-07 02:43:44 +0000290
Renato Golin33f973a2014-04-01 09:51:49 +0000291.. The initial `DagArg` of the dag must start with an identifier or
292 !cast, but this is more of an implementation detail and so for now just
293 leave it out.
Sean Silva1b600182013-01-07 02:43:44 +0000294
Renato Golin33f973a2014-04-01 09:51:49 +0000295.. productionlist::
296 SimpleValue: "(" `DagArg` `DagArgList` ")"
297 DagArgList: `DagArg` ("," `DagArg`)*
298 DagArg: `Value` [":" `TokVarName`] | `TokVarName`
Sean Silva1b600182013-01-07 02:43:44 +0000299
Renato Golin33f973a2014-04-01 09:51:49 +0000300The initial :token:`DagArg` is called the "operator" of the dag.
Sean Silva1b600182013-01-07 02:43:44 +0000301
Renato Golin33f973a2014-04-01 09:51:49 +0000302.. productionlist::
303 SimpleValue: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")"
Sean Silva1b600182013-01-07 02:43:44 +0000304
Renato Golin33f973a2014-04-01 09:51:49 +0000305Bodies
306------
Sean Silva1b600182013-01-07 02:43:44 +0000307
Renato Golin33f973a2014-04-01 09:51:49 +0000308.. productionlist::
309 ObjectBody: `BaseClassList` `Body`
310 BaseClassList: [":" `BaseClassListNE`]
311 BaseClassListNE: `SubClassRef` ("," `SubClassRef`)*
312 SubClassRef: (`ClassID` | `MultiClassID`) ["<" `ValueList` ">"]
313 DefmID: `TokIdentifier`
Sean Silva1b600182013-01-07 02:43:44 +0000314
Renato Golin33f973a2014-04-01 09:51:49 +0000315The version with the :token:`MultiClassID` is only valid in the
316:token:`BaseClassList` of a ``defm``.
317The :token:`MultiClassID` should be the name of a ``multiclass``.
Sean Silva1b600182013-01-07 02:43:44 +0000318
Renato Golin33f973a2014-04-01 09:51:49 +0000319.. put this somewhere else
Sean Silva1b600182013-01-07 02:43:44 +0000320
Renato Golin33f973a2014-04-01 09:51:49 +0000321It is after parsing the base class list that the "let stack" is applied.
Sean Silva1b600182013-01-07 02:43:44 +0000322
Renato Golin33f973a2014-04-01 09:51:49 +0000323.. productionlist::
324 Body: ";" | "{" BodyList "}"
325 BodyList: BodyItem*
326 BodyItem: `Declaration` ";"
327 :| "let" `TokIdentifier` [`RangeList`] "=" `Value` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000328
Renato Golin33f973a2014-04-01 09:51:49 +0000329The ``let`` form allows overriding the value of an inherited field.
Sean Silva1b600182013-01-07 02:43:44 +0000330
Renato Golin33f973a2014-04-01 09:51:49 +0000331``def``
332-------
Sean Silva1b600182013-01-07 02:43:44 +0000333
Renato Golin33f973a2014-04-01 09:51:49 +0000334.. TODO::
335 There can be pastes in the names here, like ``#NAME#``. Look into that
336 and document it (it boils down to ParseIDValue with IDParseMode ==
337 ParseNameMode). ParseObjectName calls into the general ParseValue, with
338 the only different from "arbitrary expression parsing" being IDParseMode
339 == Mode.
Sean Silva1b600182013-01-07 02:43:44 +0000340
Renato Golin33f973a2014-04-01 09:51:49 +0000341.. productionlist::
342 Def: "def" `TokIdentifier` `ObjectBody`
Sean Silva1b600182013-01-07 02:43:44 +0000343
Renato Golin33f973a2014-04-01 09:51:49 +0000344Defines a record whose name is given by the :token:`TokIdentifier`. The
345fields of the record are inherited from the base classes and defined in the
346body.
Sean Silva1b600182013-01-07 02:43:44 +0000347
Renato Golin33f973a2014-04-01 09:51:49 +0000348Special handling occurs if this ``def`` appears inside a ``multiclass`` or
349a ``foreach``.
Sean Silva1b600182013-01-07 02:43:44 +0000350
Renato Golin33f973a2014-04-01 09:51:49 +0000351``defm``
352--------
Sean Silva1b600182013-01-07 02:43:44 +0000353
Renato Golin33f973a2014-04-01 09:51:49 +0000354.. productionlist::
355 Defm: "defm" `TokIdentifier` ":" `BaseClassListNE` ";"
Sean Silva1b600182013-01-07 02:43:44 +0000356
Renato Golin33f973a2014-04-01 09:51:49 +0000357Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must
358precede any ``class``'s that appear.
Sean Silva1b600182013-01-07 02:43:44 +0000359
Nicolai Haehnlefcd65252018-03-09 12:24:42 +0000360``defset``
361----------
362.. productionlist::
363 Defset: "defset" `Type` `TokIdentifier` "=" "{" `Object`* "}"
364
365All records defined inside the braces via ``def`` and ``defm`` are collected
366in a globally accessible list of the given name (in addition to being added
367to the global collection of records as usual). Anonymous records created inside
368initializier expressions using the ``Class<args...>`` syntax are never collected
369in a defset.
370
371The given type must be ``list<A>``, where ``A`` is some class. It is an error
372to define a record (via ``def`` or ``defm``) inside the braces which doesn't
373derive from ``A``.
374
Renato Golin33f973a2014-04-01 09:51:49 +0000375``foreach``
376-----------
Sean Silva1b600182013-01-07 02:43:44 +0000377
Renato Golin33f973a2014-04-01 09:51:49 +0000378.. productionlist::
Nicolai Haehnle8aa9d582018-03-09 12:24:30 +0000379 Foreach: "foreach" `ForeachDeclaration` "in" "{" `Object`* "}"
380 :| "foreach" `ForeachDeclaration` "in" `Object`
381 ForeachDeclaration: ID "=" ( "{" `RangeList` "}" | `RangePiece` | `Value` )
Sean Silva1b600182013-01-07 02:43:44 +0000382
Renato Golin33f973a2014-04-01 09:51:49 +0000383The value assigned to the variable in the declaration is iterated over and
384the object or object list is reevaluated with the variable set at each
385iterated value.
Sean Silva1b600182013-01-07 02:43:44 +0000386
Nicolai Haehnle8aa9d582018-03-09 12:24:30 +0000387Note that the productions involving RangeList and RangePiece have precedence
388over the more generic value parsing based on the first token.
389
Renato Golin33f973a2014-04-01 09:51:49 +0000390Top-Level ``let``
391-----------------
Sean Silva1b600182013-01-07 02:43:44 +0000392
Renato Golin33f973a2014-04-01 09:51:49 +0000393.. productionlist::
394 Let: "let" `LetList` "in" "{" `Object`* "}"
395 :| "let" `LetList` "in" `Object`
396 LetList: `LetItem` ("," `LetItem`)*
397 LetItem: `TokIdentifier` [`RangeList`] "=" `Value`
Sean Silva1b600182013-01-07 02:43:44 +0000398
Renato Golin33f973a2014-04-01 09:51:49 +0000399This is effectively equivalent to ``let`` inside the body of a record
400except that it applies to multiple records at a time. The bindings are
401applied at the end of parsing the base classes of a record.
Sean Silva1b600182013-01-07 02:43:44 +0000402
Renato Golin33f973a2014-04-01 09:51:49 +0000403``multiclass``
404--------------
Sean Silva1b600182013-01-07 02:43:44 +0000405
Renato Golin33f973a2014-04-01 09:51:49 +0000406.. productionlist::
407 MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`]
408 : [":" `BaseMultiClassList`] "{" `MultiClassObject`+ "}"
409 BaseMultiClassList: `MultiClassID` ("," `MultiClassID`)*
410 MultiClassID: `TokIdentifier`
411 MultiClassObject: `Def` | `Defm` | `Let` | `Foreach`