Make tests independent of tagged value representation.
catseye
12 years ago
924 | 924 | | fun main() { |
925 | 925 | | var a = 20; |
926 | 926 | | var b = 30; |
927 | | a + b as integer in union(integer, string) | |
928 | | } | |
929 | = ('Type(integer:)', 50) | |
930 | ||
931 | All good looks like this: | |
932 | ||
933 | | fun main() { | |
934 | | var a = 20; | |
935 | | var b = 30; | |
936 | | a + b as integer in union(integer, string) | |
937 | | } | |
938 | = ('Type(integer:)', 50) | |
939 | ||
940 | Union types. | |
927 | | var c = a + b as integer in union(integer, string) | |
928 | | print("ok") | |
929 | | } | |
930 | = ok | |
931 | ||
932 | Values of union type can be passed to functions. | |
941 | 933 | |
942 | 934 | | fun foo(a, b: union(integer, string)) { |
943 | 935 | | a + 1 |
970 | 962 | | } |
971 | 963 | = 337 |
972 | 964 | |
965 | The expression in a `typecase` must be a variable. | |
966 | ||
967 | | main = fun() { | |
968 | | var a = 333 as integer in union(integer, string); | |
969 | | typecase 333 is integer { | |
970 | | print("what?") | |
971 | | }; | |
972 | | } | |
973 | ? identifier | |
974 | ||
975 | The expression in a `typecase` can be an argument. | |
976 | ||
977 | | fun wat(j: union(integer, string)) { | |
978 | | typecase j is integer { | |
979 | | print("integer") | |
980 | | }; | |
981 | | } | |
982 | | main = fun() { | |
983 | | wat(444 as integer in union(integer, string)) | |
984 | | } | |
985 | = integer | |
986 | ||
987 | The expression in a `typecase` cannot effectively be a global, as globals | |
988 | must be literals and there is no way (right now) to make a literal of union | |
989 | type. | |
990 | ||
973 | 991 | This is a very strange case in the language. Thankfully, assignment |
974 | 992 | typechecks as void, without any automatic promotion to the union type... |
975 | 993 | |
989 | 1007 | |
990 | 1008 | ### Struct Types + Union Types ### |
991 | 1009 | |
992 | Union types may be used to make fields "nullable", so that | |
993 | you can actually make finite, recursive data types. | |
1010 | Union types may be used to make fields of a struct "nullable", so that | |
1011 | you can in actuality create recursive, but finite, data structures. | |
994 | 1012 | |
995 | 1013 | | struct list { |
996 | 1014 | | value: string; |
12 | 12 | Builtins: `int`, `str`, `chr`, `ord`. |
13 | 13 | |
14 | 14 | Tests for empty structs. Demo of "typed enum" (union of empty structs.) |
15 | ||
16 | Type promotion with higher precedence? So that it can be used at toplevel. | |
15 | 17 | |
16 | 18 | ### Implementation ### |
17 | 19 |
22 | 22 | |
23 | 23 | /* |
24 | 24 | var stdin = process.openStdin(); |
25 | // node.js does not make this easy. forgetting about it for now. | |
25 | // node.js does not make this easy -- not unless I want to | |
26 | // generate code in cps! forgetting about it for now. | |
26 | 27 | var input = function(s) { |
27 | 28 | var answer = undefined; |
28 | 29 | stdin.on('data', function(chunk) { answer = chunk; }); |
46 | 47 | return ""; |
47 | 48 | } else if (o === null) { |
48 | 49 | return "None"; |
49 | } else if (typeof o === "object") { | |
50 | var s = "("; | |
51 | for (var i = 0; i < o.length; i++) { | |
52 | s += repr(o[i]); | |
53 | if (i != o.length - 1) { s += ', '; } | |
54 | } | |
55 | s += ")"; | |
56 | return s; | |
57 | 50 | } else { |
58 | 51 | return o; |
59 | 52 | } |
57 | 57 | return "None" |
58 | 58 | elsif o.is_a? String |
59 | 59 | return "'" + o + "'" |
60 | elsif o.is_a? Array | |
61 | if o.length == 0 then return "()" end | |
62 | h = "(" | |
63 | for c in o[0..o.length-2] do | |
64 | h += repr(c) + ", " | |
65 | end | |
66 | return h + repr(o[o.length-1]) + ")" | |
67 | 60 | else |
68 | 61 | return o.to_s |
69 | 62 | end |
168 | 161 | elif ast.type == 'Make': |
169 | 162 | self.out.write('{') |
170 | 163 | self.commas(ast.children[1:]) |
171 | self.out.write(", '_fieldnames', [") | |
172 | for fieldinit in ast.children[1:-1]: | |
173 | self.out.write("'%s', " % fieldinit.value) | |
174 | self.out.write("'%s'" % ast.children[-1].value) | |
175 | self.out.write(']}') | |
164 | self.out.write('}') | |
176 | 165 | elif ast.type == 'FieldInit': |
177 | 166 | self.out.write("'%s'," % ast.value) |
178 | 167 | self.compile(ast.children[0]) |