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) and except for list elements (see List). Like HTML/XML spaces |
| 44 | + | below) and except as list elements (see List). Like HTML/XML spaces |
| 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 | The [" and ] delimit the extent of the string. A simple form | |
| 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] |
| 79 | + | [This grouped string is allowed *ONLY* as a 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, |
| 82 | + | allowed as list elements. If you need to markup a list element, |
| 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 | ||
| 97 | - | A list may contain one or grouped-string or nested list, but |
| 97 | + | A list may contain one or more 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] |
| 153 | + | [This is a grouped 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. |
| 207 | + | for documentation. |
| 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] ] |
| 215 | + | [def [dup a] [a][a]] [/ arguments are local templates that |
| 216 | need to be expanded, e.g. [a] ] | |
| 217 | ||
| 218 | [def [cat a b] [a][b]] | |
| 219 | ||
| 220 | Template expansion: | |
| 221 | ||
| 222 | [pi] [/ nullary template ] | |
| 223 | ||
| 224 | [dup apple pie] [/ unary template. argument is a string. ] | |
| 225 | ||
| 226 | [dup [apple pie]] [/ unary template. argument is a 1-element list. ] | |
| 227 | ||
| 228 | [cat [apple][pie]] [/ 2 arguments. argument is a 2-element list. ] | |
| 229 | ||
| 230 | Optional Named Arguments: | |
| 231 | ||
| 232 | Any argument can be made optional by preceding the formal argument | |
| 233 | name with the tilde '~'. Example: | |
| 234 | ||
| 235 | [decl [$ path ~width ~height]] | |
| 236 | ||
| 237 | The $ template above can be used this way: | |
| 238 | ||
| 239 | [$image.jpg [~width 200px] [~height 200px]] | |
| 240 | ||
| 241 | Optional arguments can be placed anywhere in the template expansion. | |
| 242 | Order does not matter: | |
| 243 | ||
| 244 | [$[~width 200px] image.jpg [~height 200px]] [/ OK] | |
| 245 | [$[~height 200px] [~width 200px] image.jpg] [/ OK] | |
| 246 | ||
| 247 | Notice too that image.jpg need not be placed inside braces. All optional | |
| 248 | arguments are gathered and what's left should conform to the rules for | |
| 249 | template expansion above; hence becomes: | |
| 250 | ||
| 251 | [$image.jpg] [/ nullary template ] | |
| 252 | ||
| 253 | Of course you can place them all inside braces if you want: | |
| 254 | ||
| 255 | [$[image.jpg] [~width 200px] [~height 200px]] | |
| 256 | ||
| 257 | Variable args: | |
| 258 | ||
| 259 | Example: | |
| 260 | ||
| 261 | [decl [table [~title] . rows]] | |
| 262 | ||
| 263 | The dot '.' before the last formal argument signifies variable | |
| 264 | number of arguments. It is only allowed before the final formal | |
| 265 | argument. The actual arguments passed are collected in one list. | |
| 266 | ||
| 267 | Example invocation: | |
| 268 | ||
| 269 | [table [~title My First Table] | |
| 270 | [[Heading 1] [Heading 2] [Heading 3]] | |
| 271 | [[R0-C0] [R0-C1] [R0-C2]] | |
| 272 | ] | |
| 273 | ||
| 274 | Again, the list may contain one or more grouped-string or nested list. | |
| 275 | ||
| 276 | Intrinsics: | |
| 277 | ||
| 278 | [decl [head x]] [/ Get first element from x. ] | |
| 279 | [decl [tail x]] [/ Return a list or string without the first element of x. ] | |
| 280 | [decl [empty x]] [/ Return 1 if x is empty else 0. ] | |
| 281 | [decl [at x n]] [/ Return the nth element of x. ] | |
| 282 | [decl [size x]] [/ Return size of x. ] | |
| 283 | [decl [append x e]] [/ Append e to x. ] | |
| 284 | [decl [insert x e n]] [/ Insert e to x at position n. ] | |
| 285 | [decl [reverse x]] [/ Reverse x. ] | |
| 286 | [decl [join x y]] [/ Join x and y as one longer list. ] | |
| 287 | - | [decl [fold x s f]] [/ For a list x, initial state s, and binary function f, |
| 287 | + | |
| 288 | [decl [fold x s f]] [/ For a list x, initial state s, and binary template f, | |
| 289 | fold returns the result of the repeated application of | |
| 290 | [f e s] for each element e of list x, to the result | |
| 291 | of the previous f invocation (s if it is the first call). ] | |
| 292 | ||
| 293 | Many list operations can be implemented using fold. Yet, for the sake | |
| 294 | of efficiency, we provide these common operations as intrinsics. | |
| 295 | - | [decl [transform x f]] [/ For a list x and function f, transform returns a new |
| 295 | + | |
| 296 | [decl [transform x f]] [/ For a list x and template f, transform returns a new | |
| 297 | list with elements created by applying [f e] to each | |
| 298 | element e of x. ] | |
| 299 | - | Since strings are just special forms of lists, all functions that accept |
| 299 | + | |
| 300 | Since strings are just special forms of lists, all templates that accept | |
| 301 | lists can also accept strings. | |
| 302 | ||
| 303 | [decl [load file]] [/ Loads file. ] | |
| 304 | [decl [save file x]] [/ Saves x to file. ] | |
| 305 | ||
| 306 | load processes files (i.e. markups are significant). If you want to load | |
| 307 | files verbatim, enclose it in the escape markup. Example: | |
| 308 | ||
| 309 | [""[load text.gia]""] | |
| 310 | ||
| 311 | Load works similarly to C #include. It is possible to load a file inside | |
| 312 | a template body. All the templates in the loaded file will be available | |
| 313 | in the scope where it is loaded. | |
| 314 | - | [decl [add a b]] [/ Add a and b. both a and b are numeric integer strings. ] |
| 314 | + | |
| 315 | - | [decl [subt a b]] [/ Subract a and b. both a and b are numeric integer strings. ] |
| 315 | + | [decl [add a b]] [/ Add a and b. ] |
| 316 | - | [decl [mult a b]] [/ Multiply a and b. both a and b are numeric integer strings. ] |
| 316 | + | [decl [subt a b]] [/ Subract a and b. ] |
| 317 | - | [decl [div a b]] [/ Divide a and b. both a and b are numeric integer strings. ] |
| 317 | + | [decl [mult a b]] [/ Multiply a and b. ] |
| 318 | - | [decl [mod a b]] [/ Remainder of a / b. both a and b are numeric integer strings. ] |
| 318 | + | [decl [div a b]] [/ Divide a and b. ] |
| 319 | [decl [mod a b]] [/ Remainder of a / b. ] | |
| 320 | ||
| 321 | All arithmetic templates above expect both arguments to be numeric strings. | |
| 322 | ||
| 323 | [decl [eq a b]] [/ Returns 1 if a == b. ] | |
| 324 | [decl [lt a b]] [/ Returns 1 if a is less than b. ] | |
| 325 | [decl [and a b]] [/ Returns a and b (boolean logic). ] | |
| 326 | [decl [or a b]] [/ Returns a or b (boolean logic). ] | |
| 327 | [decl [if cond then else]] [/ Returns then if cond is 1, otherwise returns else. ] | |
| 328 | ||
| 329 | Other comparisons and booleans can be synthesized from the basics above. | |
| 330 | For example not can be defined as: | |
| 331 | ||
| 332 | [def [not x] [if [x][0][1]]] | |
| 333 | ||
| 334 | ne (not-equal) can be defined as: | |
| 335 | - | Lambda Functions: |
| 335 | + | |
| 336 | [def [ne a b] [not [eq [a][b]]]], etc. | |
| 337 | - | Functions are first class and can be passed to and returned from other |
| 337 | + | |
| 338 | - | functions. For example, the transform intrinsic requires a lambda function |
| 338 | + | So far, all the templates above are purely functional with no |
| 339 | sife-effects. We have only two intrinsic templates with side-effects: | |
| 340 | ||
| 341 | - | Here's an example of a lambda function: |
| 341 | + | [var x value] [/ declare and define a value ] |
| 342 | [set x value] [/ assign a new value to a variable ] | |
| 343 | ||
| 344 | Variables are special beasts. They are the only means for imperative | |
| 345 | - | Its syntax resembles a function definition. |
| 345 | + | programming in the language. They respect the same scope as templates. |
| 346 | They can take in any value (strings, lists and even lambda templates | |
| 347 | (see below)). But unlike templates that can be defined but cannot be | |
| 348 | redefined, values of variables are mutable. | |
| 349 | ||
| 350 | Lambda Templates: | |
| 351 | ||
| 352 | Templates are first class and can be passed to and returned from other | |
| 353 | templates. For example, the transform intrinsic requires a lambda template | |
| 354 | for its last (f) argument. | |
| 355 | - | Function arguments: |
| 355 | + | |
| 356 | Here's an example of a lambda template: | |
| 357 | - | If the arity of the function argument is the same as the one expected, |
| 357 | + | |
| 358 | [lambda [x] [dup [x]]] | |
| 359 | - | function. Likewise, dup is also a unary function), the function can |
| 359 | + | |
| 360 | Its syntax resembles a template definition. | |
| 361 | ||
| 362 | - | [transform [[a][b][c]][dup]] |
| 362 | + | |
| 363 | ||
| 364 | [transform [[a][b][c]] [lambda [x] [dup [x]]]] | |
| 365 | ||
| 366 | This doubles all elements of the list: | |
| 367 | ||
| 368 | [[aa][bb][cc]] | |
| 369 | ||
| 370 | Template arguments: | |
| 371 | ||
| 372 | If the arity of the template argument is the same as the one expected, | |
| 373 | the argument (e.g. Transform expects its f argument to be a unary | |
| 374 | template. Likewise, dup is also a unary template), the template can | |
| 375 | be passed as-is. Example: | |
| 376 | ||
| 377 | [transform [[a][b][c]] [dup]] | |
| 378 | ||
| 379 | Hence: | |
| 380 | ||
| 381 | [dup] | |
| 382 | ||
| 383 | is a shorthand equivalent to: | |
| 384 | ||
| 385 | [lambda [x] [dup [x]]] | |
| 386 | ||
| 387 | Scopes: | |
| 388 | ||
| 389 | - | [import [ns][foo][bar]] [/ Import foo and bar from ns ] |
| 389 | + | |
| 390 | ||
| 391 | [namespace ns | |
| 392 | [decl [foo x]] | |
| 393 | [decl [bar x]] | |
| 394 | ] | |
| 395 | ||
| 396 | The template x can be referenced in other scopes using the | |
| 397 | dot notation. Example: | |
| 398 | ||
| 399 | [ns.foo hello, world!] | |
| 400 | ||
| 401 | You may import names from other scopes this way: | |
| 402 | ||
| 403 | [import ns.foo] [/ Import foo from ns ] | |
| 404 | [import ns.bar] [/ Import bar from ns ] | |
| 405 | ||
| 406 | Then you can use foo and bar without qualification: | |
| 407 | ||
| 408 | [foo hello, world!] | |
| 409 | [bar howdy, joel!] | |
| 410 | ||
| 411 | You may also import a whole namespace: | |
| 412 | ||
| 413 | [import ns] [/ Import all templates in ns ] | |
| 414 | ||
| 415 | All the intrinsics are declared in namespace "std". There is an | |
| 416 | implicit | |
| 417 | ||
| 418 | [import std] | |
| 419 | ||
| 420 | before anything else. In case of ambiguity (when template names clash), | |
| 421 | you can use explicit qualification. Example: | |
| 422 | ||
| 423 | [std.plus [1][2]] | |
| 424 | ||
| 425 | Standard Library: | |
| 426 | ||
| 427 | Apart from the intrinsics, additional support templates are auto-loaded | |
| 428 | at startup. These templates are all in namespace std. | |
| 429 | ||
| 430 | ||
| 431 | ||
| 432 | ||
| 433 | ||
| 434 | ||
| 435 | ||
| 436 | ||
| 437 | ||
| 438 |