Stratego/XT 0.17 - released July 2009
ulimit -s unlimited
, or with any bigger stack size than the current one.
See the installation instructions if you are not familiar with the standard installation procedure of tarballs or RPMs.
Source tar.gz
SuSE Linux RPM
SuSE 11.0:
SuSE 10.3:
Fedora Core RPM
Fedora Core 11:
Fedora Core 10:
Fedora Core 9:
Fedora Core 5:
Debian DEB
Debian 5.0:
Debian 4.0:
Ubuntu DEB
Ubuntu 9.04:
Ubuntu 8.10:
Ubuntu 8.04:
Microsoft Windows Cygwin binaries
README
with installation instructions.
Mac OS X binaries
README
with installation instructions.
Nix Package
One-click installation using Nix, open with nix-install-package
The Stratego/XT Manual is a series of three books: a tutorial, a series of examples, and a reference manual with the finer details of the language and tools. The manual is available online and can be downloaded for offline use.
Warning: this manual is specific for Stratego/XT 0.17 and will not be extended. The latest version of the manual, available at at the documentation page, might be more extensive, but might also cover features that were not yet available in Stratego/XT 0.17.
Online API documentation:
Download API documentation for local and offline use:
Stratego/XT is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
Despite the disclaimer above we do our best to help users of Stratego/XT. Subscribe to the Stratego mailing lists, in particular the stratego-announce and stratego mailing lists to get announcements of new releases and ask questions about usage of the languages and tools. Also we're interested to know what people are using Stratego/XT for and how it might be improved, so feel free to drop us a line.
Stratego/XT 0.17 introduces major improvements across the board, including language additions, a new compiler library, numerous improvements to the compiler, significant changes to the library handling, new libraries for parsing, pretty printing and term validation, 64-bit support, stack traces and more.
For this release, over 200 outstanding issues have been addressed, much thanks to the efforts of external bug reporters and contributors.
The manual has been updated to reflect the changes made to the language and libraries, and the new libraries come with up-to-date source code documentation.
M. Bravenboer, K. T. Kalleberg, R. Vermaas, and E. Visser. Stratego/XT 0.17. A Language and Toolset for Program Transformation. Science of Computer Programming, 2008. Special issue on Experimental Systems and Tools, http://dx.doi.org/10.1016/j.scico.2007.11.003
The backend has been changed so that the GCC-specific nested functions feature is no longer required. This makes the C-code a lot more portable across GCC-supported platforms, since nested functions are not reliably supported on all architectures, notably not on MIPS and OSX/Intel. Furthermore, this allows Stratego to use other C compilers for than GCC for the generation of platform-specific binary code.
The compiler backend and supporting runtime code have been modified to provide full stack traces for the dreaded "rewriting failed" situations.
Consider the following program:
main = foo foo = bar bar = fap ; zap fap = id zap = fail
When executed, it will print:
prog: rewriting failed, trace: main_0_0 foo_0_0 bar_0_0 zap_0_0
This also works when you use io-wrap
and friends, but there are some
caveats:
let
blocks and other reasons for lifting will show up as
lifted_X
frames.
A tiny set of stack introspection strategies for debugging purposes has also been introduced.
A new with
construct has been added for rewrite rules, which makes
use of the stack tracing feature above. A with
clause works much
like a regular where
clause, and can for example be used to assign
variables for use in the right-hand side of a rule:
desugar: |[ e1 + e2 ]| -> |[ x_add(e1, e2) ]| where <typeof> e1 => Int() ; <typeof> e2 => Int() with x_add := <new-add-operation> (e1, e2)
However, unlike the where
clause, its operations are not allowed to
fail, or a run-time error will be reported with a stack trace. Thus,
this addition allows Stratego programmers to explicitly distinguish
between conditions of a rule (the where
clause) and operations
that must always succeed (the with
clause). This helps in
readability and in debugging errors in rewrite rules. Any failures
inside a with
clause are considered programmer errors: the contract
specified by the with
clause is then not satisfied (for example, a
rule may require some dynamic rule to be defined). By immediately
reporting such errors, this feature allows them to be quickly
identified, avoiding problems that are only detected in the result of
a transformation (e.g., after some rules did not fire in a
topdown(try(s)) strategy).
For every rewrite rule, an unrestricted number of with
and where
clauses can be used. In strategies, with
can be used as a strategy
invocation, similar to where
(e.g., with(<may-not-fail> t)
).
The compiler has been librarified. Program analysis and transformation tools which work on Stratego code may now be based on the Stratego compiler library. The intent is to make meta-programming with Stratego a lot easier and speedup the Stratego compiler.
An assignment operator has been added to the language as a more
attractive syntax for the common pattern s => t
. In the assignment
operator, the variable name is now before the right-hand side. Also,
the right-hand side is a term pattern.
get-signature(|file) : Method(_, returntype, name, types, _, _) -> MethodSignature(cn, returntype, name, types) where cn := <get-classname> file
This used to be written as:
<get-classname> file => cn
Note that this is a purely syntactic change: the variable can only be assigned to once.
Thanks to Bogdan Dumitriu, the dynamic rule facility of Stratego has been
extended to deal with additional control flow constructs, including break,
break to label, continue and exceptions (try-catch-finally). Some of the
dynamic rule strategies, such as dr-fix-and-intersect
and dr-fix-and-union
have been extended to work with labels, and new dynamic rule prefixes break-
and break-to-label-
are introduced.
A presentation from Stratego User Days 2006 provides a high-level walk-through.
Stratego now supports scoped global variables. In the context of a dynamic rules section one can now write
rules( Foo := <compute> )which abbreviates the following commonly used programming pattern:
x := <compute> ; rules( Foo : _ -> x )The value bound in the assignment can be retrieved by the application <Foo>. The usual scoping features of dynamic rules apply to global variable as well. For more information see this blog.
A useful extension to the standard strategies generated for invoking dynamic rules such as bagof-Foo, once-Foo, etc.
The idea is that it is in general useful to apply a sequence of dynamic rules, but not produce all possible results, but chain each result to the next dynamic rule invocation.
Suppose that you have two dynamic rules defined:
Foo : x -> (1, x) Foo : x -> (2, x)
With these two rules defined, applying
In this way, you can apply a series of dynamic rules to a term. Note that you can achieve this with repeat(once-Foo) as well, but once-Foo will remove the rule from the environment, which is not always desirable.
While chain-Foo only applies the rules visible in the current scope, bigchain-Foo applies the rules from all scopes.
While proper strategy definitions that are imported as externals are not exported as externals from a library (as per August 2006), constructors imported by a library, were also exported by that library. This caused congruences to be regenerated, possibly not in that same library, but in a library one step further in the import chain. Thus, the external definitions for congruences from an imported library, prevented generation of new congruences. However, since imported external definitions are not exported, the next library does not see those congruence definitions, and will re-generate them; giving rise to a warning when the external definition for this new congruence is imported in another application or library.
To solve this issue constructors are now treated in the same way as strategy definitions.
There is now a notion of "external" constructor declarations. Syntax:
external Foo : A * B -> C
These external constructor declarations are exported by a library along with the external definitions for the strategies in the library. Thus, importing libraries and programs can use these constructors in rules and strategies.
However, external constructors are not exported from an importing library. Just like external definitions are not exported from an importing library. This entails that a third library that imports the second, does not get the constructor declarations of the first. In order to use those, the first library needs to be imported explicitly. Here is an example:
Library A ----------------- module A constructors Foo : A -----------------> module libA constructors external Foo : A ----------------- Library B ----------------- module B imports libA strategies bar = !Foo() // constructor Foo is available through libA import -----------------> module libB strategies external bar // only strategy bar is exported, not constructor Foo ----------------- Library or Application C ----------------- module C imports libB strategies baz = !Foo(); ...; bar // error! libB does not export constructor Foo ------------------ Library or Application C // corrected ----------------- module C imports libB libA strategies baz = !Foo(); ...; bar // Foo is imported through libA ------------------
This change may break existing code; explicit imports of indirectly imported libraries are needed. In practice, the change had a minimal impact on the code in Stratego/XT and derived projects.
The let
construct now allows the defition of rules in addition to strategies:
let R : p1 -> p2 in ... end
A new language construct called import-term
was added which allows
the embedding of terms (data) directly into the program.
get-pp-table = import-term(pptable.trm)
This removes the need for external data files, such as parse and pretty-print tables. The resulting executable is self-contained, thus making deployment of your program transformation tools easier.
A new discipline for library naming and usage is introduces in
0.17. The standard library is now named libstratego-lib
, whereas the
XTC library is named libstratego-xtc
. Additional libraries have been
added for parsing, pretty printing and term validation, see below.
To avoid the term serialization paid when composing transformation pipelines using XTC, the compiler and all supporting tools have been rearchitected as libraries in addition to the familiar XTC components.
For Stratego/XT users, the most significant change is that the SGLR
parser, the various RTG tools and the GPP tools are now available as
libraries, respectively named libstratego-sglr
, libstratego-rtg
and libstratego-gpp
.
The librarification allows parse tables to be loaded once, at startup,
and used repeatedly when multiple files must be parsed (when using
XTC, the parse table is loaded by the sglr
child process every time
a file must be parsed).
Consider the following program:
module foo imports libstratego-lib libstratego-sglr strategies main = tbl := <import-term(Exp.tbl); open-parse-table> ; <parse-string(|tbl)> "a+b"
It assumes the existence of a parse table (Exp.tbl
). This table is
included into the program using the import-term
construct
(introduced above). The call to open-parse-table
will register the
parse table with the libstratego-sglr
library, and subsequent calls
to parse-string
will not need to reload the parse table.
Compiling and executing the program:
$ strc -i foo.str $(strcflags stratego-lib stratego-sglr) $ ./foo Plus(Var("a"),Var("b"))
The resulting program foo
is now fully self-contained. It does not need
the Exp.tbl
file to execute.
API documentation for the Stratego Libraries is available from the Documentation page on the Stratego/XT website.
The new tool strcflags
makes it no longer necessary to know all the
details of how to invoke the Stratego compiler when you're using a
certain library. Given the name of a package or Stratego library, the
tool returns the flags (such as include paths) for strc.
Example:
$ strc -i foo.str $(strcflags stratego-lib)
You can also specify multiple packages. For example, if you're using java-front, then you are usually using the Stratego library as well.
$ strc -i foo.str $(strcflags stratego-lib java-front)
The tool strcflags is a simple wrapper around the tool pkg-config
,
which we are using for configuring Stratego/XT packages when building
packages from source.
To support strcflags with your own packages, add a declaration of a
variable strcflags
to the pkg-config .pc
files.
Creating libraries using the Stratego compiler has never been
easier. By using the --library
option to the compiler, all necessary
library files will be created.
$ strc -i foo.str --library
The resulting output includes static and dynamic libraries, as well as libtool support files:
libfoo.a libfoo.c libfoo.la libfoo.lo libfoo.o libfoo.rtree libfoo.so
This option is intended for creating libraries that are not part of an
autoconf/automake package, similar to invoking strc
to compile a
program all the way to an executable.
This release brings about major improvements to the deployment capabilities of Stratego/XT.
The Stratego libraries expose various features from the underlying platform Stratego/XT executes on. In 0.17, the library has been refactored so that the dependence on platforms is clearer, and this gives rise to several variants of the library, including one for C99, POSIX and one for POSIX+XSI. The great majority of Stratego/XT programs, use the high-level strategies for file and term I/O, and these programs will be unaffected.
The main benefit of this change is that we can now build all the Stratego libraries on platforms that only support functions from standard C99 (i.e. not full POSIX). This enables the deployment of Stratego applications on such platforms. Some strategies from the Stratego library are only available in the POSIX and POSIX+XSI extensions. The name of the modules defining these strategies reflect this.
Stratego/XT now supports compiling natively on Microsoft Windows using MinGW. This results in a smaller footprint because of significantly fewer and smaller dependencies as compared with Cygwin.
Binaries created for MinGW can be deployed to Microsoft Windows users without any dependencies.
For this purpose, the stratego-libraries
package is also available
separately from Stratego/XT as source tarball and native Microsoft
Windows binaries. If you already have Stratego/XT, then there is no
need to install the stratego-libraries
.
Stratego/XT 0.17 now fully supports OSX on PowerPC as well as Intel CPUs.
Thanks to patches from Eelco Dolstra, the ATerm library now supports 64-bit machines, and the final blocker preventing Stratego/XT running on 64-bit is now removed. This means 64-bit support is finally here. Binary packages for 64-bit Linux distributions are provided for your convenience.
The full list of issues closed in this release is available at:
The release page contains the source distributions, binary RPMs, and detailed instructions on how to install the distributions:
See our issue tracking systems for reports about (open) bugs:
Please report any problems with installation or bugs in the implementation to our issue tracking system. Please check the existing issues to see if a report about the problem was already submitted.
Developments, bug reports, and beta tests carried out by
Thanks!