a .NET hosted scripting language with a focus on meta-programming and embedded DSLs
I just committed pushed the collection helper functions I call █████████ ████████ █████████ (psr) to SVN GitHub.
Following is a short documentation (or rather an overview) of psr:
The psr is a collection of scripts that help in day-to-day hacking with Prexonite Script. This page shortly outlines the contents of each of the currently available files.
The script enables special treating of the debug command using compiler hooks for increased performance. For each call to the debug command, it checks whether the function requests debugging (through the debugging
MetaKey). Unless that is the case, the call will be removed. if
-Blocks using debug as their condition will be evaluated at compile time in respect to the debugging
key.
It is possible to use the debug
command without including this script, in that case, however, your scripts will also contain calls to debug when not being debugged.
The actual functionality of this script has been moved to managed code inside the Prexonite.dll for performance reasons. CompilerHooks have to be used with care. While the loss in compiler performance is barely noticeable with just one user-defined CompilerHook, many of them can really slow the translation down. The managed implementation uses a shared CompilerHook to further save time, should Prexonite.dll ever include additional CompilerHooks.
The script contains numerous functions that will prove invaluable when writing CompilerHooks in Prexonite Script. It's most important function is ast
.
It dynamically invokes constructors of AstNodes and supplies common arguments. The signature of the AstConstant node is AstConstant(string file, int line, int column, object constant)
, ast
reduces that to ast("Constant",yourConstant)
Other notable functions include
See the file for detailed information.
The script demonstrates the use of ast.pxs. It defines the function times(x) which, when used in a while loop, automatically transforms it into a for loop with x iterations.
The script defines numerous functions useful when handling lists. Most of them are implemented as coroutines. It includes functions like map
, where
and range
but also union
, intersect
and groupby
.
A sample expression that makes use of the right-append operator >>
to prevent complex nesting.
[1, 6, 8, 12, 15, 20, 99 ]>>
where( x => x> 10)>>
orderby( (a,b) =>
if(a> b)
1
else if(a >
groupby( x => x mod 2)>>
select ( g =>
( if(g.Key == 0)
"even"
else
"odd"
): g.Value
)>>
all
is an expression that returns [ odd: [99, 15], even: [20,12]]
The functions are wricodeen against the IEnumerable interface (late-bound, user objects have to support GetEnumerator
) and are therefor not limited to Prexonite lists.
This script defines just one function struct
which uses the Prexonite object model to automate the creation of structures for the user. Have a look at the sample from the file:
function CreateLazyValue(factory)
{
var v;
function Evaluated = factory is Null;
function Value
{
if(!Evaluated)
{
v = factory.();
factory = null;
}
return v;
}
return struct;
}
The structure returned will have to methods Evaluated
and Value
.
struct
automatically searches for nested function definitions and assigns the corresponding closures to the structure.
This way all methods refer to the same v
and ref factory
as if they were fields. This approach is fine as long as you don't need actual fields or cloning (because the methods cannot be separated from their common environment).
This script defines the function create_stack
which &emdash; what a surprise &emdash; creates a stack.
The returned structure reacts to push(value1, ...)
, pop
, peek
, count
as well as clear
.
It is not possible to retrieve (and manipulate) the underlying list.
Stack is implemented using struct
and therefor does not support cloning.