forked from AaronNGray/prop-cc
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ChangeLog
288 lines (210 loc) · 10.1 KB
/
ChangeLog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
Release 2.4
Updated projects and solution to Visual Studio 2010.
Removed "using namespace std"'s to local std::'s
converted <string.h>'s to <string>'s
support for .pcc and .ph in Visual Studio
Release 2.3.8
Converted tabs to 2 spaces.
Release 2.3.7
Port to Cygwin GCC 3.4.3, Linux GCC 4.0, MS Visual C++ Express 2005
See port.txt
Release 2.3.4
(i) Fixed a few bugs in the translator that caused it not to compile
on g++ 2.7.0.
(ii) Added additional state compression for rewriting tree automata.
We'll now use 1-byte representation for rule set and state tables
whenever possible. One-byte state representation is used whenever
the number of states is <= 256. One-byte rule representation
is used whenever the number of rules is <= 127.
Release 2.3.3
(i) Added system V gc timer code.
(ii) The old view mechanism has been reissued as a new feature, with
some syntactic changes. It should now work with rewriting.
(iii) Added better debugging facilities for rewriting.
(iv) The rewriting modifiers before:, topdown:, bottomup: and after: have been
renamed into the following:
before:
preorder:
topdown:
bottomup:
postorder:
The meaning of preorder: is analogous to that of the old topdown:
while the meaning of postorder: is analogous to the old after:
The topdown mode now correctly normalizes a term.
(v) Missing types in traversal list are now correctly reported.
(vi) A state caching bug creeped into version 2.3.0: the index
is not activated if there are no explicit rewrite statements
in the TRS. This is now fixed.
------------------------------------------------------------------------------
Release 2.3.2
(i) The datatype mapping process has been completely redone.
This affects pretty much everything that has to do with datatypes,
including garbage collection, persistence, and pretty printing.
Previous releases' generated template code had problems.
Code generated by old versions of Prop will NOT work with this release.
(ii) Pretty printing methods generated by Prop now uses the
library class PrettyPOstream defined in <AD/pretty/postream.h>.
This class is still quite rudimentary.
I'll have to think about what to do with pretty printing.
(iii) Added addition code for checking for correct datatype
inheritance, especially inheritance of collectable classes.
Currently only one collectable class may be inherited.
(iv) Adding synthesized value checking in parser generation.
Missing synthesized value in production will give warnings.
(v) Fixed some BigInt, AVL, SplayTree bugs.
(vi) Added template instantiation stuff for g++'s -fno-implicit-templates.
Please see the manual for details.
(vii) Improved syntax error reporting; we now prints out the set of
terminals that can be part of the valid input stream.
Release 2.3.1
(i) Fixed various problems with collectable datatypes.
------------------------------------------------------------------------------
Release 2.3.0
(i) rewriting
Added topdown:, bottomup:, before: and after: modes in rewriting.
Added the indexing mechanism for rewriting. External indices are
still not very well tested, especially GCRewriteCache implemented
with weak pointers.
Added the cutrewrite construct for replacement.
(ii) weakpointers
Changed the GC classes so that weakpointer collection
is automatically performed. Previously, weakpointer collection
is tied with finalization, which makes it possible to get unsafe
results if the user forgets to turn on finalization when using
weakpointers.
Weakpointers collection can be disabled with the
set_weak_pointer_collection() method.
In order to reclaim entries the weak pointer table, we'll try to
perform a garbage collection before the weak pointer table is expanded.
[This may cause excessive garbage collection if a lot of weakpointers
are manipulated. To be fixed later.]
(iii)
Fixed quark literal naming bug. Generated quark literals are now prefixed
with the mangled filename of the source program.
------------------------------------------------------------------------------
Release 2.1
This is *yet* another rewrite of Prop. It has been bootscrapped from
version 2.0.6 (not released), then rewritten using the new features.
Rarely used features and features that have been poorly implemented in
releases 2.0.x have been removed. Among these are:
(1) lexer and parser generation.
(2) hash consing and reference counting.
(3) let ... in { ... }
(4) cost minimization in matching
(5) rule class.
(6) dataview
Some of these will be reintroduced later when better integration with
existing features is developed.
CHANGES
-------
Here are some important changes to the translator.
[1] Mapping of polymorphic datatypes.
Mapping of polymorphic datatypes have been altered. Previously
we use a very elaborate smart pointer class to simulate pointer semantics,
which failed to work consistently on buggy compilers. Now we use macros
instead.
[2] Optimizations on pattern matching.
An adaptive traversal algorithm based on the work of Sekar, Ramesh,
and Ramakrishnan (``Adaptive Pattern Matching'' TR SUNY at Stony Brook, year
199?) has been implemented. This optimization should further
speed up pattern matching and reduce the size of the generated code.
[3] Optimizations on inference.
A limited form of decomposition has been implemented on guard expressions.
Specifically, guards in the form of conjuncts are decomposed and hoisted
to speed up inference object matching. This is similar to ``pushing down
selects'' in database.
[The next step would be to implement indexing on the keys
and faster joins.]
[4] The following changes have been made to the syntax:
[a] The pattern connectives or:, and: and not: have been
eliminated in favor of ||, &&, and ! respectively.
[b] Guards can now be written using a few different syntaxes:
For example,
foo(?x,?y) where predicate(x?,y?):
foo(?x,?y) if predicate(x?,y?);
foo(?x,?y) | predicate(x?,y?);
are all equivalent.
[c] We can now say
foo(?x,?y): ?x
in place of foo(?x,?y): rewrite(?x);
or even foo(?x,?y): { rewrite(?x); }
in a rewrite class.
[d] Certain parenthesis are now optional.
For example,
datatype Tree = empty | leaf (int) | node (Tree, int, Tree);
can now be written as:
datatype Tree = empty | leaf int | node Tree, int, Tree;
[5] Semiunification of non-linear patterns has been (partially) implemented.
Equality tests are automatically generated for repeated variables within
a pattern.
This feature needs a typeclass extension to the type system
to be fully functional.
[6] Minor variant to 'match' called 'match while' has been added:
match[all] while (e1) and (e2) and ... and (en)
{ p1: { action1 }
| p2: { action2 }
| ...
| ...
| pn: { actionn }
}
repeats the matching process until none of the rules matches.
[7] We can now define functions using pattern matching using the
'fun' declaration form. It is an abbreviation for 'match' and
function definition. Mutually recursive functions are
defined using the 'and' connective.
The advantage of this form is that
we can omit naming the arguments and declaring the types
and long as the type inferencer can deduce the types at compile time.
datatype Tree = empty | node Tree, int, Tree;
fun depth empty => int: { return 0; }
| depth node(a,_,b): { return max(depth(a),depth(b)) + 1; }
and flip empty => Tree: { return empty; }
| flip node(a,i,b): { return node(flip(b),i,flip(a)); }
;
[8] Embedded tags optimizations on term representations.
It is now possible to use compact representations that embeds the
variant tag of a datatype into the lower bits of its pointer.
For example, the datatype Tree in
datatype Tree = empty
| leaf int
| node Tree, int, Tree
;
is mapped into the following code by default:
#define empty (a_Tree *)0
class a_Tree
{
public:
enum Tag_Tree { tag_leaf = 0, tag_node = 1; };
protected:
Tag_Tree _tag_;
...
};
class Tree_leaf : public a_Tree { ... };
class Tree_node : public a_Tree { ... };
On the other hand, with the embedded tag anotations '!':
// embedded variant tag
datatype Tree ! = empty
| leaf int ! // embedded argument
| node Tree, int, Tree
;
the class hierarchy can be collasped into just the class
class a_Tree { ... };
The tag field in the base class a_Tree will also be eliminated.
Instead the tag is embedded in the lower bits of the leaf
and node pointers. Furthermore, the integer argument in the
leaf node will actually be imbedded within the pointer for the leaf,
and no heap storage is consumed(the integer will loose a few bits
of precision however, typically 2).
Using this optimization, the variant tag of a term can be accessed
without a load from memory. Furthermore, the terms can all be 1 word
smaller (due to alignment this may not be always true). Of course, bit
masking must now be done to strip the tag bits before we dereference
the pointers. In most machines this requires a single instruction; but
since we can eliminate one load with this optimization, I think things
even out after all even if it's not improved upon.
These optimizations are largely transparent from the application:
the correct pattern matching code will be generated. One possible
exception is that an embedded argument is not mutable.
As always, we generate code assuming that the C++ compiler performs
agressive optimizations such as common subexpression elimination.
[9] User definable lists and array-like constructors