1 /////////////////////////////////////////////////////////////////////////////
2 // Testing polymorphic datatypes.
3 // (and garbage collection)
4 /////////////////////////////////////////////////////////////////////////////
7 /////////////////////////////////////////////////////////////////////////////
8 // The following datatype equations simulate an abstract syntax
9 // for a small language. All types are garbage collected.
10 /////////////////////////////////////////////////////////////////////////////
11 datatype LIST<T> :: printable collectable
15 and EXP :: printable collectable
18 | add (EXP, EXP) => "(" _ "+" _ ")"
19 | sub (EXP, EXP) => "(" _ "-" _ ")"
20 | mul (EXP, EXP) => "(" _ "*" _ ")"
21 | div (EXP, EXP) => "(" _ "/" _ ")"
22 | list (LIST<EXP>) => _
24 and STMT :: printable collectable
25 = assign_stmt(ID, EXP) => _ ":=" _ ";"
26 | while_stmt (EXP, STMT) => "while" _ "do" { _ } "end while;"
27 | if_stmt (EXP, STMT, STMT) => "if" _ "then" { _ } "else" { _ } "endif;"
28 | block_stmt (LIST<STMT>) => "begin" { _ } "end"
30 where type ID = const char *
33 /////////////////////////////////////////////////////////////////////////////
34 // Instantiate the datatypes.
35 // This will generate a bunch of methods, functions and classes
36 // to implement printing and garbage collection.
37 /////////////////////////////////////////////////////////////////////////////
38 instantiate extern datatype LIST<int>, LIST< EXP >, LIST< STMT >, EXP, STMT;
39 instantiate datatype LIST<int>, LIST< EXP >, LIST< STMT >, EXP, STMT;
43 EXP e1 = add(var("x"),num(1));
44 EXP e2 = sub(var("y"),num(2));
47 while_stmt(e1, block_stmt(#[ assign_stmt("u", e2) ])),
48 assign_stmt("v",num(2))
51 LIST<EXP> list2 = #[ e1, e2, var("z") ];
52 LIST<EXP> list3 = #[ num(-1), list(list2), list(list2) ];
54 cout << "list2 = " << list2 << '\n';
55 cout << "list3 = " << list3 << '\n';
56 cout << "Program =\n" << s1 << '\n';