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 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 a list element] | |
80 | ||
81 | The double quote is not necessary because bare markups are not | |
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 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 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 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 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 | Variables: | |
277 | ||
278 | Templates above are purely functional with no sife-effects. Variables | |
279 | on the other hand allow side-effects: | |
280 | ||
281 | [var x value] [/ declare and define a value ] | |
282 | [set x value] [/ assign a new value to a variable ] | |
283 | ||
284 | Variables are special beasts. They are the only means for imperative | |
285 | programming in the language. They respect the same scope as templates. | |
286 | You cannot have a template and a variable with the same name. They can | |
287 | take in any value (strings, lists and even lambda templates (see | |
288 | below)). But unlike constant templates which cannot be redefined, values | |
289 | of variables are mutable. | |
290 | ||
291 | Intrinsics: | |
292 | ||
293 | [decl [head x]] [/ Get first element from x. ] | |
294 | [decl [tail x]] [/ Return a list or string without the first element of x. ] | |
295 | [decl [empty x]] [/ Return 1 if x is empty else 0. ] | |
296 | [decl [at x n]] [/ Return the nth element of x. ] | |
297 | [decl [size x]] [/ Return size of x. ] | |
298 | [decl [append x e]] [/ Append e to x. ] | |
299 | [decl [insert x e n]] [/ Insert e to x at position n. ] | |
300 | [decl [reverse x]] [/ Reverse x. ] | |
301 | [decl [join x y]] [/ Join x and y as one longer list. ] | |
302 | ||
303 | [decl [fold x s f]] [/ For a list x, initial state s, and binary template f, | |
304 | fold returns the result of the repeated application of | |
305 | [f e s] for each element e of list x, to the result | |
306 | of the previous f invocation (s if it is the first call). ] | |
307 | ||
308 | Many list operations can be implemented using fold. Yet, for the sake | |
309 | of efficiency, we provide these common operations as intrinsics. | |
310 | ||
311 | [decl [transform x f]] [/ For a list x and template f, transform returns a new | |
312 | list with elements created by applying [f e] to each | |
313 | element e of x. ] | |
314 | ||
315 | Since strings are just special forms of lists, all templates that accept | |
316 | lists can also accept strings. | |
317 | ||
318 | [decl [load file]] [/ Loads file. ] | |
319 | [decl [save file x]] [/ Saves x to file. ] | |
320 | ||
321 | load processes files (i.e. markups are significant). If you want to load | |
322 | files verbatim, enclose it in the escape markup. Example: | |
323 | ||
324 | [""[load text.gia]""] | |
325 | ||
326 | Load works similarly to C #include. It is possible to load a file inside | |
327 | a template body. All the templates in the loaded file will be available | |
328 | in the scope where it is loaded. | |
329 | ||
330 | [decl [add a b]] [/ Add a and b. ] | |
331 | [decl [subt a b]] [/ Subract a and b. ] | |
332 | [decl [mult a b]] [/ Multiply a and b. ] | |
333 | [decl [div a b]] [/ Divide a and b. ] | |
334 | [decl [mod a b]] [/ Remainder of a / b. ] | |
335 | ||
336 | All arithmetic templates above expect both arguments to be numeric strings. | |
337 | ||
338 | - | So far, all the templates above are purely functional with no |
338 | + | |
339 | - | sife-effects. We have only two intrinsic templates with side-effects: |
339 | + | |
340 | [decl [and a b]] [/ Returns a and b (boolean logic). ] | |
341 | - | [var x value] [/ declare and define a value ] |
341 | + | |
342 | - | [set x value] [/ assign a new value to a variable ] |
342 | + | |
343 | ||
344 | Other comparisons and booleans can be synthesized from the basics above. | |
345 | For example not can be defined as: | |
346 | - | They can take in any value (strings, lists and even lambda templates |
346 | + | |
347 | - | (see below)). But unlike templates that can be defined but cannot be |
347 | + | |
348 | - | redefined, values of variables are mutable. |
348 | + | |
349 | ne (not-equal) can be defined as: | |
350 | ||
351 | [def [ne a b] [not [eq [a][b]]]], etc. | |
352 | ||
353 | Lambda Templates: | |
354 | ||
355 | Templates are first class and can be passed to and returned from other | |
356 | templates. For example, the transform intrinsic requires a lambda template | |
357 | for its last (f) argument. | |
358 | ||
359 | Here's an example of a lambda template: | |
360 | ||
361 | [lambda [x] [dup [x]]] | |
362 | ||
363 | Its syntax resembles a template definition. | |
364 | ||
365 | Here's a sample invocation of transform: | |
366 | ||
367 | [transform [[a][b][c]] [lambda [x] [dup [x]]]] | |
368 | ||
369 | This doubles all elements of the list: | |
370 | ||
371 | [[aa][bb][cc]] | |
372 | ||
373 | Template arguments: | |
374 | ||
375 | If the arity of the template argument is the same as the one expected, | |
376 | the argument (e.g. Transform expects its f argument to be a unary | |
377 | template. Likewise, dup is also a unary template), the template can | |
378 | be passed as-is. Example: | |
379 | ||
380 | [transform [[a][b][c]] [dup]] | |
381 | ||
382 | Hence: | |
383 | ||
384 | [dup] | |
385 | ||
386 | is a shorthand equivalent to: | |
387 | ||
388 | [lambda [x] [dup [x]]] | |
389 | ||
390 | Scopes: | |
391 | ||
392 | Templates can be placed inside a namespace. Example: | |
393 | ||
394 | [namespace ns | |
395 | [decl [foo x]] | |
396 | [decl [bar x]] | |
397 | ] | |
398 | ||
399 | The template x can be referenced in other scopes using the | |
400 | dot notation. Example: | |
401 | ||
402 | [ns.foo hello, world!] | |
403 | ||
404 | You may import names from other scopes this way: | |
405 | ||
406 | [import ns.foo] [/ Import foo from ns ] | |
407 | [import ns.bar] [/ Import bar from ns ] | |
408 | ||
409 | Then you can use foo and bar without qualification: | |
410 | ||
411 | [foo hello, world!] | |
412 | [bar howdy, joel!] | |
413 | ||
414 | You may also import a whole namespace: | |
415 | ||
416 | [import ns] [/ Import all templates in ns ] | |
417 | ||
418 | All the intrinsics are declared in namespace "std". There is an | |
419 | implicit | |
420 | ||
421 | [import std] | |
422 | ||
423 | before anything else. In case of ambiguity (when template names clash), | |
424 | you can use explicit qualification. Example: | |
425 | ||
426 | [std.plus [1][2]] | |
427 | ||
428 | Standard Library: | |
429 | ||
430 | Apart from the intrinsics, additional support templates are auto-loaded | |
431 | at startup. These templates are all in namespace std. | |
432 | ||
433 | ||
434 | ||
435 | ||
436 | ||
437 | ||
438 | ||
439 | ||
440 | ||
441 |