Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [/=============================================================================
- Gaea text template language!
- Thanks to hkaiser, VeXocide and heller !!! on Spirit IRC
- Thanks to Daniel James, Matias Capeletto and Dave Abrahams
- for added comments and suggestions (Boost Docs List).
- ==============================================================================]
- Reserved tokens:
- [
- ]
- [u
- [def
- [decl
- [lambda
- [import
- [namespace
- [/
- [^
- ["
- [""
- ""]
- \[
- \]
- (the last 2 is for escaping [ and ])
- Comments:
- [/ comments. ]
- [/ nested [/ nested comments] comments. ]
- [/ balanced square braces [ and ] (i.e starts with [ and ends with ] and
- with equal number of [ and ]), are allowed inside comments. This is a
- good way to comment out code. ]
- Markups:
- [*This is a markup]
- [orderedlist [a][b][c]]
- Markups are always significant, except inside escapes (see ["" Escapes
- below) and except as list elements (see List). Like HTML/XML spaces
- are coalesced unless they are inside the preformatted markup
- (see [^ Preformatted below).
- Markup Identifiers:
- Identifiers consist of one or more letters, digits and extended
- characters: ! $ % & * + - . : < = > ? @ _ ` # ' that
- cannot begin a number and cannot conflict with a reserved token.
- Examples:
- This-is-an-identifier
- ?
- *
- ==
- ?WTH
- Simple Strings:
- This is a string
- Jack and Jill went up the hill to fetch a pail of water.
- Jack fell down and broke his crown, and Jill came tumbling after.
- 123 is a numeric string
- Grouped String:
- ["This is grouped a string]
- The [" and ] delimit the extent of the string. A simple form
- of grouped strings are allowed *ONLY* as list (see List below)
- elements:
- [This grouped string is allowed *ONLY* as a list element]
- The double quote is not necessary because bare markups are not
- allowed as list elements. If you need to markup a list element,
- put them in braces:
- [[*A marked-up list element]]
- Marked up Strings:
- This string [*contains] a markup. '*' should better be a
- template, otherwise this is an error.
- [*This] string contains a markup. '*' should better be a
- template, otherwise this is an error.
- Lists:
- A list may contain one or more grouped-string or nested list, but
- not bare markups.
- Examples:
- [[a][b][c]] [/ 1st ]
- [[a][[b][c]]] [/ 2nd ]
- Lists can form linear or hierarchical data structures. 1st is a
- 3-element list [a][b][c]. 2nd is a 2-element list where the first
- element is [a] and the second is a 2-element list [b][c].
- Formatting makes it clear:
- 1st:
- [
- [a][b][c]
- ]
- 2nd:
- [
- [a]
- [
- [b][c]
- ]
- ]
- This is an erroneous list:
- [[a][b][c] duh!] [/ not a list ]
- There should never be "naked" list elements (those without
- braces). That one above is not a list. It is a grouped string;
- and so is this:
- [duh! [a][b][c]] [/ not a list ]
- It is important to keep in mind that lists may not contain bare
- markups. This:
- [[dup x][dup y]]
- will *NOT* expand the 'dup' templates. If you need markups expanded
- in list elements, put them in braces:
- [[[dup x]][[dup y]]]
- Strings as lists:
- A string is just a special form of list with single character elements.
- List elements:
- [
- [This is a grouped string]
- [[*This is a markup]]
- [[a][b][c]] [/ A nested list ]
- [This string [*contains] a markup]
- [[*this] is still a string.]
- [[this is a single element list!]]
- ["[this is *not* a nested list!]] [/ the double quote " prevents this from
- becoming a list (see Protect below)]
- ]
- Nil:
- []
- A nil can be an empty string or an empty list.
- Unicode Code Points:
- [u2018] [/ Generates unicode code point (hexadecimal). ]
- Escapes:
- \[ [/ Escapes the open bracket]
- \] [/ Escapes the close bracket]
- [""x""] [/ Escapes all occurances of [ and ] in x. ]
- Preformatted:
- [^ some-text] [/ Make spaces, tabs and newlines significant ]
- Protect:
- ["* blah] [/ Don't expand * regardless if * is
- a template (or not) ]
- ["[x][y][z]] [/ Don't make this a list ]
- Protect ["* blah] is not really the same as [""* blah""]. Only the
- template * is not expanded. For example, ["* [bar]] will still expand
- bar, while [""* [bar]""] will not evaluate both * and bar.
- Template:
- Forward declarations:
- [decl [foo]]
- [decl [dup a]]
- Forward declarations are good for recursion and is always perfect
- for documentation.
- Definitions:
- [def [pi] 3.14159265] [/ nullary template def ]
- [def pi 3.14159265] [/ short for nullary template def ]
- [def [dup a] [a][a]] [/ arguments are local templates that
- need to be expanded, e.g. [a] ]
- [def [cat a b] [a][b]]
- Template expansion:
- [pi] [/ nullary template ]
- [dup apple pie] [/ unary template. argument is a string. ]
- [dup [apple pie]] [/ unary template. argument is a 1-element list. ]
- [cat [apple][pie]] [/ 2 arguments. argument is a 2-element list. ]
- Optional Named Arguments:
- Any argument can be made optional by preceding the formal argument
- name with the tilde '~'. Example:
- [decl [$ path ~width ~height]]
- The $ template above can be used this way:
- [$image.jpg [~width 200px] [~height 200px]]
- Optional arguments can be placed anywhere in the template expansion.
- Order does not matter:
- [$[~width 200px] image.jpg [~height 200px]] [/ OK]
- [$[~height 200px] [~width 200px] image.jpg] [/ OK]
- Notice too that image.jpg need not be placed inside braces. All optional
- arguments are gathered and what's left should conform to the rules for
- template expansion above; hence becomes:
- [$image.jpg] [/ nullary template ]
- Of course you can place them all inside braces if you want:
- [$[image.jpg] [~width 200px] [~height 200px]]
- Variable args:
- Example:
- [decl [table [~title] . rows]]
- The dot '.' before the last formal argument signifies variable
- number of arguments. It is only allowed before the final formal
- argument. The actual arguments passed are collected in one list.
- Example invocation:
- [table [~title My First Table]
- [[Heading 1] [Heading 2] [Heading 3]]
- [[R0-C0] [R0-C1] [R0-C2]]
- ]
- Again, the list may contain one or more grouped-string or nested list.
- Variables:
- Templates above are purely functional with no sife-effects. Variables
- on the other hand allow side-effects:
- [var x value] [/ declare and define a value ]
- [set x value] [/ assign a new value to a variable ]
- Variables are special beasts. They are the only means for imperative
- programming in the language. They respect the same scope as templates.
- You cannot have a template and a variable with the same name. They can
- take in any value (strings, lists and even lambda templates (see
- below)). But unlike constant templates which cannot be redefined, values
- of variables are mutable.
- Intrinsics:
- [decl [head x]] [/ Get first element from x. ]
- [decl [tail x]] [/ Return a list or string without the first element of x. ]
- [decl [empty x]] [/ Return 1 if x is empty else 0. ]
- [decl [at x n]] [/ Return the nth element of x. ]
- [decl [size x]] [/ Return size of x. ]
- [decl [append x e]] [/ Append e to x. ]
- [decl [insert x e n]] [/ Insert e to x at position n. ]
- [decl [reverse x]] [/ Reverse x. ]
- [decl [join x y]] [/ Join x and y as one longer list. ]
- [decl [fold x s f]] [/ For a list x, initial state s, and binary template f,
- fold returns the result of the repeated application of
- [f e s] for each element e of list x, to the result
- of the previous f invocation (s if it is the first call). ]
- Many list operations can be implemented using fold. Yet, for the sake
- of efficiency, we provide these common operations as intrinsics.
- [decl [transform x f]] [/ For a list x and template f, transform returns a new
- list with elements created by applying [f e] to each
- element e of x. ]
- Since strings are just special forms of lists, all templates that accept
- lists can also accept strings.
- [decl [load file]] [/ Loads file. ]
- [decl [save file x]] [/ Saves x to file. ]
- load processes files (i.e. markups are significant). If you want to load
- files verbatim, enclose it in the escape markup. Example:
- [""[load text.gia]""]
- Load works similarly to C #include. It is possible to load a file inside
- a template body. All the templates in the loaded file will be available
- in the scope where it is loaded.
- [decl [add a b]] [/ Add a and b. ]
- [decl [subt a b]] [/ Subract a and b. ]
- [decl [mult a b]] [/ Multiply a and b. ]
- [decl [div a b]] [/ Divide a and b. ]
- [decl [mod a b]] [/ Remainder of a / b. ]
- All arithmetic templates above expect both arguments to be numeric strings.
- [decl [eq a b]] [/ Returns 1 if a == b. ]
- [decl [lt a b]] [/ Returns 1 if a is less than b. ]
- [decl [and a b]] [/ Returns a and b (boolean logic). ]
- [decl [or a b]] [/ Returns a or b (boolean logic). ]
- [decl [if cond then else]] [/ Returns then if cond is 1, otherwise returns else. ]
- Other comparisons and booleans can be synthesized from the basics above.
- For example not can be defined as:
- [def [not x] [if [x][0][1]]]
- ne (not-equal) can be defined as:
- [def [ne a b] [not [eq [a][b]]]], etc.
- Lambda Templates:
- Templates are first class and can be passed to and returned from other
- templates. For example, the transform intrinsic requires a lambda template
- for its last (f) argument.
- Here's an example of a lambda template:
- [lambda [x] [dup [x]]]
- Its syntax resembles a template definition.
- Here's a sample invocation of transform:
- [transform [[a][b][c]] [lambda [x] [dup [x]]]]
- This doubles all elements of the list:
- [[aa][bb][cc]]
- Template arguments:
- If the arity of the template argument is the same as the one expected,
- the argument (e.g. Transform expects its f argument to be a unary
- template. Likewise, dup is also a unary template), the template can
- be passed as-is. Example:
- [transform [[a][b][c]] [dup]]
- Hence:
- [dup]
- is a shorthand equivalent to:
- [lambda [x] [dup [x]]]
- Scopes:
- Templates can be placed inside a namespace. Example:
- [namespace ns
- [decl [foo x]]
- [decl [bar x]]
- ]
- The template x can be referenced in other scopes using the
- dot notation. Example:
- [ns.foo hello, world!]
- You may import names from other scopes this way:
- [import ns.foo] [/ Import foo from ns ]
- [import ns.bar] [/ Import bar from ns ]
- Then you can use foo and bar without qualification:
- [foo hello, world!]
- [bar howdy, joel!]
- You may also import a whole namespace:
- [import ns] [/ Import all templates in ns ]
- All the intrinsics are declared in namespace "std". There is an
- implicit
- [import std]
- before anything else. In case of ambiguity (when template names clash),
- you can use explicit qualification. Example:
- [std.plus [1][2]]
- Standard Library:
- Apart from the intrinsics, additional support templates are auto-loaded
- at startup. These templates are all in namespace std.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement