This chapter documents important changes in the Tom language that impact
running code. We explain how to modify your programs in order to be able to use the last version of Tom.
13.1 Migration from 2.3 to 2.4
Builtins
Since version 2.4, builtin sorts (int, long, String, etc.) are no longer
implicit. The corresponding %include { ... } must be done explicitly.
Gom, Vas, and ApiGen
Since version 2.4, ApiGen and Vas are obsolete. Gom should be used instead.
13.2 Migration from 2.2 to 2.3
Mapping definition and term notation
To avoid ambiguities, since version 2.3, constants should be written using
explicit parentheses: a(), nil(), for example.
To be coherent, the parentheses have also to be used in the mapping definition:
Static functions
Since version 2.3, Tom generate static functions in Java, instead of
object methods. This allows to use Tom constructs in the main()
function, this improves the efficiency of the generated code, and this makes
safer the use of strategies.
To be compatible with the previous version, the –noStatic flag can be
used.
From Vas to Gom
In the future, Gom will replace Vas.
To make the migration easier, the Gom compiler accepts the Vas syntax.
However, there are some minor changes:
-
in Gom the importation of builtin modules (int,
String,...) should be explicit,
- when using the new ML-like syntax, the defined sorts should no longer be
declared,
- factories are no longer needed by the generated code. As a consequence,
Java imports and constructors are simpler,
- the methods to get and set values of subterms are named after the slot
name: for a slot named slot of type SlotType, the access and
modification are getslot() and setslot(SlotName value).
The String getName() function is now String symbolName(), and
there is no more int getArity().
- The methods boolean isOperator() now use the exact name of the
operator, without capitalizing it.
- when defining a list-operator, Gom automatically generates Java access
functions. getHead, getTail, and isEmpty are replaced
respectively by getHeadconc, getTailconc, and
isEmptyconc
for a list-operator named conc.
- objects generated by Gom do no longer implement the ATerm interface.
Therefore, some functionalities have disappear. In particular,
genericCollect and genericTraversal can no longer be used. The
strategy language has to be used instead.
- to implement strategies on a module Module, the class
ModuleBasicStrategy replaces the ModuleVisitableFwd of Vas.
13.3 Migration from 2.1 to 2.2
Mapping definition
Since version 2.2, the mapping definition formalism has been
simplified. Therefore, we are no longer able to be fully compatible
with the old syntax. Some small and simple modifications have to be
performed:
-
in %op, the slot-names are no longer optional. For each
argument of a constructor, a name has to be given. This name can
then be used within the “bracket” notation.
%op T f(T,T) has to be replaced by %op T
f(arg1:T,arg2:T), where arg1 and arg2 are slot-names.
- for each slot-name, a get_slot(name,t) construct has
to be specified. This defines, given an object t, how to
access to the slot-name named name.
The definition of get_slot can be defined by using the
previously defined construct get_subterm (the first slot
corresponds to the 0−th subterm, second slot to the 1−st
subterm, etc.).
Thus, for the previous example, we can have:
%op T f(arg1:T, arg2:T) {
get_slot(arg1,t) { get_subterm(t,0) }
get_slot(arg2,t) { get_subterm(t,1) }
}
- for each operator (%op, %oplist, and
%oparray), the is_fsym(t) predicate has to be
defined. This function should return true when t is
rooted by the considered symbol, and false otherwise.
In practice, the constructs can be deduced by combining
get_fun_sym, cmp_fun_sym, and fsym:
%op T f(arg1:T, arg2:T) {
is_fsym(t) { cmp_fun_sym(get_fun_sym(t), body of the old fsym construct) }
get_slot(arg1,t) { get_subterm(t,0) }
get_slot(arg2,t) { get_subterm(t,1) }
}
- in %oplist, get_head, get_tail, and
is_empty have to be defined.
In practice, these definitions have to be copied from
%typelist to %oplist
- in %oparray, get_element, and get_size have to be defined.
In practice, these definitions have to be copied from
%typearray to %oparray
- %typelist, and %typearray do no longer exist:
%typeterm has to be used to define any kind of sort. This is
not a problem since access functions are now defined inside operator
definitions (%op, %oplist, or %oparray)
- get_fun_sym, cmp_fun_sym, and
get_subterm do no longer exist in %typeterm
- fsym do no longer exists in %op, %oplist,
and %oparray
As an example, let us consider the following “old” mapping
definition:
%typeterm TomTerm {
implement { ATermAppl }
cmp_fun_sym(t1,t2) { t1 == t2 }
get_fun_sym(t) { t.getName() }
get_subterm(t, n) { t.getArgument(n) }
equals(t1, t2) { t1 == t2 }
}
%typelist TomList {
implement { ATermList }
get_fun_sym(t) { ((t instanceof ATermList)?"conc":null) }
cmp_fun_sym(t1,t2) { t1 == t2 }
equals(l1,l2) { l1 == l2 }
get_head(l) { (ATermAppl)l.getFirst() }
get_tail(l) { l.getNext() }
is_empty(l) { l.isEmpty() }
}
%op TomTerm a {
fsym { "a" }
make() { factory.makeAppl(factory.makeAFun("a", 0, false)) }
}
%op TomTerm f(TomTerm) {
fsym { "f" }
make(t1) { factory.makeAppl(factory.makeAFun("f", 1, false),t1) }
}
%oplist TomList conc( TomTerm* ) {
fsym { "conc" }
make_empty() { factory.makeList() }
make_insert(e,l) { l.insert(e) }
}
The two first type definitions have to be replaced by:
%typeterm TomTerm {
implement { ATermAppl }
equals(t1, t2) { t1 == t2 }
}
%typeterm TomList {
implement { ATermList }
equals(l1,l2) { l1 == l2 }
}
The operator definition can be replaced by the following code:
%op TomTerm a {
is_fsym(t) { t.getName() == "a" }
make() { factory.makeAppl(factory.makeAFun("a", 0, false)) }
}
%op TomTerm f(arg:TomTerm) {
is_fsym(t) { t.getName() == "f" }
get_slot(arg,t) { (TomTerm) t.getArgument(t,0) }
make(t1) { factory.makeAppl(factory.makeAFun("f", 1, false),t1) }
}
%oplist TomList conc( TomTerm* ) {
is_fsym(t) { t instanceof ATermList }
get_head(l) { (ATermAppl)l.getFirst() }
get_tail(l) { l.getNext() }
is_empty(l) { l.isEmpty() }
make_empty() { factory.makeList() }
make_insert(e,l) { l.insert(e) }
}
Disjunction of patterns
Since version 2.2, the disjunction of patterns construct has become
deprecated. It can still be used, but we recommend to use the
disjunction of symbols instead.
This last construct allows to share patterns which have similar
subterms but different head-symbols. Therefore, the construct
g(g(a)) ∣ g(h(a)) can be replaced by g( (g ∣ h)(a) ).
Since version 2.2, this construct has been extended to support
disjunction of symbols which do not have identical signature: only
involved slots have to be compatible.
Considering %op T f(arg1:T, arg2:T) and %op T
g(arg1:T), it is now possible to write g( (g ∣ f)[arg1=a] ).
Variable
To prepare a future extension where variables have to be distinguished from
constructors of arity 0, we have turned into error all ambiguities
between variables and constructors.
As a consequence, a variable cannot any longer have the same name as a constant.
Vas
Since version 2.2, ApiGen and Vas have been updated:
-
name of list-operators defined in Vas are now significant
and can be used in match constructs.
- generated Tom mappings are now stored in the same directory
as the generated factory. In practice, imports of the form
%include{ file.tom } have to be replace by
%include{ package/file.tom }.
Strategy library
The TravelerFactory class has been removed and replaced by a
Tom mapping: mutraveler.tom. Therefore, backquote notation
has to be used:
travelerFactory.Repeat(travelerFactory.OnceBottomUp(rule)) is
replaced by `Repeat(OnceBottomUp(rule)).
13.4 Migration from 2.0 to 2.1
Tom library
Since version 2.1, the runtime library has been reorganized. Java
importations have to be updated according to the following hierarchy:
tom
|--- library
| |--- adt (datatype definitions)
| |--- mapping (predefined mapping)
| |--- adt (generated mapping)
| |--- plugin (platform tools)
| |--- set (to handle sets)
| |--- strategy
| |--- concurrent (to support parallel strategy)
| |--- traversal (generic traversal)
| |--- xml (xml tools)
|
|--- platform (the Tom Plugin Platform, known as Tom server)
|--- adt
Command line options
-
–protected is a new option which makes Tom
generates protected access functions. By default, access functions
are now private instead of public,
- –noWarning has been replaced by its dual
–wall (for printing warnings).
13.5 Migration from 1.5 to 2.0
New backquote usage
Since version 2.0, Tom integrates an optimizer which removes unused
variable assignments and performs inlining optimizations.
In order to make these optimizations correct, the Tom compiler needs
to know whether a Tom variable (instantiated by pattern matching) is
used or not.
In previous versions of Tom, it was possible to use or re-assign a
Tom variable without any particular requirement.
Since version 2.0, it is recommended (and needed if you want to use
the optimizer) to use the backquote mechanism to retrieve the value of
a Tom variable.
The syntax of a backquote construct has been modified in the following
way:
-
`Name (like `x) is now correct.
This allows access to the value of a Tom variable.
This construct also allows access to the value of list-variable,
but the `Name`*' construct is to be preferred,
- `Name`*' (like `X*) is now correct.
This allows access to the value of a Tom list-variable,
- `Name( ... ) is correct, as in
previous versions. This construct builds a term in memory,
- `( ... ) is now correct and can be used to
simulate the previous syntax.
Since version 2.0, it is no longer possible to start a backquote
construct by using something different from a Name or a `('.
Thus, `1+x is no longer valid: `(1+x) or 1+`x
has to be used instead,
- `xml( ... ) has to be used to create an Xml
term.
Command line options
-
–destdir (short version: -d) option: as in
javac, this option specify where to place generated
files,
- –output (short version: -o) option: as in
gcc, this option specify the name of the
unique generated file. This option is not compatible
with –destdir,
- -o is no longer the short version of –noOutput.
Predefined mapping
Since version 2.0, Tom does no longer support predefined builtin
sorts, via %typeint, %typestring or
%typedouble.
Tom comes now with a library of predefined mappings. Among them,
int.tom, string.tom and double.tom.
In order to use these mappings, the %include construct should
be used (i.e. %include{ int.tom } to import the predefined
int mapping).