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 |