Permalink
Fetching contributors…
Cannot retrieve contributors at this time
113 lines (78 sloc) 4.62 KB
* *
* } {
{ { } }
} }{ {
{ *{ } } * _____ __ __
* }{ }{ * ) / ____| / _|/ _|
.- { { } { }} -. | | ___ | |_| |_ ___ ___
( ( } { } { } } ) -------------------------------------- yerba!
|`-..________ ..-'| | |___| (_) | | | || __/ __/
| | \_____\___/|_| |_| \___|\___|
| ;--.
| (__ \ _____ _ _
| | ) ) / ____| (_) | |
| |/ / | (___ ___ _ __ _ _ __ | |_
| ( / \___ \ / __| '__| | '_ \| __|
| |/ ____) | (__| | | | |_) | |_
| | |_____/ \___|_| |_| .__/ \__|
`-.._________..-' | |
|_|
Yerbascript is an extension of CoffeeScript which allows for syntax extensions (macros).
This can be used to perform expensive evaluations at compile time, or to create your own keywords
which can define variables and/or operate on symbols.
In order to simplify the implimentation and definition of macros, the grammar is standardized to
that of a function. So the calling form is:
myMacro [arg1, arg2, ...]
Perens are optional, just like a coffeescript function. This disallows definition of infix operators,
so if you want to do that you are welcome to fork. :-)
By convention Yerbascript looks for definitions in a macros.coffee file in your project root. Currently
the mechanism for finding the project root is specific to the RZR framework, but in the future it should
be possible to define a predicate specific to whatever structure you prefer for your project.
The macros.coffee file should look like this:
export.macros =
getSymbolName: (context) ->
"some output js"
[... more macro defs]
Each macro is a key-value pair, the key being the name of the new macro, and the value being a compilation
function. The compilation function is passed args:
args: These are the args that get passed to your macro. Bear in mind, they have neither been compiled nor
evaluated yet. You can compile them to a javascript string by calling `arg[n].compile compileContext`. If
you want, you can then eval that string.
And context, an object comprised of:
projectRoot: This is handy for doing relative requires. Your compile function will be executed in the context
of nodes.coffee inside the coffeescript internals, but using this it should be possible for you to rely on
application or 3rd party code in your macro implimentations.
compileContext: Any time you call arg[n].compile you need to pass it this value. This tells
the compiler what level of nesting you are at, whether the target phrase is part of an expression, and
other details. This is referred to in the Coffeescript source as 'o'.
When your compilation function is done, it should return a string. This will become a part of the generated
javascript file whenever your keyword is found within a coffee source.
Bear in mind, the grammar places no restrictions on the number of arguments a macro can accept, so if you
want to enforce this you could add something like this to your compile function:
throw SyntaxError 'foo takes one argument' unless args.length == 1
Because this is a Jison based compiler, adding a new keyword will require a rebuild of the Yerbascript
parser. Fortunately any further changes you make to an existing keyword can be loaded on the fly.
To build the parser just type:
cake build:parser
Happy hacking!
---------
CoffeeScript is a little language that compiles into JavaScript.
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
npm install -g coffee-script
(Leave off the -g if you don't wish to install globally.)
Execute a script:
coffee /path/to/script.coffee
Compile a script:
coffee -c /path/to/script.coffee
For documentation, usage, and examples, see:
http://coffeescript.org/
To suggest a feature, report a bug, or general discussion:
http://github.com/jashkenas/coffee-script/issues/
If you'd like to chat, drop by #coffeescript on Freenode IRC,
or on webchat.freenode.net.
The source repository:
git://github.com/jashkenas/coffee-script.git
All contributors are listed here:
http://github.com/jashkenas/coffee-script/contributors