SHOW:
|
|
- or go back to the newest paste.
| 1 | [/============================================================================= | |
| 2 | ||
| 3 | Gaea text template language! | |
| 4 | ||
| 5 | Thanks to hkaiser, VeXocide and heller !!! on Spirit IRC | |
| 6 | Thanks to Daniel James, Matias Capeletto and Dave Abrahams | |
| 7 | for added comments and suggestions (Boost Docs List). | |
| 8 | ||
| 9 | ==============================================================================] | |
| 10 | ||
| 11 | Reserved tokens: | |
| 12 | [ | |
| 13 | ] | |
| 14 | [u | |
| 15 | [def | |
| 16 | [decl | |
| 17 | [lambda | |
| 18 | [import | |
| 19 | [namespace | |
| 20 | [/ | |
| 21 | [^ | |
| 22 | [" | |
| 23 | ["" | |
| 24 | ""] | |
| 25 | \[ | |
| 26 | \] | |
| 27 | ||
| 28 | (the last 2 is for escaping [ and ]) | |
| 29 | ||
| 30 | Comments: | |
| 31 | ||
| 32 | [/ comments. ] | |
| 33 | [/ nested [/ nested comments] comments. ] | |
| 34 | [/ balanced square braces [ and ] (i.e starts with [ and ends with ] and | |
| 35 | with equal number of [ and ]), are allowed inside comments. This is a | |
| 36 | good way to comment out code. ] | |
| 37 | ||
| 38 | Markups: | |
| 39 | ||
| 40 | [*This is a markup] | |
| 41 | [orderedlist [a][b][c]] | |
| 42 | ||
| 43 | Markups are always significant, except inside escapes (see ["" Escapes | |
| 44 | - | below). Like HTML/XML spaces are coalesced unless they are inside the |
| 44 | + | below) and except for list elements (see List). Like HTML/XML spaces |
| 45 | - | preformatted markup (see [^ Preformatted below). |
| 45 | + | are coalesced unless they are inside the preformatted markup |
| 46 | (see [^ Preformatted below). | |
| 47 | ||
| 48 | Markup Identifiers: | |
| 49 | ||
| 50 | Identifiers consist of one or more letters, digits and extended | |
| 51 | characters: ! $ % & * + - . : < = > ? @ _ ` # ' that | |
| 52 | cannot begin a number and cannot conflict with a reserved token. | |
| 53 | ||
| 54 | Examples: | |
| 55 | ||
| 56 | This-is-an-identifier | |
| 57 | ? | |
| 58 | * | |
| 59 | == | |
| 60 | ?WTH | |
| 61 | ||
| 62 | Simple Strings: | |
| 63 | ||
| 64 | This is a string | |
| 65 | ||
| 66 | Jack and Jill went up the hill to fetch a pail of water. | |
| 67 | Jack fell down and broke his crown, and Jill came tumbling after. | |
| 68 | ||
| 69 | 123 is a numeric string | |
| 70 | ||
| 71 | Grouped String: | |
| 72 | ||
| 73 | ["This is grouped a string] | |
| 74 | ||
| 75 | - | of grouped strings are allowed *ONLY* as list elements |
| 75 | + | |
| 76 | - | (see List below). |
| 76 | + | of grouped strings are allowed *ONLY* as list (see List below) |
| 77 | elements: | |
| 78 | ||
| 79 | [This grouped string is allowed *ONLY* as list element] | |
| 80 | ||
| 81 | The double quote is not necessary because bare markups are not | |
| 82 | allowed as list elements. If you need markups in list elements, | |
| 83 | put them in braces: | |
| 84 | ||
| 85 | [[*A marked-up list element]] | |
| 86 | ||
| 87 | Marked up Strings: | |
| 88 | ||
| 89 | This string [*contains] a markup. '*' should better be a | |
| 90 | template, otherwise this is an error. | |
| 91 | ||
| 92 | [*This] string contains a markup. '*' should better be a | |
| 93 | template, otherwise this is an error. | |
| 94 | ||
| 95 | Lists: | |
| 96 | - | A list may contain one or grouped-string or nested list. |
| 96 | + | |
| 97 | A list may contain one or grouped-string or nested list, but | |
| 98 | not bare markups. | |
| 99 | ||
| 100 | Examples: | |
| 101 | ||
| 102 | [[a][b][c]] [/ 1st ] | |
| 103 | [[a][[b][c]]] [/ 2nd ] | |
| 104 | ||
| 105 | Lists can form linear or hierarchical data structures. 1st is a | |
| 106 | 3-element list [a][b][c]. 2nd is a 2-element list where the first | |
| 107 | element is [a] and the second is a 2-element list [b][c]. | |
| 108 | ||
| 109 | Formatting makes it clear: | |
| 110 | ||
| 111 | 1st: | |
| 112 | ||
| 113 | [ | |
| 114 | [a][b][c] | |
| 115 | ] | |
| 116 | ||
| 117 | 2nd: | |
| 118 | ||
| 119 | [ | |
| 120 | [a] | |
| 121 | [ | |
| 122 | [b][c] | |
| 123 | ] | |
| 124 | ] | |
| 125 | ||
| 126 | This is an erroneous list: | |
| 127 | ||
| 128 | [[a][b][c] duh!] [/ not a list ] | |
| 129 | ||
| 130 | There should never be "naked" list elements (those without | |
| 131 | braces). That one above is not a list. It is a grouped string; | |
| 132 | and so is this: | |
| 133 | ||
| 134 | [duh! [a][b][c]] [/ not a list ] | |
| 135 | ||
| 136 | It is important to keep in mind that lists may not contain bare | |
| 137 | markups. This: | |
| 138 | ||
| 139 | [[dup x][dup y]] | |
| 140 | ||
| 141 | will *NOT* expand the 'dup' templates. If you need markups expanded | |
| 142 | in list elements, put them in braces: | |
| 143 | ||
| 144 | [[[dup x]][[dup y]]] | |
| 145 | ||
| 146 | Strings as lists: | |
| 147 | ||
| 148 | A string is just a special form of list with single character elements. | |
| 149 | ||
| 150 | List elements: | |
| 151 | ||
| 152 | [ | |
| 153 | [This is grouped a string] | |
| 154 | ||
| 155 | [[*This is a markup]] | |
| 156 | ||
| 157 | [[a][b][c]] [/ A nested list ] | |
| 158 | ||
| 159 | [This string [*contains] a markup] | |
| 160 | ||
| 161 | [[*this] is still a string.] | |
| 162 | ||
| 163 | [[this is a single element list!]] | |
| 164 | ||
| 165 | ["[this is *not* a nested list!]] [/ the double quote " prevents this from | |
| 166 | becoming a list (see Protect below)] | |
| 167 | ] | |
| 168 | ||
| 169 | Nil: | |
| 170 | ||
| 171 | [] | |
| 172 | ||
| 173 | A nil can be an empty string or an empty list. | |
| 174 | ||
| 175 | Unicode Code Points: | |
| 176 | ||
| 177 | [u2018] [/ Generates unicode code point (hexadecimal). ] | |
| 178 | ||
| 179 | Escapes: | |
| 180 | ||
| 181 | \[ [/ Escapes the open bracket] | |
| 182 | \] [/ Escapes the close bracket] | |
| 183 | [""x""] [/ Escapes all occurances of [ and ] in x. ] | |
| 184 | ||
| 185 | Preformatted: | |
| 186 | ||
| 187 | [^ some-text] [/ Make spaces, tabs and newlines significant ] | |
| 188 | ||
| 189 | Protect: | |
| 190 | ||
| 191 | ["* blah] [/ Don't expand * regardless if * is | |
| 192 | a template (or not) ] | |
| 193 | ["[x][y][z]] [/ Don't make this a list ] | |
| 194 | ||
| 195 | Protect ["* blah] is not really the same as [""* blah""]. Only the | |
| 196 | template * is not expanded. For example, ["* [bar]] will still expand | |
| 197 | bar, while [""* [bar]""] will not evaluate both * and bar. | |
| 198 | ||
| 199 | Template: | |
| 200 | Forward declarations: | |
| 201 | ||
| 202 | [decl [foo]] | |
| 203 | ||
| 204 | [decl [dup a]] | |
| 205 | ||
| 206 | Forward declarations are good for recursion and is always perfect | |
| 207 | for documenting templates. | |
| 208 | ||
| 209 | Definitions: | |
| 210 | ||
| 211 | [def [pi] 3.14159265] [/ nullary template def ] | |
| 212 | ||
| 213 | [def pi 3.14159265] [/ short for nullary template def ] | |
| 214 | ||
| 215 | [def [dup a] [a][a]] [/ arguments always need to be evaluated, e.g. [a] ] | |
| 216 | ||
| 217 | [def [cat a b] [a][b]] | |
| 218 | ||
| 219 | Template expansion: | |
| 220 | ||
| 221 | [pi] [/ nullary template ] | |
| 222 | ||
| 223 | [dup apple pie] [/ unary template. argument is a string. ] | |
| 224 | ||
| 225 | [dup [apple pie]] [/ unary template. argument is a 1-element list. ] | |
| 226 | ||
| 227 | [cat [apple][pie]] [/ 2 arguments. argument is a 2-element list. ] | |
| 228 | ||
| 229 | Optional Named Arguments: | |
| 230 | ||
| 231 | Any argument can be made optional by preceding the formal argument | |
| 232 | name with the tilde '~'. Example: | |
| 233 | ||
| 234 | [decl [$ path ~width ~height]] | |
| 235 | ||
| 236 | The $ template above can be used this way: | |
| 237 | ||
| 238 | [$image.jpg [~width 200px] [~height 200px]] | |
| 239 | ||
| 240 | Optional arguments can be placed anywhere in the template expansion. | |
| 241 | Order does not matter: | |
| 242 | ||
| 243 | [$[~width 200px] image.jpg [~height 200px]] [/ OK] | |
| 244 | [$[~height 200px] [~width 200px] image.jpg] [/ OK] | |
| 245 | ||
| 246 | Notice too that image.jpg need not be placed inside braces. All optional | |
| 247 | arguments are gathered and what's left should conform to the rules for | |
| 248 | template expansion above; hence becomes: | |
| 249 | ||
| 250 | [$image.jpg] [/ nullary template ] | |
| 251 | ||
| 252 | Of course you can place them all inside braces if you want: | |
| 253 | ||
| 254 | [$[image.jpg] [~width 200px] [~height 200px]] | |
| 255 | ||
| 256 | Variable args: | |
| 257 | ||
| 258 | Example: | |
| 259 | ||
| 260 | - | Again, the list may contain one or more markup, grouped-string or nested |
| 260 | + | |
| 261 | - | list. |
| 261 | + | |
| 262 | The dot '.' before the last formal argument signifies variable | |
| 263 | number of arguments. It is only allowed before the final formal | |
| 264 | argument. The actual arguments passed are collected in one list. | |
| 265 | ||
| 266 | Example invocation: | |
| 267 | ||
| 268 | [table [~title My First Table] | |
| 269 | [[Heading 1] [Heading 2] [Heading 3]] | |
| 270 | [[R0-C0] [R0-C1] [R0-C2]] | |
| 271 | ] | |
| 272 | ||
| 273 | Again, the list may contain one or more grouped-string or nested list. | |
| 274 | ||
| 275 | Intrinsics: | |
| 276 | ||
| 277 | [decl [head x]] [/ Get first element from x. ] | |
| 278 | [decl [tail x]] [/ Return a list or string without the first element of x. ] | |
| 279 | [decl [empty x]] [/ Return 1 if x is empty else 0. ] | |
| 280 | [decl [at x n]] [/ Return the nth element of x. ] | |
| 281 | [decl [size x]] [/ Return size of x. ] | |
| 282 | [decl [append x e]] [/ Append e to x. ] | |
| 283 | [decl [insert x e n]] [/ Insert e to x at position n. ] | |
| 284 | [decl [reverse x]] [/ Reverse x. ] | |
| 285 | [decl [join x y]] [/ Join x and y as one longer list. ] | |
| 286 | ||
| 287 | [decl [fold x s f]] [/ For a list x, initial state s, and binary function f, | |
| 288 | fold returns the result of the repeated application of | |
| 289 | [f e s] for each element e of list x, to the result | |
| 290 | of the previous f invocation (s if it is the first call). ] | |
| 291 | ||
| 292 | Many list operations can be implemented using fold. Yet, for the sake | |
| 293 | of efficiency, we provide these common operations as intrinsics. | |
| 294 | ||
| 295 | [decl [transform x f]] [/ For a list x and function f, transform returns a new | |
| 296 | list with elements created by applying [f e] to each | |
| 297 | element e of x. ] | |
| 298 | ||
| 299 | Since strings are just special forms of lists, all functions that accept | |
| 300 | lists can also accept strings. | |
| 301 | ||
| 302 | [decl [load file]] [/ Loads file. ] | |
| 303 | [decl [save file x]] [/ Saves x to file. ] | |
| 304 | ||
| 305 | load processes files (i.e. markups are significant). If you want to load | |
| 306 | files verbatim, enclose it in the escape markup. Example: | |
| 307 | ||
| 308 | [""[load text.gia]""] | |
| 309 | ||
| 310 | Load works similarly to C #include. It is possible to load a file inside | |
| 311 | a template body. All the templates in the loaded file will be available | |
| 312 | in the scope where it is loaded. | |
| 313 | ||
| 314 | [decl [add a b]] [/ Add a and b. both a and b are numeric integer strings. ] | |
| 315 | [decl [subt a b]] [/ Subract a and b. both a and b are numeric integer strings. ] | |
| 316 | [decl [mult a b]] [/ Multiply a and b. both a and b are numeric integer strings. ] | |
| 317 | [decl [div a b]] [/ Divide a and b. both a and b are numeric integer strings. ] | |
| 318 | [decl [mod a b]] [/ Remainder of a / b. both a and b are numeric integer strings. ] | |
| 319 | ||
| 320 | [decl [eq a b]] [/ Returns 1 if a == b. ] | |
| 321 | [decl [lt a b]] [/ Returns 1 if a is less than b. ] | |
| 322 | [decl [and a b]] [/ Returns a and b (boolean logic). ] | |
| 323 | [decl [or a b]] [/ Returns a or b (boolean logic). ] | |
| 324 | [decl [if cond then else]] [/ Returns then if cond is 1, otherwise returns else. ] | |
| 325 | ||
| 326 | Other comparisons and booleans can be synthesized from the basics above. | |
| 327 | For example not can be defined as: | |
| 328 | ||
| 329 | [def [not x] [if [x][0][1]]] | |
| 330 | ||
| 331 | ne (not-equal) can be defined as: | |
| 332 | ||
| 333 | [def [ne a b] [not [eq [a][b]]]], etc. | |
| 334 | ||
| 335 | Lambda Functions: | |
| 336 | ||
| 337 | Functions are first class and can be passed to and returned from other | |
| 338 | functions. For example, the transform intrinsic requires a lambda function | |
| 339 | for its last (f) argument. | |
| 340 | ||
| 341 | Here's an example of a lambda function: | |
| 342 | ||
| 343 | [lambda [x] [dup [x]]] | |
| 344 | ||
| 345 | Its syntax resembles a function definition. | |
| 346 | ||
| 347 | Here's a sample invocation of transform: | |
| 348 | ||
| 349 | [transform [[a][b][c]] [lambda [x] [dup [x]]]] | |
| 350 | ||
| 351 | This doubles all elements of the list: | |
| 352 | ||
| 353 | [[aa][bb][cc]] | |
| 354 | ||
| 355 | Function arguments: | |
| 356 | ||
| 357 | If the arity of the function argument is the same as the one expected, | |
| 358 | the argument (e.g. Transform expects its f argument to be a unary | |
| 359 | function. Likewise, dup is also a unary function), the function can | |
| 360 | be passed as-is. Example: | |
| 361 | ||
| 362 | [transform [[a][b][c]][dup]] | |
| 363 | ||
| 364 | Hence: | |
| 365 | ||
| 366 | [dup] | |
| 367 | ||
| 368 | is a shorthand equivalent to: | |
| 369 | ||
| 370 | [lambda [x] [dup [x]]] | |
| 371 | ||
| 372 | Scopes: | |
| 373 | ||
| 374 | Templates can be placed inside a namespace. Example: | |
| 375 | ||
| 376 | [namespace ns | |
| 377 | ||
| 378 | [decl [foo x]] | |
| 379 | [decl [bar x]] | |
| 380 | ] | |
| 381 | ||
| 382 | The template x can be referenced in other scopes using the | |
| 383 | dot notation. Example: | |
| 384 | ||
| 385 | [ns.foo hello, world!] | |
| 386 | ||
| 387 | You may import names from other scopes this way: | |
| 388 | ||
| 389 | [import [ns][foo][bar]] [/ Import foo and bar from ns ] | |
| 390 | ||
| 391 | Then you can use foo and bar without qualification: | |
| 392 | ||
| 393 | [foo hello, world!] | |
| 394 | ||
| 395 | You may also import a whole namespace: | |
| 396 | ||
| 397 | [import ns] [/ Import all templates in ns ] | |
| 398 | ||
| 399 | All the intrinsics are declared in namespace "std". There is an | |
| 400 | implicit | |
| 401 | ||
| 402 | [import std] | |
| 403 | ||
| 404 | before anything else. In case of ambiguity (when template names clash), | |
| 405 | you can use explicit qualification. Example: | |
| 406 | ||
| 407 | [std.plus [1][2]] | |
| 408 | ||
| 409 | ||
| 410 | ||
| 411 |