| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 1 | =========================== | 
|  | 2 | TableGen Language Reference | 
|  | 3 | =========================== | 
|  | 4 |  | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 5 | .. contents:: | 
|  | 6 | :local: | 
|  | 7 |  | 
|  | 8 | .. warning:: | 
|  | 9 | This document is extremely rough. If you find something lacking, please | 
| Tanya Lattner | 0d28f80 | 2015-08-05 03:51:17 +0000 | [diff] [blame] | 10 | fix it, file a documentation bug, or ask about it on llvm-dev. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 11 |  | 
|  | 12 | Introduction | 
|  | 13 | ============ | 
|  | 14 |  | 
|  | 15 | This document is meant to be a normative spec about the TableGen language | 
|  | 16 | in and of itself (i.e. how to understand a given construct in terms of how | 
|  | 17 | it affects the final set of records represented by the TableGen file). If | 
|  | 18 | you are unsure if this document is really what you are looking for, please | 
| Sean Silva | 397ee6e | 2014-04-07 22:46:40 +0000 | [diff] [blame] | 19 | read the :doc:`introduction to TableGen <index>` first. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 20 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 21 | Notation | 
|  | 22 | ======== | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 23 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 24 | The lexical and syntax notation used here is intended to imitate | 
|  | 25 | `Python's`_. In particular, for lexical definitions, the productions | 
|  | 26 | operate at the character level and there is no implied whitespace between | 
|  | 27 | elements. The syntax definitions operate at the token level, so there is | 
|  | 28 | implied whitespace between tokens. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 29 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 30 | .. _`Python's`: http://docs.python.org/py3k/reference/introduction.html#notation | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 31 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 32 | Lexical Analysis | 
|  | 33 | ================ | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 34 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 35 | TableGen supports BCPL (``// ...``) and nestable C-style (``/* ... */``) | 
|  | 36 | comments. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 37 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 38 | The following is a listing of the basic punctuation tokens:: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 39 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 40 | - + [ ] { } ( ) < > : ; .  = ? # | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 41 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 42 | Numeric literals take one of the following forms: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 43 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 44 | .. 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 Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 47 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 48 | .. 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 Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 53 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 54 | One aspect to note is that the :token:`DecimalInteger` token *includes* the | 
|  | 55 | ``+`` or ``-``, as opposed to having ``+`` and ``-`` be unary operators as | 
|  | 56 | most languages do. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 57 |  | 
| Pete Cooper | 9b90dc7 | 2014-08-07 05:47:13 +0000 | [diff] [blame] | 58 | Also note that :token:`BinInteger` creates a value of type ``bits<n>`` | 
|  | 59 | (where ``n`` is the number of bits).  This will implicitly convert to | 
|  | 60 | integers when needed. | 
|  | 61 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 62 | TableGen has identifier-like tokens: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 63 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 64 | .. productionlist:: | 
|  | 65 | ualpha: "a"..."z" | "A"..."Z" | "_" | 
|  | 66 | TokIdentifier: ("0"..."9")* `ualpha` (`ualpha` | "0"..."9")* | 
|  | 67 | TokVarName: "$" `ualpha` (`ualpha` |  "0"..."9")* | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 68 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 69 | Note that unlike most languages, TableGen allows :token:`TokIdentifier` to | 
|  | 70 | begin with a number. In case of ambiguity, a token will be interpreted as a | 
|  | 71 | numeric literal rather than an identifier. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 72 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 73 | TableGen also has two string-like literals: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 74 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 75 | .. productionlist:: | 
|  | 76 | TokString: '"' <non-'"' characters and C-like escapes> '"' | 
|  | 77 | TokCodeFragment: "[{" <shortest text not containing "}]"> "}]" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 78 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 79 | :token:`TokCodeFragment` is essentially a multiline string literal | 
|  | 80 | delimited by ``[{`` and ``}]``. | 
| Sean Silva | cc37335 | 2014-02-09 02:43:50 +0000 | [diff] [blame] | 81 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 82 | .. note:: | 
|  | 83 | The current implementation accepts the following C-like escapes:: | 
| Sean Silva | 543fd7f | 2013-01-09 02:20:30 +0000 | [diff] [blame] | 84 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 85 | \\ \' \" \t \n | 
| Sean Silva | 543fd7f | 2013-01-09 02:20:30 +0000 | [diff] [blame] | 86 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 87 | TableGen also has the following keywords:: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 88 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 89 | bit   bits      class   code         dag | 
|  | 90 | def   foreach   defm    field        in | 
|  | 91 | int   let       list    multiclass   string | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 92 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 93 | TableGen also has "bang operators" which have a | 
|  | 94 | wide variety of meanings: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 95 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 96 | .. productionlist:: | 
|  | 97 | BangOperator: one of | 
|  | 98 | :!eq     !if      !head    !tail      !con | 
| Joerg Sonnenberger | 0a53727 | 2014-09-03 13:17:03 +0000 | [diff] [blame] | 99 | :!add    !shl     !sra     !srl       !and | 
| Matt Arsenault | 1c8d933 | 2016-11-15 06:49:28 +0000 | [diff] [blame] | 100 | :!or     !empty   !subst   !foreach   !strconcat | 
| Nicolai Haehnle | d34f684 | 2018-03-06 13:49:16 +0000 | [diff] [blame] | 101 | :!cast   !listconcat       !size      !foldl | 
| Nicolai Haehnle | aa9ca69 | 2018-03-14 11:00:57 +0000 | [diff] [blame] | 102 | :!isa    !dag     !le      !lt        !ge | 
|  | 103 | :!gt     !ne | 
| Matt Arsenault | 1c8d933 | 2016-11-15 06:49:28 +0000 | [diff] [blame] | 104 |  | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 105 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 106 | Syntax | 
|  | 107 | ====== | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 108 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 109 | TableGen has an ``include`` mechanism. It does not play a role in the | 
|  | 110 | syntax per se, since it is lexically replaced with the contents of the | 
|  | 111 | included file. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 112 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 113 | .. productionlist:: | 
|  | 114 | IncludeDirective: "include" `TokString` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 115 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 116 | TableGen's top-level production consists of "objects". | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 117 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 118 | .. productionlist:: | 
|  | 119 | TableGenFile: `Object`* | 
| Nicolai Haehnle | fcd6525 | 2018-03-09 12:24:42 +0000 | [diff] [blame] | 120 | Object: `Class` | `Def` | `Defm` | `Defset` | `Let` | `MultiClass` | | 
|  | 121 | `Foreach` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 122 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 123 | ``class``\es | 
|  | 124 | ------------ | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 125 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 126 | .. productionlist:: | 
|  | 127 | Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 128 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 129 | A ``class`` declaration creates a record which other records can inherit | 
|  | 130 | from. A class can be parametrized by a list of "template arguments", whose | 
|  | 131 | values can be used in the class body. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 132 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 133 | A given class can only be defined once. A ``class`` declaration is | 
|  | 134 | considered to define the class if any of the following is true: | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 135 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 136 | .. break ObjectBody into its consituents so that they are present here? | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 137 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 138 | #. The :token:`TemplateArgList` is present. | 
|  | 139 | #. The :token:`Body` in the :token:`ObjectBody` is present and is not empty. | 
|  | 140 | #. The :token:`BaseClassList` in the :token:`ObjectBody` is present. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 141 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 142 | You can declare an empty class by giving and empty :token:`TemplateArgList` | 
|  | 143 | and an empty :token:`ObjectBody`. This can serve as a restricted form of | 
|  | 144 | forward declaration: note that records deriving from the forward-declared | 
|  | 145 | class will inherit no fields from it since the record expansion is done | 
|  | 146 | when the record is parsed. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 147 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 148 | .. productionlist:: | 
|  | 149 | TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 150 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 151 | Declarations | 
|  | 152 | ------------ | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 153 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 154 | .. Omitting mention of arcane "field" prefix to discourage its use. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 155 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 156 | The declaration syntax is pretty much what you would expect as a C++ | 
|  | 157 | programmer. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 158 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 159 | .. productionlist:: | 
|  | 160 | Declaration: `Type` `TokIdentifier` ["=" `Value`] | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 161 |  | 
| Sylvestre Ledru | 7d54050 | 2016-07-02 19:28:40 +0000 | [diff] [blame] | 162 | It assigns the value to the identifier. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 163 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 164 | Types | 
|  | 165 | ----- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 166 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 167 | .. productionlist:: | 
|  | 168 | Type: "string" | "code" | "bit" | "int" | "dag" | 
|  | 169 | :| "bits" "<" `TokInteger` ">" | 
|  | 170 | :| "list" "<" `Type` ">" | 
|  | 171 | :| `ClassID` | 
|  | 172 | ClassID: `TokIdentifier` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 173 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 174 | Both ``string`` and ``code`` correspond to the string type; the difference | 
|  | 175 | is purely to indicate programmer intention. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 176 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 177 | The :token:`ClassID` must identify a class that has been previously | 
|  | 178 | declared or defined. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 179 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 180 | Values | 
|  | 181 | ------ | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 182 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 183 | .. productionlist:: | 
|  | 184 | Value: `SimpleValue` `ValueSuffix`* | 
|  | 185 | ValueSuffix: "{" `RangeList` "}" | 
|  | 186 | :| "[" `RangeList` "]" | 
|  | 187 | :| "." `TokIdentifier` | 
|  | 188 | RangeList: `RangePiece` ("," `RangePiece`)* | 
|  | 189 | RangePiece: `TokInteger` | 
|  | 190 | :| `TokInteger` "-" `TokInteger` | 
|  | 191 | :| `TokInteger` `TokInteger` | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 192 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 193 | The peculiar last form of :token:`RangePiece` is due to the fact that the | 
|  | 194 | "``-``" is included in the :token:`TokInteger`, hence ``1-5`` gets lexed as | 
|  | 195 | two consecutive :token:`TokInteger`'s, with values ``1`` and ``-5``, | 
|  | 196 | instead of "1", "-", and "5". | 
|  | 197 | The :token:`RangeList` can be thought of as specifying "list slice" in some | 
|  | 198 | contexts. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 199 |  | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 200 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 201 | :token:`SimpleValue` has a number of forms: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 202 |  | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 203 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 204 | .. productionlist:: | 
|  | 205 | SimpleValue: `TokIdentifier` | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 206 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 207 | The value will be the variable referenced by the identifier. It can be one | 
|  | 208 | of: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 209 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 210 | .. The code for this is exceptionally abstruse. These examples are a | 
|  | 211 | best-effort attempt. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 212 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 213 | * name of a ``def``, such as the use of ``Bar`` in:: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 214 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 215 | def Bar : SomeClass { | 
|  | 216 | int X = 5; | 
|  | 217 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 218 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 219 | def Foo { | 
|  | 220 | SomeClass Baz = Bar; | 
|  | 221 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 222 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 223 | * value local to a ``def``, such as the use of ``Bar`` in:: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 224 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 225 | def Foo { | 
|  | 226 | int Bar = 5; | 
|  | 227 | int Baz = Bar; | 
|  | 228 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 229 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 230 | * a template arg of a ``class``, such as the use of ``Bar`` in:: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 231 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 232 | class Foo<int Bar> { | 
|  | 233 | int Baz = Bar; | 
|  | 234 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 235 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 236 | * value local to a ``multiclass``, such as the use of ``Bar`` in:: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 237 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 238 | multiclass Foo { | 
|  | 239 | int Bar = 5; | 
|  | 240 | int Baz = Bar; | 
|  | 241 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 242 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 243 | * a template arg to a ``multiclass``, such as the use of ``Bar`` in:: | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 244 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 245 | multiclass Foo<int Bar> { | 
|  | 246 | int Baz = Bar; | 
|  | 247 | } | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 248 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 249 | .. productionlist:: | 
|  | 250 | SimpleValue: `TokInteger` | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 251 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 252 | This represents the numeric value of the integer. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 253 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 254 | .. productionlist:: | 
|  | 255 | SimpleValue: `TokString`+ | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 256 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 257 | Multiple adjacent string literals are concatenated like in C/C++. The value | 
|  | 258 | is the concatenation of the strings. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 259 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 260 | .. productionlist:: | 
|  | 261 | SimpleValue: `TokCodeFragment` | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 262 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 263 | The value is the string value of the code fragment. | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 264 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 265 | .. productionlist:: | 
|  | 266 | SimpleValue: "?" | 
| Renato Golin | ca10564 | 2014-03-20 16:08:34 +0000 | [diff] [blame] | 267 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 268 | ``?`` represents an "unset" initializer. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 269 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 270 | .. productionlist:: | 
|  | 271 | SimpleValue: "{" `ValueList` "}" | 
|  | 272 | ValueList: [`ValueListNE`] | 
|  | 273 | ValueListNE: `Value` ("," `Value`)* | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 274 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 275 | This represents a sequence of bits, as would be used to initialize a | 
|  | 276 | ``bits<n>`` field (where ``n`` is the number of bits). | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 277 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 278 | .. productionlist:: | 
|  | 279 | SimpleValue: `ClassID` "<" `ValueListNE` ">" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 280 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 281 | This generates a new anonymous record definition (as would be created by an | 
|  | 282 | unnamed ``def`` inheriting from the given class with the given template | 
|  | 283 | arguments) and the value is the value of that record definition. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 284 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 285 | .. productionlist:: | 
|  | 286 | SimpleValue: "[" `ValueList` "]" ["<" `Type` ">"] | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 287 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 288 | A list initializer. The optional :token:`Type` can be used to indicate a | 
|  | 289 | specific element type, otherwise the element type will be deduced from the | 
|  | 290 | given values. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 291 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 292 | .. The initial `DagArg` of the dag must start with an identifier or | 
|  | 293 | !cast, but this is more of an implementation detail and so for now just | 
|  | 294 | leave it out. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 295 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 296 | .. productionlist:: | 
|  | 297 | SimpleValue: "(" `DagArg` `DagArgList` ")" | 
|  | 298 | DagArgList: `DagArg` ("," `DagArg`)* | 
|  | 299 | DagArg: `Value` [":" `TokVarName`] | `TokVarName` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 300 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 301 | The initial :token:`DagArg` is called the "operator" of the dag. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 302 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 303 | .. productionlist:: | 
|  | 304 | SimpleValue: `BangOperator` ["<" `Type` ">"] "(" `ValueListNE` ")" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 305 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 306 | Bodies | 
|  | 307 | ------ | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 308 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 309 | .. productionlist:: | 
|  | 310 | ObjectBody: `BaseClassList` `Body` | 
|  | 311 | BaseClassList: [":" `BaseClassListNE`] | 
|  | 312 | BaseClassListNE: `SubClassRef` ("," `SubClassRef`)* | 
|  | 313 | SubClassRef: (`ClassID` | `MultiClassID`) ["<" `ValueList` ">"] | 
|  | 314 | DefmID: `TokIdentifier` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 315 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 316 | The version with the :token:`MultiClassID` is only valid in the | 
|  | 317 | :token:`BaseClassList` of a ``defm``. | 
|  | 318 | The :token:`MultiClassID` should be the name of a ``multiclass``. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 319 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 320 | .. put this somewhere else | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 321 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 322 | It is after parsing the base class list that the "let stack" is applied. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 323 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 324 | .. productionlist:: | 
|  | 325 | Body: ";" | "{" BodyList "}" | 
|  | 326 | BodyList: BodyItem* | 
|  | 327 | BodyItem: `Declaration` ";" | 
|  | 328 | :| "let" `TokIdentifier` [`RangeList`] "=" `Value` ";" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 329 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 330 | The ``let`` form allows overriding the value of an inherited field. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 331 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 332 | ``def`` | 
|  | 333 | ------- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 334 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 335 | .. TODO:: | 
|  | 336 | There can be pastes in the names here, like ``#NAME#``. Look into that | 
|  | 337 | and document it (it boils down to ParseIDValue with IDParseMode == | 
|  | 338 | ParseNameMode). ParseObjectName calls into the general ParseValue, with | 
|  | 339 | the only different from "arbitrary expression parsing" being IDParseMode | 
|  | 340 | == Mode. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 341 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 342 | .. productionlist:: | 
|  | 343 | Def: "def" `TokIdentifier` `ObjectBody` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 344 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 345 | Defines a record whose name is given by the :token:`TokIdentifier`. The | 
|  | 346 | fields of the record are inherited from the base classes and defined in the | 
|  | 347 | body. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 348 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 349 | Special handling occurs if this ``def`` appears inside a ``multiclass`` or | 
|  | 350 | a ``foreach``. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 351 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 352 | ``defm`` | 
|  | 353 | -------- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 354 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 355 | .. productionlist:: | 
|  | 356 | Defm: "defm" `TokIdentifier` ":" `BaseClassListNE` ";" | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 357 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 358 | Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must | 
|  | 359 | precede any ``class``'s that appear. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 360 |  | 
| Nicolai Haehnle | fcd6525 | 2018-03-09 12:24:42 +0000 | [diff] [blame] | 361 | ``defset`` | 
|  | 362 | ---------- | 
|  | 363 | .. productionlist:: | 
|  | 364 | Defset: "defset" `Type` `TokIdentifier` "=" "{" `Object`* "}" | 
|  | 365 |  | 
|  | 366 | All records defined inside the braces via ``def`` and ``defm`` are collected | 
|  | 367 | in a globally accessible list of the given name (in addition to being added | 
|  | 368 | to the global collection of records as usual). Anonymous records created inside | 
|  | 369 | initializier expressions using the ``Class<args...>`` syntax are never collected | 
|  | 370 | in a defset. | 
|  | 371 |  | 
|  | 372 | The given type must be ``list<A>``, where ``A`` is some class. It is an error | 
|  | 373 | to define a record (via ``def`` or ``defm``) inside the braces which doesn't | 
|  | 374 | derive from ``A``. | 
|  | 375 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 376 | ``foreach`` | 
|  | 377 | ----------- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 378 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 379 | .. productionlist:: | 
| Nicolai Haehnle | 8aa9d58 | 2018-03-09 12:24:30 +0000 | [diff] [blame] | 380 | Foreach: "foreach" `ForeachDeclaration` "in" "{" `Object`* "}" | 
|  | 381 | :| "foreach" `ForeachDeclaration` "in" `Object` | 
|  | 382 | ForeachDeclaration: ID "=" ( "{" `RangeList` "}" | `RangePiece` | `Value` ) | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 383 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 384 | The value assigned to the variable in the declaration is iterated over and | 
|  | 385 | the object or object list is reevaluated with the variable set at each | 
|  | 386 | iterated value. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 387 |  | 
| Nicolai Haehnle | 8aa9d58 | 2018-03-09 12:24:30 +0000 | [diff] [blame] | 388 | Note that the productions involving RangeList and RangePiece have precedence | 
|  | 389 | over the more generic value parsing based on the first token. | 
|  | 390 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 391 | Top-Level ``let`` | 
|  | 392 | ----------------- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 393 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 394 | .. productionlist:: | 
|  | 395 | Let:  "let" `LetList` "in" "{" `Object`* "}" | 
|  | 396 | :| "let" `LetList` "in" `Object` | 
|  | 397 | LetList: `LetItem` ("," `LetItem`)* | 
|  | 398 | LetItem: `TokIdentifier` [`RangeList`] "=" `Value` | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 399 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 400 | This is effectively equivalent to ``let`` inside the body of a record | 
|  | 401 | except that it applies to multiple records at a time. The bindings are | 
|  | 402 | applied at the end of parsing the base classes of a record. | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 403 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 404 | ``multiclass`` | 
|  | 405 | -------------- | 
| Sean Silva | 1b60018 | 2013-01-07 02:43:44 +0000 | [diff] [blame] | 406 |  | 
| Renato Golin | 33f973a | 2014-04-01 09:51:49 +0000 | [diff] [blame] | 407 | .. productionlist:: | 
|  | 408 | MultiClass: "multiclass" `TokIdentifier` [`TemplateArgList`] | 
|  | 409 | : [":" `BaseMultiClassList`] "{" `MultiClassObject`+ "}" | 
|  | 410 | BaseMultiClassList: `MultiClassID` ("," `MultiClassID`)* | 
|  | 411 | MultiClassID: `TokIdentifier` | 
|  | 412 | MultiClassObject: `Def` | `Defm` | `Let` | `Foreach` |