aa
TestParse.java
Go to the documentation of this file.
1 package com.cliffc.aa;
2 
3 import com.cliffc.aa.type.*;
4 import com.cliffc.aa.util.SB;
5 import com.cliffc.aa.util.VBitSet;
6 import org.junit.Ignore;
7 import org.junit.Test;
8 
9 import java.util.function.Function;
10 
11 import static com.cliffc.aa.type.TypeFld.Access;
12 import static com.cliffc.aa.AA.ARG_IDX;
13 import static org.junit.Assert.*;
14 
15 public class TestParse {
16  private static final BitsFun TEST_FUNBITS = BitsFun.make0(46);
17 
18  // temp/junk holder for "instant" junits, when debugged moved into other tests
19  @Test public void testParse() {
20  // TODO:
21  // TEST for merging str:[7+43+44] and another concrete fcn, such as {&}.
22  // The Meet loses precision to fast. This is a typing bug.
23 
24  // fails, str.hash, str.eq is missing.
25  // needs a class for primitives which includes things like hash & eq & toString.
26  //test("tab = [7];\n" +
27  // "put = { key val ->\n" +
28  // " idx = key.hash() % #tab;\n" +
29  // " entry = tab[idx];\n" +
30  // " entry && key.eq(entry.key) ? (oldval=entry.val; entry.val:=val; ^oldval);\n" +
31  // " 0\n" +
32  // "};\n" +
33  // "put(\"Monday\",1);\n",
34  // Type.XNIL);
35 
36  // A collection of tests which like to fail easily
37  test("-1", TypeInt.con( -1));
38  test("{5}()", TypeInt.con(5)); // No args nor -> required; this is simply a function returning 5, being executed
39  testerr("x=1+y","Unknown ref 'y'",4);
40  test_obj("str(3.14)", TypeStr.con("3.14"));
41  test("math_rand(1)?x=4:x=3;x", TypeInt.NINT8); // x defined on both arms, so available after
42  test_ptr("x=@{n:=1;v:=2}; x.n := 3; x", "@{n:=3; v:=2}");
43  test("x=3; mul2={x -> x*2}; mul2(2.1)", TypeFlt.con(2.1*2.0)); // must inline to resolve overload {*}:Flt with I->F conversion
44  testerr("sq={x -> x*x}; sq(\"abc\")", "*\"abc\" is none of (flt64,int64)",9);
45  test("fun:{int str -> int}={x y -> x+2}; fun(2,3)", TypeInt.con(4));
46  testerr("math_rand(1)?x=2: 3 ;y=x+2;y", "'x' not defined on false arm of trinary",20);
47  testerr("{+}(1,2,3)", "Passing 3 arguments to {+} which takes 2 arguments",3);
48  test_isa("{x y -> x+y}", TypeFunPtr.make(BitsFun.make0(46),3, TypeMemPtr.NO_DISP)); // {Scalar Scalar -> Scalar}
49  testerr("dist={p->p.x*p.x+p.y*p.y}; dist(@{x=1})", "Unknown field '.y' in @{x=1}",19);
50  testerr("Point=:@{x;y}; Point((0,1))", "*(0, 1) is not a *Point:@{x:=; y:=}",21);
51  test("x=@{a:=1; b= {a=a+1;b=0}}; x. b(); x.a",TypeInt.con(2));
52  test("x=@{a:=1;noinline_b= {a=a+1;b=0}}; x.noinline_b(); x.a",TypeInt.NINT8);
53 
54  test("f0 = { f x -> x ? f(f0(f,x-1),1) : 0 }; f0({&},2)", Type.XNIL);
55  test("fact = { x -> x <= 1 ? x : x*fact(x-1) }; fact(1)",TypeInt.con(1));
56  test("fact = { x -> x <= 1 ? x : x*fact(x-1) }; fact(3)",TypeInt.con(6));
57  test("is_even = { n -> n ? is_odd(n-1) : 1}; is_odd = {n -> n ? is_even(n-1) : 0}; is_even(99)", TypeInt.BOOL );
58  test("fib = { x -> x <= 1 ? 1 : fib(x-1)+fib(x-2) }; fib(1)",TypeInt.con(1));
59  test("fib = { x -> x <= 1 ? 1 : fib(x-1)+fib(x-2) }; fib(4)",TypeInt.con(5));
60  test("A= :@{n=A?; v=flt}; f={x:A? -> x ? A(f(x.n),x.v*x.v) : 0}; f(A(0,1.2)).v;", TypeFlt.con(1.2*1.2));
61  testerr("fact = { x -> x <= 1 ? x : x*fact(x-1) }; fact(0);(1,);(1,).0;@{x;y];","Expected closing '}' but found ']' instead",63);
62  // id accepts and returns both ints and reference types (arrays).
63  //test_struct("noinline_id = {x->x};(noinline_id(5)&7, #noinline_id([3]))",TypeStruct.make_tuple(Type.XNIL,TypeInt.INT8,TypeInt.con(3)));
64  }
65 
66  @Test public void testParse00() {
67  // Simple int
68  test("1", TypeInt.TRUE);
69  // Unary operator
70  test("-1", TypeInt.con( -1));
71  test("!1", Type.XNIL);
72  // Binary operators
73  test("1+2", TypeInt.con( 3));
74  test("1-2", TypeInt.con( -1));
75  test("1+2*3", TypeInt.con( 7));
76  test("1 < 2", TypeInt.TRUE );
77  test("1 <=2", TypeInt.TRUE );
78  test("1 > 2", TypeInt.FALSE);
79  test("1 >=2", TypeInt.FALSE);
80  test("1 ==2", TypeInt.FALSE);
81  test("1 !=2", TypeInt.TRUE );
82  test("1.2< 2", TypeInt.TRUE );
83  test("1.2<=2", TypeInt.TRUE );
84  test("1.2> 2", TypeInt.FALSE);
85  test("1.2>=2", TypeInt.FALSE);
86  test("1.2==2", TypeInt.FALSE);
87  test("1.2!=2", TypeInt.TRUE );
88 
89  // Binary with precedence check
90  test(" 1+2 * 3+4 *5", TypeInt.con( 27));
91  test("(1+2)*(3+4)*5", TypeInt.con(105));
92  test("1// some comment\n+2", TypeInt.con(3)); // With bad comment
93  test("-1-2*3-4*5", TypeInt.con(-1-(2*3)-(4*5)));
94  test("1&3|1&2", TypeInt.con(1));
95 
96  // Float
97  test("1.2+3.4", TypeFlt.make(0,64,4.6));
98  // Mixed int/float with conversion
99  test("1+2.3", TypeFlt.make(0,64,3.3));
100 
101  // Simple strings
102  test_obj("\"Hello, world\"", TypeStr.con("Hello, world"));
103  test_obj("str(3.14)" , TypeStr.con("3.14"));
104  test_obj("str(3)" , TypeStr.con("3" ));
105  test_obj("str(\"abc\")" , TypeStr.ABC);
106  test("\"abc\"==\"abc\"",TypeInt.TRUE); // Constant strings intern
107 
108 
109  // Variable lookup
110  test("math_pi", TypeFlt.PI);
111  // bare function lookup; returns a union of '+' functions
112  testerr("+", "Syntax error; trailing junk",0);
113  testerr("!", "Syntax error; trailing junk",0);
114  test_prim("{+}", "+");
115  test_prim("{!}", "!"); // uniops are just like normal functions
116  // Function application, traditional paren/comma args
117  test("{+}(1,2)", TypeInt.con( 3));
118  test("{-}(1,2)", TypeInt.con(-1)); // binary version
119  test(" - (1 )", TypeInt.con(-1)); // unary version
120  // error; mismatch arg count
121  testerr("{!}() ", "Passing 0 arguments to {!} which takes 1 arguments",3);
122  testerr("math_pi(1)", "A function is being called, but 3.141592653589793 is not a function",10);
123  testerr("{+}(1,2,3)", "Passing 3 arguments to {+} which takes 2 arguments",3);
124 
125  // Parsed as +(1,(2*3))
126  test("{+}(1, 2 * 3) ", TypeInt.con(7));
127  // Parsed as +( (1+2*3) , (4*5+6) )
128  test("{+}(1 + 2 * 3, 4 * 5 + 6) ", TypeInt.con(33));
129  // Statements
130  test("(1;2 )", TypeInt.con(2));
131  test("(1;2;)", TypeInt.con(2)); // final semicolon is optional
132  test("{+}(1;2 ,3)", TypeInt.con(5)); // statements in arguments
133  test("{+}(1;2;,3)", TypeInt.con(5)); // statements in arguments
134  // Operators squished together
135  test("-1== -1", TypeInt.TRUE);
136  test("0== !!1", TypeInt.FALSE);
137  test("2==-1", TypeInt.FALSE);
138  test("-1== --1", TypeInt.FALSE);
139  test("-1== ---1",TypeInt.TRUE);
140  testerr("-1== --", "Missing term after '=='",5);
141  }
142 
143  @Test public void testParse01() {
144  // Syntax for variable assignment
145  test("x=1", TypeInt.TRUE);
146  test("x=y=1", TypeInt.TRUE);
147  testerr("x=y=", "Missing ifex after assignment of 'y'",4);
148  testerr("x=z" , "Unknown ref 'z'",2);
149  testerr("x=1+y","Unknown ref 'y'",4);
150  testerr("x=y; x=y","Unknown ref 'y'",2);
151  test("x=2; y=x+1; x*y", TypeInt.con(6));
152  // Re-use ref immediately after def; parses as: x=(2*3); 1+x+x*x
153  test("1+(x=2*3)+x*x", TypeInt.con(1+6+6*6));
154  testerr("x=(1+(x=2)+x); x", "Cannot re-assign final val 'x'",0);
155  test("x:=1;x++" ,TypeInt.con(1));
156  test("x:=1;x++;x",TypeInt.con(2));
157  test("x:=1;x++ + x--",TypeInt.con(3));
158  test("x++",Type.XNIL);
159  test("x++;x",TypeInt.con(1));
160 
161  // Conditional:
162  test ("0 ? 2 : 3", TypeInt.con(3)); // false
163  test ("2 ? 2 : 3", TypeInt.con(2)); // true
164  test ("math_rand(1)?x=4:x=3;x", TypeInt.NINT8); // x defined on both arms, so available after
165  test ("math_rand(1)?x=2: 3;4", TypeInt.con(4)); // x-defined on 1 side only, but not used thereafter
166  test ("math_rand(1)?(y=2;x=y*y):x=3;x", TypeInt.NINT8); // x defined on both arms, so available after, while y is not
167  testerr("math_rand(1)?x=2: 3 ;x", "'x' not defined on false arm of trinary",20);
168  testerr("math_rand(1)?x=2: 3 ;y=x+2;y", "'x' not defined on false arm of trinary",20);
169  testerr("0 ? x=2 : 3;x", "'x' not defined on false arm of trinary",11);
170  test ("2 ? x=2 : 3;x", TypeInt.con(2)); // off-side is constant-dead, so missing x-assign is ignored
171  test ("2 ? x=2 : y ", TypeInt.con(2)); // off-side is constant-dead, so missing 'y' is ignored
172  testerr("x=1;2?(x=2):(x=3);x", "Cannot re-assign final val 'x'",7);
173  test ("x=1;2? 2 :(x=3);x",TypeInt.con(1)); // Re-assigned allowed & ignored in dead branch
174  test ("math_rand(1)?1:int:2:int",TypeInt.NINT8); // no ambiguity between conditionals and type annotations
175  testerr("math_rand(1)?1: :2:int","missing expr after ':'",16); // missing type
176  testerr("math_rand(1)?1::2:int","missing expr after ':'",15); // missing type
177  testerr("math_rand(1)?1:\"a\"", "Cannot mix GC and non-GC types",18);
178  test ("math_rand(1)?1",TypeInt.BOOL); // Missing optional else defaults to nil
179  test_ptr0("math_rand(1)?\"abc\"", (alias)->TypeMemPtr.make_nil(alias,TypeStr.ABC));
180  test ("x:=0;math_rand(1)?(x:=1);x",TypeInt.BOOL);
181  testerr("a.b.c();","Unknown ref 'a'",0);
182  }
183 
184  // Short-circuit tests
185  @Test public void testParse01a() {
186  test("0 && 0", Type.XNIL);
187  test("1 && 2", TypeInt.con(2));
188  test("0 && 2", Type.XNIL);
189  test("0 || 0", Type.XNIL);
190  test("0 || 2", TypeInt.con(2));
191  test("1 || 2", TypeInt.con(1));
192  test("0 && 1 || 2 && 3", TypeInt.con(3)); // Precedence
193 
194  test_obj("x:=y:=0; z=x++ && y++;(x,y,z)", // increments x, but it starts zero, so y never increments
196  test_obj("x:=y:=0; x++ && y++; z=x++ && y++; (x,y,z)", // x++; x++; y++; (2,1,0)
198  test("(x=1) && x+2", TypeInt.con(3)); // Def x in 1st position
199 
200  testerr("1 && (x=2;0) || x+3 && x+4", "'x' not defined prior to the short-circuit",5); // x maybe alive
201  testerr("0 && (x=2;0) || x+3 && x+4", "'x' not defined prior to the short-circuit",5); // x definitely not alive
202  test("math_rand(1) && (x=2;x*x) || 3 && 4", TypeInt.INT8); // local use of x in short-circuit; requires unzip to find 4
203  }
204 
205  @Test public void testParse02() {
206  test("{5}()", TypeInt.con(5)); // No args nor -> required; this is simply a function returning 5, being executed
207  // Since call not-taken, post GCP Parms not loaded from _tf, limited to ~Scalar. The
208  // hidden internal call from {&} to the primitive is never inlined (has ~Scalar args)
209  // so 'x&1' never sees the TypeInt return from primitive AND.
211  test_isa("{x -> x&1}", TypeFunPtr.make(TEST_FUNBITS,2,tdisp)); // {Int -> Int}
212 
213  // Anonymous function definition
214  test_isa("{x y -> x+y}", TypeFunPtr.make(TEST_FUNBITS,3,tdisp)); // {Scalar Scalar -> Scalar}
215 
216  // Function execution and result typing
217  test("x=3; andx={y -> x & y}; andx(2)", TypeInt.con(2)); // trivially inlined; capture external variable
218  test("x=3; and2={x -> x & 2}; and2(x)", TypeInt.con(2)); // trivially inlined; shadow external variable
219  testerr("plus2={x -> x+2}; x", "Unknown ref 'x'",18); // Scope exit ends lifetime
220  testerr("fun={x -> }; fun(0)", "Missing function body",10);
221  testerr("fun(2)", "Unknown ref 'fun'", 0);
222  test("mul3={x -> y=3; x*y}; mul3(2)", TypeInt.con(6)); // multiple statements in func body
223  // Needs overload cloning/inlining to resolve {+}
224  test("x=3; addx={y -> x+y}; addx(2)", TypeInt.con(5)); // must inline to resolve overload {+}:Int
225  test("x=3; mul2={x -> x*2}; mul2(2.1)", TypeFlt.con(2.1*2.0)); // must inline to resolve overload {*}:Flt with I->F conversion
226  test("x=3; mul2={x -> x*2}; mul2(2.1)+mul2(x)", TypeFlt.con(2.1*2.0+3*2)); // Mix of types to mul2(), mix of {*} operators
227  test("sq={x -> x*x}; sq 2.1", TypeFlt.con(4.41)); // No () required for single args
228  testerr("sq={x -> x&x}; sq(\"abc\")", "*\"abc\" is not a int64",9);
229  testerr("sq={x -> x*x}; sq(\"abc\")", "*\"abc\" is none of (flt64,int64)",9);
230  testerr("f0 = { f x -> f0(x-1) }; f0({+},2)", "Passing 1 arguments to f0 which takes 2 arguments",16);
231  // Recursive:
232  test("fact = { x -> x <= 1 ? x : x*fact(x-1) }; fact(3)",TypeInt.con(6));
233  test("fib = { x -> x <= 1 ? 1 : fib(x-1)+fib(x-2) }; fib(4)",TypeInt.con(5));
234  test("f0 = { x -> x ? {+}(f0(x-1),1) : 0 }; f0(2)", TypeInt.con(2));
235  testerr("fact = { x -> x <= 1 ? x : x*fact(x-1) }; fact()","Passing 0 arguments to fact which takes 1 arguments",46);
236  test_obj("fact = { x -> x <= 1 ? x : x*fact(x-1) }; (fact(0),fact(1),fact(2))",
238 
239  // Co-recursion requires parallel assignment & type inference across a lexical scope
240  test("is_even = { n -> n ? is_odd(n-1) : 1}; is_odd = {n -> n ? is_even(n-1) : 0}; is_even(4)", TypeInt.con(1) );
241  test("is_even = { n -> n ? is_odd(n-1) : 1}; is_odd = {n -> n ? is_even(n-1) : 0}; is_even(99)", TypeInt.BOOL );
242 
243  // This test merges 2 TypeFunPtrs in a Phi, and then fails to resolve.
244  testerr("(math_rand(1) ? {+} : {*})(2,3)","Unable to resolve call",26); // either 2+3 or 2*3, or {5,6} which is INT8.
245  }
246 
247  @Test public void testParse03() {
248  // Type annotations
249  test("-1:int", TypeInt.con( -1));
250  test("(1+2.3):flt", TypeFlt.make(0,64,3.3));
251  test("x:int = 1", TypeInt.TRUE);
252  test("x:flt = 1", TypeInt.TRUE); // casts for free to a float
253  testerr("x:flt32 = 123456789", "123456789 is not a flt32",1);
254  testerr("1:","Syntax error; trailing junk",1); // missing type
255  testerr("2:x", "Syntax error; trailing junk", 1);
256  testerr("(2:)", "Syntax error; trailing junk", 2);
257 
258  test (" -1 :int1", TypeInt.con(-1));
259  testerr("(-1):int1", "-1 is not a int1",4);
260  testerr("\"abc\":int", "*\"abc\" is not a int64",5);
261  testerr("1:str", "1 is not a *str",1);
262 
263  test ("{x:int -> x*2}(1)", TypeInt.con(2)); // Types on parms
264  testerr("{x:str -> x}(1)", "1 is not a *str", 13);
265 
266  // Type annotations on dead args are ignored
267  test ("fun:{int str -> int}={x y -> x+2}; fun(2,3)", TypeInt.con(4));
268  testerr("fun:{int str -> int}={x y -> x+y}; fun(2,3)", "3 is not a *str",41);
269  // Test that the type-check is on the variable and not the function.
270  test_obj("fun={x y -> x*2}; bar:{int str -> int} = fun; baz:{int @{x;y} -> int} = fun; (fun(2,3),bar(2,\"abc\"))",
272  testerr("fun={x y -> x+y}; baz:{int @{x;y} -> int} = fun; (fun(2,3), baz(2,3))",
273  "3 is not a *@{x:=; y:=; ...}", 66);
274  testerr("fun={x y -> x+y}; baz={x:int y:@{x;y} -> foo(x,y)}; (fun(2,3), baz(2,3))",
275  "Unknown ref 'foo'", 41);
276  // This test failed because the inner fun does not inline until GCP,
277  // and then it resolves and lifts the DISPLAY (which after resolution
278  // is no longer needed). Means: cannot resolve during GCP and preserve
279  // monotonicity. Would like '.fun' to load BEFORE GCP.
280  testerr("fun={x y -> x+y}; baz={x:int y:@{x;y} -> fun(x,y)}; (fun(2,3), baz(2,3))",
281  "3 is not a *@{x:=; y:=; ...}", 69);
282 
283  testerr("x=3; fun:{int->int}={x -> x*2}; fun(2.1)+fun(x)", "2.1 is not a int64",36);
284  test("x=3; fun:{real->real}={x -> x*2}; fun(2.1)+fun(x)", TypeFlt.con(2.1*2+3*2)); // Mix of types to fun()
285  test("fun:{real->flt32}={x -> x}; fun(123 )", TypeInt.con(123 ));
286  test("fun:{real->flt32}={x -> x}; fun(0.125)", TypeFlt.con(0.125));
287  testerr("fun:{real->flt32}={x -> x}; fun(123456789)", "123456789 is not a flt32",3);
288 
289  // Named types
290  test_name("A= :( )" ); // Zero-length tuple
291  test_name("A= :( , )", Type.SCALAR); // One-length tuple
292  test_name("A= :( , ,)", Type.SCALAR ,Type.SCALAR );
293  test_name("A= :(flt, )", TypeFlt.FLT64 );
294  test_name("A= :(flt,int)", TypeFlt.FLT64,TypeInt.INT64);
295  test_name("A= :( ,int)", Type.SCALAR ,TypeInt.INT64);
296 
297  test_ptr("A= :(str?, int); A( \"abc\",2 )","A:(*\"abc\", 2)");
298  test_ptr("A= :(str?, int); A( (\"abc\",2) )","A:(*\"abc\", 2)");
299  testerr("A= :(str?, int)?","Named types are never nil",16);
300  }
301 
302  @Test public void testParse04() {
303  // simple anon struct tests
304  testerr("a=@{x=1.2;y}; x", "Unknown ref 'x'",14);
305  testerr("a=@{x=1;x=2}.x", "Cannot re-assign final field '.x' in @{x=1}",8);
306  test ("a=@{x=1.2;y;}; a.x", TypeFlt.con(1.2)); // standard "." field naming; trailing semicolon optional
307  test_ptr("x=@{n:=1;v:=2}; x.n := 3; x", "@{n:=3; v:=2}");
308  testerr("(a=@{x=0;y=0}; a.)", "Missing field name after '.'",17);
309  testerr("a=@{x=0;y=0}; a.x=1; a","Cannot re-assign final field '.x' in @{x=0; y=0}",16);
310  test ("a=@{x=0;y=1}; b=@{x=2} ; c=math_rand(1)?a:b; c.x", TypeInt.INT8); // either 0 or 2; structs can be partially merged
311  testerr("a=@{x=0;y=1}; b=@{x=2}; c=math_rand(1)?a:b; c.y", "Unknown field '.y' in @{x=int8}",46);
312  testerr("dist={p->p.x*p.x+p.y*p.y}; dist(@{x=1})", "Unknown field '.y' in @{x=1}",19);
313  test ("dist={p->p.x*p.x+p.y*p.y}; dist(@{x=1;y=2})", TypeInt.con(5)); // passed in to func
314  test ("dist={p->p.x*p.x+p.y*p.y}; dist(@{x=1;y=2;z=3})", TypeInt.con(5)); // extra fields OK
315  test ("dist={p:@{x;y} -> p.x*p.x+p.y*p.y}; dist(@{x:=1;y:=2})", TypeInt.con(5)); // Typed func arg
316  test ("a=@{x=(b=1.2)*b;y=b}; a.y", TypeFlt.con(1.2 )); // ok to use temp defs
317  test ("a=@{x=(b=1.2)*b;y=x}; a.y", TypeFlt.con(1.44)); // ok to use early fields in later defs
318  testerr("a=@{x=(b=1.2)*b;y=b}; b", "Unknown ref 'b'",22);
319  test ("t=@{n=0;val=1.2}; u=math_rand(1) ? t : @{n=t;val=2.3}; u.val", TypeFlt.NFLT64); // structs merge field-by-field
320  // Comments in the middle of a struct decl
321  test ("dist={p->p//qqq\n.//qqq\nx*p.x+p.y*p.y}; dist(//qqq\n@{x//qqq\n=1;y=2})", TypeInt.con(5));
322  testerr("@{x;y]","Expected closing '}' but found ']' instead",1);
323 
324  // Lexical scoping. Struct assignments make new fields, shadowing external variables.
325  test("x=@{a:=1;b=@{a= 2;b=@{a=3;b=0}}}; x.b.b.a",TypeInt.con(3));
326  // Lexical scoping. Before a new field is created, the external variable is used.
327  // After the new field, the new field is used.
328  test("x=@{a:=1;b=@{a=a+1;c=a}}; x.a*10+x.b.c",TypeInt.con(1*10+2));
329  // Similar to Python; if the first ref to a variable finds it in some
330  // (possibly external) scope, futher refs all refer to the same variable.
331  // Here 'a:=a+1' or 'a++' in the scope of 'b' increment the external variable.
332  // If the first ref to a variable is a set/store, then the variable
333  // is defined locally. Hence 'b=0' shadows the external x.b, and x.b
334  // is NOT set to 0.
335  test("x=@{a:=1;b= {a=a+1;b=0}}; x.b(); x.a",TypeInt.con(2));
336 
337  // Tuple
338  test_obj_isa("(0,\"abc\")", TypeStruct.make(Type.NIL,TypeMemPtr.OOP));
339  test("(1,\"abc\").0", TypeInt.TRUE);
340  test_obj("(1,\"abc\").1", TypeStr.ABC);
341 
342  // Named type variables
343  test("gal=:flt; gal", TypeFunPtr.make(TEST_FUNBITS,4, TypeMemPtr.NO_DISP));
344  test("gal=:flt; 3==gal(2)+1", TypeInt.TRUE);
345  test("gal=:flt; tank:gal = gal(2)", TypeInt.con(2).set_name("gal:"));
346  // test ("gal=:flt; tank:gal = 2.0", TypeName.make("gal",TypeFlt.con(2))); // TODO: figure out if free cast for bare constants?
347  testerr ("gal=:flt; tank:gal = gal(2)+1", "3 is not a gal:flt64",14);
348 
349  test ("Point=:@{x;y}; dist={p:Point -> p.x*p.x+p.y*p.y}; dist(Point(1,2))", TypeInt.con(5));
350  test ("Point=:@{x;y}; dist={p -> p.x*p.x+p.y*p.y}; dist(Point(1,2))", TypeInt.con(5));
351  testerr ("Point=:@{x;y}; dist={p:Point -> p.x*p.x+p.y*p.y}; dist((@{x=1;y=2}))", "*@{x=1; y=2} is not a *Point:@{x:=; y:=}",55);
352  testerr ("Point=:@{x;y}; Point((0,1))", "*(0, 1) is not a *Point:@{x:=; y:=}",21);
353  testerr("x=@{n: =1;}","Missing type after ':'",7);
354  testerr("x=@{n=;}","Missing ifex after assignment of 'n'",6);
356  }
357 
358  @Test public void testParse05() {
359  // nilable and not-nil pointers
360  test ("x:str? = 0", Type.XNIL); // question-type allows nil or not; zero digit is nil
361  test_obj("x:str? = \"abc\"", TypeStr.ABC); // question-type allows nil or not
362  testerr("x:str = 0", "0 is not a *str", 1);
363  test_ptr0("math_rand(1)?0:\"abc\"", (alias)->TypeMemPtr.make_nil(alias,TypeStr.ABC));
364  testerr("(math_rand(1)?0 : @{x=1}).x", "Struct might be nil when reading field '.x'", 26);
365  test ("p=math_rand(1)?0:@{x=1}; p ? p.x : 0", TypeInt.BOOL); // not-nil-ness after a nil-check
366  test ("x:int = y:str? = z:flt = 0", Type.XNIL); // nil/0 freely recasts
367  test ("\"abc\"==0", TypeInt.FALSE ); // No type error, just not nil
368  test ("\"abc\"!=0", TypeInt.TRUE ); // No type error, just not nil
369  test ("nil=0; \"abc\"!=nil", TypeInt.TRUE); // Another way to name nil
370  test ("a = math_rand(1) ? 0 : @{x=1}; // a is nil or a struct\n"+
371  "b = math_rand(1) ? 0 : @{c=a}; // b is nil or a struct\n"+
372  "b ? (b.c ? b.c.x : 0) : 0 // Nil-safe field load", TypeInt.BOOL); // Nested nil-safe field load
373  }
374 
375  @Test public void testParse06() {
376  // Building recursive types
377  test("A= :int; A(1)", TypeInt.TRUE.set_name("A:"));
378  test_ptr("A= :(str?, int); A(0,2)","A:(0, 2)");
379  // Named recursive types
380  test_ptr("A= :(A?, int); A(0,2)",(alias) -> TypeMemPtr.make(alias,TypeStruct.make("A:",false,TypeStruct.tups(Type.XNIL,TypeInt.con(2)),false)));
381  test_ptr("A= :(A?, int); A(0,2)","A:(0, 2)");
382  test ("A= :@{n=A?; v=flt}; A(@{n=0;v=1.2}).v;", TypeFlt.con(1.2));
383  test_ptr("A= :(A?, int); A(A(0,2),3)","A:(*A:(0, 2), 3)");
384 
385  // TODO: Needs a way to easily test simple recursive types
386  TypeEnv te3 = Exec.go(Env.file_scope(Env.top_scope()),"args","A= :@{n=A?; v=int}; A(@{n=0;v=3})");
387  if( te3._errs != null ) System.err.println(te3._errs.toString());
388  assertNull(te3._errs);
389  TypeStruct tt3 = (TypeStruct)te3._tmem.ld((TypeMemPtr)te3._t);
390  assertEquals("A:", tt3._name);
391  assertTrue (tt3.at(0).is_display_ptr());
392  assertEquals(Type.XNIL ,tt3.at(1));
393  assertEquals(TypeInt.con(3),tt3.at(2));
394  assertEquals("n",tt3.fld(1)._fld);
395  assertEquals("v",tt3.fld(2)._fld);
396 
397  // Missing type B is also never worked on.
398  test_isa("A= :@{n=B?; v=int}", TypeFunPtr.GENERIC_FUNPTR);
399  test_isa("A= :@{n=B?; v=int}; a = A(0,2)", TypeMemPtr.ISUSED);
400  test_isa("A= :@{n=B?; v=int}; a = A(0,2); a.n", Type.NIL);
401  // Mutually recursive type
402  test_isa("A= :@{n=B; v=int}; B= :@{n=A; v=flt}", TypeFunPtr.GENERIC_FUNPTR);
403  test_isa("A= :@{n=B; v=int}; B= :@{n=A; v=flt}", TypeFunPtr.GENERIC_FUNPTR); // Same test, again, using the same Type.INTERN table
404  test_isa("A= :@{n=C?; v=int}; B= :@{n=A?; v=flt}; C= :@{n=B?; v=str}", TypeFunPtr.GENERIC_FUNPTR);
405  // Mixed ABC's, making little abc's in-between.
406  TypeMemPtr tmpA = TypeMemPtr.make(23,TypeStruct.make(TypeFld.NO_DISP,TypeFld.make("n",Type.XNIL,1),TypeFld.make("v",TypeInt.con(5 ),2)).set_name("A:"));
407  TypeMemPtr tmpB = TypeMemPtr.make(19,TypeStruct.make(TypeFld.NO_DISP,TypeFld.make("n",tmpA ,1),TypeFld.make("v",TypeFlt.con(3.14 ),2)).set_name("B:"));
408  TypeMemPtr tmpC = TypeMemPtr.make(35,TypeStruct.make(TypeFld.NO_DISP,TypeFld.make("n",tmpB ,1),TypeFld.make("v",TypeMemPtr.make(17,TypeStr.con("abc")),2)).set_name("C:"));
409  test_isa("A= :@{n=B?; v=int}; "+
410  "a= A(0,5); "+
411  "B= :@{n=A?; v=flt}; "+
412  "b= B(a,3.14);"+
413  "C= :@{n=B?; v=str};"+
414  "c= C(b,\"abc\");"+
415  "(a,b,c)",
416  TypeMemPtr.make(37,TypeStruct.make(TypeStruct.tups(tmpA,tmpB,tmpC))));
417  }
418 
419  @Test public void testParse07() {
420  // Passing a function recursively
421  test("f0 = { f x -> x ? f(f0(f,x-1),1) : 0 }; f0({&},2)", Type.XNIL);
422  test("f0 = { f x -> x ? f(f0(f,x-1),1) : 0 }; f0({+},2)", TypeInt.con(2));
423  test_isa("A= :@{n=A?; v=int}; f={x:A? -> x ? A(f(x.n),x.v*x.v) : 0}", TypeFunPtr.GENERIC_FUNPTR);
424  test ("A= :@{n=A?; v=flt}; f={x:A? -> x ? A(f(x.n),x.v*x.v) : 0}; f(A(0,1.2)).v;", TypeFlt.con(1.2*1.2));
425  test("tmp=((0,1.2),2.3); sq={x->x*x}; map={f t -> t ? (map(f,t.0),f t.1) : 0}; map(sq,tmp).1",TypeFlt.con(2.3*2.3));
426  // Calling a function twice which returns the same alias. Verify no pointer confusion.
427  test("noinline_x={@{a}}; x0=noinline_x(); x1=noinline_x(); x0.a:=2; x1.a", TypeInt.INT8);
428 
429  // Longer variable-length list (so no inline-to-trivial). Pure integer
430  // ops, no overload resolution. Does final stores into new objects
431  // interspersed with recursive computation calls.
432  test_obj_isa("map={x -> x ? @{nn=map(x.n);vv=x.v&x.v} : 0};"+
433  "map(@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=0;v=1};v=2};v=3};v=4})",
435  // Test does loads after recursive call, which should be allowed to bypass.
436  test("sum={x -> x ? sum(x.n) + x.v : 0};"+
437  "sum(@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=0;v=1};v=2};v=3};v=4})",
438  TypeInt.INT64);
439 
440  // User-defined linked list.
441  String ll_def = "List=:@{next;val};";
442  String ll_con = "tmp=List(List(0,1.2),2.3);";
443  String ll_map = "map = {fun list -> list ? List(map(fun,list.next),fun(list.val)) : 0};";
444  String ll_fun = "sq = {x -> x*x};";
445  String ll_apl = "map(sq,tmp);";
446 
448  test(ll_def+ll_con+"; tmp.next.val", TypeFlt.con(1.2));
449  test_isa(ll_def+ll_con+ll_map, TypeFunPtr.GENERIC_FUNPTR);
450  test_isa(ll_def+ll_con+ll_map+ll_fun, TypeFunPtr.GENERIC_FUNPTR);
451 
452  // TODO: Needs a way to easily test simple recursive types
453  TypeEnv te4 = Exec.go(Env.file_scope(Env.top_scope()),"args",ll_def+ll_con+ll_map+ll_fun+ll_apl);
454  if( te4._errs != null ) System.err.println(te4._errs.toString());
455  assertNull(te4._errs);
456  TypeStruct tt4 = (TypeStruct)te4._tmem.sharpen((TypeMemPtr)te4._t)._obj;
457  assertEquals("List:", tt4._name);
458  TypeMemPtr tmp5 = (TypeMemPtr)tt4.at(1);
459  assertEquals(2.3*2.3,tt4.at(2).getd(),1e-6);
460  assertEquals("next",tt4.fld(1)._fld);
461  assertEquals("val" ,tt4.fld(2)._fld);
462 
463  // Test inferring a recursive struct type, with a little help
464  test_struct("map={x:@{n=;v=flt}? -> x ? @{nn=map(x.n);vv=x.v*x.v} : 0}; map(@{n=0;v=1.2})",
467  TypeFld.make("vv",TypeFlt.con(1.2*1.2) ,2)));
468 
469  // Test inferring a recursive struct type, with less help. This one
470  // inlines so doesn't actually test inferring a recursive type.
471  test_struct("map={x -> x ? @{nn=map(x.n);vv=x.v*x.v} : 0}; map(@{n=0;v=1.2})",
474  TypeFld.make("vv",TypeFlt.con(1.2*1.2) ,2)));
475 
476  // Test inferring a recursive struct type, with less help. Too complex to
477  // inline, so actual inference happens
478  test_obj_isa("map={x -> x ? @{nn=map(x.n);vv=x.v*x.v} : 0};"+
479  "map(@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=math_rand(1)?0:@{n=0;v=1.2};v=2.3};v=3.4};v=4.5})",
481  TypeFld.make("nn",TypeMemPtr.STRUCT0,1),
482  TypeFld.make("vv",TypeFlt.FLT64 ,2)));
483 
484  // Test inferring a recursive tuple type, with less help. This one
485  // inlines so doesn't actually test inferring a recursive type.
486  test_ptr("map={x -> x ? (map(x.0),x.1*x.1) : 0}; map((0,1.2))",
487  (alias) -> TypeMemPtr.make(alias,TypeStruct.make(TypeStruct.tups(Type.XNIL,TypeFlt.con(1.2*1.2)))));
488 
489  test_obj_isa("map={x -> x ? (map(x.0),x.1*x.1) : 0};"+
490  "map((math_rand(1)?0: (math_rand(1)?0: (math_rand(1)?0: (0,1.2), 2.3), 3.4), 4.5))",
492  }
493 
494 
495  @Test public void testParse08() {
496  // Main issue with the map() test is final assignments crossing recursive
497  // not-inlined calls. Smaller test case:
498  test_ptr("tmp=@{val=2;nxt=@{val=1;nxt=0}}; noinline_map={tree -> tree ? @{vv=tree.val&tree.val;nn=noinline_map(tree.nxt)} : 0}; noinline_map(tmp)",
499  "@{vv=int8; nn=*$?}");
500 
501  // Too big to inline, multi-recursive
502  test_ptr("tmp=@{"+
503  " l=@{"+
504  " l=@{ l=0; r=0; v=3 };"+
505  " r=@{ l=0; r=0; v=7 };"+
506  " v=5"+
507  " };"+
508  " r=@{"+
509  " l=@{ l=0; r=0; v=15 };"+
510  " r=@{ l=0; r=0; v=22 };"+
511  " v=20"+
512  " };"+
513  " v=12 "+
514  "};"+
515  "map={tree -> tree"+
516  " ? @{ll=map(tree.l);rr=map(tree.r);vv=tree.v&tree.v}"+
517  " : 0};"+
518  "map(tmp)",
519  "@{ll=*$?; rr=$; vv=int8}");
520 
521 
522  // Failed attempt at a Tree-structure inference test. Triggered all sorts
523  // of bugs and error reporting issues, so keeping it as a regression test.
524  testerr("tmp=@{"+
525  " l=@{"+
526  " l=@{ l=0; v=3 };"+
527  " l=0;"+
528  " v=5"+
529  " };"+
530  " v=12 "+
531  "};"+
532  "map={tree -> tree"+
533  " ? @{ll=map(tree.l);vv=tree.v}"+
534  " : 0};"+
535  "map(tmp)",
536  "Cannot re-assign final field '.l' in @{l=*use; v:=0}",36);
537 
538  // Good tree-structure inference test
539  test_ptr("tmp=@{"+
540  " l=@{"+
541  " l=@{ l=0; r=0; v=3 };"+
542  " r=@{ l=0; r=0; v=7 };"+
543  " v=5"+
544  " };"+
545  " r=@{"+
546  " l=@{ l=0; r=0; v=15 };"+
547  " r=@{ l=0; r=0; v=22 };"+
548  " v=20"+
549  " };"+
550  " v=12 "+
551  "};"+
552  "map={tree fun -> tree"+
553  " ? @{l=map(tree.l,fun);r=map(tree.r,fun);v=fun(tree.v)}"+
554  " : 0};"+
555  "map(tmp,{x->x+x})",
556  "@{l=*$?; r=$; v=int64}");
557 
558  // A linked-list mixing ints and strings, always in pairs
559  String ll_cona = "a=0; ";
560  String ll_conb = "b=math_rand(1) ? ((a,1),\"abc\") : a; ";
561  String ll_conc = "c=math_rand(1) ? ((b,2),\"def\") : b; ";
562  String ll_cond = "d=math_rand(1) ? ((c,3),\"ghi\") : c; ";
563  String ll_cone = "e=math_rand(1) ? ((d,4),\"jkl\") : d; ";
564  String ll_cont = "tmp=e; ";
565  // Standard pair-UN-aware map call
566  String ll_map2 = "map = {fun list -> list ? (map(fun,list.0),fun(list.1)) : 0};";
567  String ll_fun2 = "plus = {x -> x+x};";
568  String ll_apl2 = "map(plus,tmp);";
569  // End type: ((((*?,scalar)?,str)?,int64),str)?
570 
571  // After inlining once, we become pair-aware.
572 
574  TypeMemPtr xpt_int = TypeMemPtr.make(BitsAlias.RECORD_BITS0,xts_int);
575  TypeStruct xts_str = TypeStruct.make(xpt_int,TypeMemPtr.STRPTR);
577 
578  test_isa(ll_cona+ll_conb+ll_conc+ll_cond+ll_cone+ll_cont+ll_map2+ll_fun2+ll_apl2,xtmp);
579  }
580 
581  @Test public void testParse09() {
582  // Test re-assignment
583  test("x=1", TypeInt.TRUE);
584  test("x=y=1", TypeInt.TRUE);
585  testerr("x=y=", "Missing ifex after assignment of 'y'",4);
586  testerr("x=z" , "Unknown ref 'z'",2);
587  testerr("x=1+y","Unknown ref 'y'",4);
588 
589  test("x:=1", TypeInt.TRUE);
590  test_obj("x:=0; a=x; x:=1; b=x; x:=2; (a,b,x)", TypeStruct.make(TypeStruct.tups(Type.XNIL,TypeInt.con(1),TypeInt.con(2))));
591 
592  testerr("x=1; x:=2; x", "Cannot re-assign final val 'x'", 5);
593  testerr("x=1; x =2; x", "Cannot re-assign final val 'x'", 5);
594 
595  test("math_rand(1)?(x=4):(x=3);x", TypeInt.NINT8); // x defined on both arms, so available after
596  test("math_rand(1)?(x:=4):(x:=3);x", TypeInt.NINT8); // x defined on both arms, so available after
597  test("math_rand(1)?(x:=4):(x:=3);x:=x+1", TypeInt.INT64); // x mutable on both arms, so mutable after
598  test ("x:=0; 1 ? (x:=4):; x:=x+1", TypeInt.con(5)); // x mutable ahead; ok to mutate on 1 arm and later
599  test ("x:=0; 1 ? (x =4):; x", TypeInt.con(4)); // x final on 1 arm, dead on other arm
600  testerr("x:=0; math_rand(1) ? (x =4):3; x=2; x", "Cannot re-assign read-only val 'x'",31);
601  // A final store, but defs of @{a} do not escape into nonline_x, hence do
602  // not merge and escape out.
603  test("noinline_x={@{a}}; noinline_x().a=2; noinline_x().a", TypeInt.INT8);
604  }
605 
606  // Ffnls are declared with an assignment. This is to avoid the C++/Java
607  // problem of making final-field cycles. Java requires final fields to be
608  // only assigned in constructors before the value escapes, which prevents any
609  // final-cyclic structures. Final assignments have to be unambiguous - they
610  // fold into a 'New' at some point, same as casting to a 'Name', but they can
611  // interleave with other operations (such as other News) as long as the store
612  // is unambiguous.
613  // unknown
614  // Field mod status makes a small lattice: final read/write
615  // read-only
616 
617  // Type-error if a final assignment does not fold into a New. Cannot cast
618  // final to r/w, nor r/w to final. Can cast both to r/o. The reason you
619  // cannot cast to a final, is that some other caller/thread with some other
620  // r/w copy of the same pointer you have, can modify the supposedly final
621  // object. Hence you cannot cast to "final", but you can cast to "read-only"
622  // which only applies to you, and not to other r/w pointers.
623  @Test public void testParse10() {
624  // Test re-assignment in struct
625  test_obj_isa("x=@{n:=1;v:=2}", TypeStruct.make(TypeMemPtr.DISP_FLD,
626  TypeFld.make("n",TypeInt.con(1),Access.RW,1),
627  TypeFld.make("v",TypeInt.con(2),Access.RW,2)));
628  testerr ("x=@{n =1;v:=2}; x.n = 3; x.n", "Cannot re-assign final field '.n' in @{n=1; v:=2}",18);
629  test ("x=@{n:=1;v:=2}; x.n = 3", TypeInt.con(3));
630  test_ptr("x=@{n:=1;v:=2}; x.n := 3; x", "@{n:=3; v:=2}");
631  testerr ("x=@{n:=1;v:=2}; x.n = 3; x.v = 1; x.n = 4; x.n", "Cannot re-assign final field '.n' in @{n=3; v=1}",37);
632  test ("x=@{n:=1;v:=2}; y=@{n=3;v:=4}; tmp = math_rand(1) ? x : y; tmp.n", TypeInt.NINT8);
633  testerr ("x=@{n:=1;v:=2}; y=@{n=3;v:=4}; tmp = math_rand(1) ? x : y; tmp.n = 5; tmp.n", "Cannot re-assign read-only field '.n' in @{n==nint8; v:=nint8}",63);
634  test ("x=@{n:=1;v:=2}; foo={q -> q.n=3}; foo(x); x.n",TypeInt.con(3)); // Side effects persist out of functions
635  // Tuple assignment
636  testerr ("x=(1,2); x.0=3; x", "Cannot re-assign final field '.0' in (1, 2)",11);
637  // Final-only and read-only type syntax.
638  testerr ("ptr2rw = @{f:=1}; ptr2final:@{f=} = ptr2rw; ptr2final", "*@{f:=1} is not a *@{f=; ...}",27); // Cannot cast-to-final
639 
640  test_obj_isa("ptr2 = @{f =1}; ptr2final:@{f=} = ptr2 ; ptr2final", // Good cast
642  testerr ("ptr=@{f=1}; ptr2rw:@{f:=} = ptr; ptr2rw", "*@{f=1} is not a *@{f:=; ...}", 18); // Cannot cast-away final
643  test ("ptr=@{f=1}; ptr2rw:@{f:=} = ptr; 2", TypeInt.con(2)); // Dead cast-away of final
644  test ("@{x:=1;y =2}:@{x;y=}.y", TypeInt.con(2)); // Allowed reading final field
645  testerr ("f={ptr2final:@{x;y=} -> ptr2final.y }; f(@{x:=1;y:=2})", "*@{x:=1; y:=2} is not a *@{x:=; y=; ...}",42); // Another version of casting-to-final
646  testerr ("f={ptr2final:@{x;y=} -> ptr2final.y=3; ptr2final}; f(@{x:=1;y =2})", "Cannot re-assign final field '.y' in @{x:=1; y=2}",34);
647  test ("f={ptr:@{x==;y:=} -> ptr.y=3; ptr}; f(@{x:=1;y:=2}).y", TypeInt.con(3)); // On field x, cast-away r/w for r/o
648  test ("f={ptr:@{x=;y:=} -> ptr.y=3; ptr}; f(@{x =1;y:=2}).y", TypeInt.con(3)); // On field x, cast-up r/o for final but did not read
649  testerr ("f={ptr:@{x=;y:=} -> ptr.y=3; ptr}; f(@{x:=1;y:=2}).x", "*@{x:=1; y:=2} is not a *@{x=; y:=; ...}",37); // On field x, cast-up r/w for final and read
650  test ("f={ptr:@{x;y} -> ptr.y }; f(@{x:=1;y:=2}:@{x;y==})", TypeInt.con(2)); // cast r/w to r/o, and read
651  test ("f={ptr:@{x==;y==} -> ptr }; f(@{x=1;y=2}).y", TypeInt.con(2)); // cast final to r/o and read
652  test ("ptr=@{f:=1}; ptr:@{f=}.f=2",TypeInt.con(2)); // Checking that it is-a final does not make it final
653  // In general for these next two, want a 'MEET' style type assertion where
654  // locally at the function parm we "finalize" ptr.y, so the function body
655  // cannot modify it. However, no final store occurs so after the function,
656  // ptr.y remains writable.
657  testerr ("f={ptr:@{x;y=} -> ptr.y=3}; f(@{x:=1;y:=2});", "*@{x:=1; y:=2} is not a *@{x:=; y=; ...}",30);
658  //testerr ("f={ptr:@{x;y} -> ptr.y=3}; f(@{x:=1;y:=2}:@{x;y=})", "*@{.==nScalar} is not a *@{x:=; y:=; ...}",29);
659  test ("ptr=@{a:=1}; val=ptr.a; ptr.a=2; val",TypeInt.con(1));
660  // Allowed to build final pointer cycles
661  test ("ptr0=@{p:=0;v:=1}; ptr1=@{p=ptr0;v:=2}; ptr0.p=ptr1; ptr0.p.v+ptr1.p.v+(ptr0.p==ptr1)", TypeInt.con(4)); // final pointer-cycle is ok
662  }
663 
664  // Early function exit
665  @Test public void testParse11() {
666  test("x:=0; {1 ? ^2; x=3}(); x",Type.XNIL); // Following statement is ignored
667  test("{ ^3; 5}()",TypeInt.con(3)); // early exit
668  test("x:=0; {^3; x++}(); x",Type.XNIL); // Following statement is ignored
669  test("x:=0; {^1 ? (x=1); x=3}(); x",TypeInt.con(1)); // Return of an ifex
670  test("x:=0; {^1 ? x=1 ; x=3}(); x",TypeInt.con(1)); // Return of an ifex
671  test("f={0 ? ^0; 7}; f()", TypeInt.con(7));
672  // Find: returns 0 if not found, or first element which passes predicate.
673  test("find={list pred -> !list ? ^0; pred(list.1) ? ^list.1; find(list.0,pred)}; find(((0,3),2),{e -> e&1})", TypeInt.con(3));
674  test("x:=0; {1 ? ^2; x=3}(); x",Type.XNIL); // Following statement is ignored
675  // Curried functions
676  test("for={A-> A+3 }; for 2 ", TypeInt.con(5));
677  test("for={A->{B->A+B}}; for 2 3", TypeInt.con(5));
678  test("for={pred->{body->!pred()?^;tmp=body(); tmp?^tmp;7}}; for {1}{0}", TypeInt.con(7));
679  }
680 
681  // Upwards exposed closure tests
682  @Test public void testParse12() {
683  test("incA= {cnt:=0; {cnt++} }(); incA();incA()",TypeInt.con(1));
684  test("cnt:=0; incA={cnt++}; incA();incA()+cnt",TypeInt.con(1+2));
685  test("incA= {cnt:=0; {cnt++} }(); incA() ",Type.XNIL);
686  test("incA= {cnt:=0; {cnt++} }(); incA();incA()",TypeInt.con(1));
687  test("tmp = {cnt:=0;({cnt++},{cnt})}();incA=tmp.0;getA=tmp.1;incA();incA()+getA()",TypeInt.con(1+2));
688  test("gen = {cnt:=0;({cnt++},{cnt})};" +
689  "tmp:=gen(); incA=tmp.0;getA=tmp.1;"+
690  "tmp:=gen(); incB=tmp.0;getB=tmp.1;"+
691  "incA();incB();incA(); getA()*10+getB()",
692  TypeInt.con(2*10+1));
693  }
694 
695  // Serial loops; using variable 'for': "for pred body".
696  // If 'pred' is false , the loop exits with false.
697  // If 'body' is truthy, the loop exits with this value.
698  // To 'continue', use '^0'. To 'break' with non-zero 'val' use '^val'.
699  // Break cannot exit with '0'.
700  private final String FORELSE="for={pred->{body->!pred()?^;(tmp=body())?^tmp; for pred body}};";
701  // If 'pred' is false, the loop exits with false, else loop continues. 'body' value is ignored.
702  // To 'continue', use '^'.
703  // There is no 'break'.
704  private final String DO="do={pred->{body->!pred()?^;body(); do pred body}};";
705 
706  @Test public void testParse13() {
707  test(DO+"i:=0; do {i++ < 2} {i== 9}; i",TypeInt.con(3)); // Late exit, body never returns true.
708  test(FORELSE+"i:=0; for {i++ < 100} {i== 5} ",TypeInt.BOOL); // Not sure of exit value, except bool
709  test(FORELSE+"i:=0; for {i++ < 100} {i==50?i}",TypeInt.INT64); // Early exit on condition i==50
710  test(DO+"sum:=0; i:=0; do {i++ < 100} {sum:=sum+i}; sum",TypeInt.INT64);
711  }
712 
713  // Array syntax examples
714  @Test public void testParse14() {
715  test_ptr("[3]", "[$]0/obj");
716  test ("ary = [3]; ary[0]", Type.XNIL);
717  test ("[3][0]", Type.XNIL);
718  test ("ary = [3]; ary[0]:=2", TypeInt.con(2));
719  test_obj("ary = [3]; ary[0]:=0; ary[1]:=1; ary[2]:=2; (ary[0],ary[1],ary[2])", // array create, array storing
721  testary("0[0]","0 is not a *[]Scalar/obj",1);
722  testary("[3] [4]","Index must be out of bounds",5);
723  testary("[3] [-1]","Index must be out of bounds",5);
724  test_obj("[3]:[int]", TypeAry.make(TypeInt.con(3),Type.XNIL,TypeObj.OBJ)); // Array of 3 XNILs in INTs.
725  //test("[1,2,3]", TypeAry.make(TypeInt.con(1),TypeInt.con(3),TypeInt.INT8)); // Array of 3 elements
726  test("ary=[3];#ary",TypeInt.con(3)); // Array length
727  test_ptr(DO+"ary=[99]; i:=0; do {i++ < #ary} {ary[i]:=i*i};ary", "[$]int64/obj"); // sequential iteration over array
728  // ary.{e -> f(e)} // map over array elements
729  // ary.{e -> f(e)}.{e0 e1 -> f(e0,e1) } // map/reduce over array elements
730  }
731 
732 
733  // Parametric polymorphism
734  @Ignore
735  @Test public void testParse15() {
737  // Should be typable with H-M
738  test_ptr("noinline_map={lst fcn -> lst ? fcn lst.1};"+
739  "in_int=(0,2);"+ // List of ints
740  "in_str=(0,\"abc\");"+ // List of strings
741  "out_str =noinline_map(in_int,str:{int->str});"+ // Map over ints with int->str conversion, returning a list of strings
742  "out_bool=noinline_map(in_str,{str -> str==\"abc\"});"+ // Map over strs with str->bool conversion, returning a list of bools
743  "(out_str,out_bool)",
744  "(*\"2\",int1)");
745 
746  // ID in different contexts; in general requires a new TypeVar per use; for
747  // such a small function it is always inlined completely, has the same effect.
748  test("id={x->x};id(1)",TypeInt.con(1));
749  test("{x->x}(3.14)",TypeFlt.con(3.14));
750  test_prim("{x->x}({+})","+");
751  test("id={x->x};id({+})(id(1),id(math_pi))",TypeFlt.make(0,64,Math.PI+1));
752 
753  // Straight from TestHM.test08; types as {A -> (A,A)}.
754  // Function is never called, so returns the uncalled-function type.
755  test("fun={ g -> f={x -> g}; (f 3,f 1)}", TypeFunPtr.make(BitsFun.make0(46),ARG_IDX+1,Type.ANY));
756  // Called with different typevars A
757  test_ptr("fun={ g -> f={x -> g}; (f 3,f 1)}; (fun \"abc\",fun 3.14)",
758  "(*(*\"abc\", $), *(3.14, 3.14))");
759 
760  // recursive unification. Trivially types as a dead fcn ptr.
761  test_isa("x={x -> x x}",TypeFunPtr.make(BitsFun.make0(46),3,tdisp));
762  // recursive unification. Passing an ID to x then passes ID to ID, returning ID.
763  test_isa("x={x -> x x}; x({y->y})",TypeFunPtr.make(BitsFun.make0(47),4,tdisp));
764  // Looks like recursive unification, but x is a function of 0 arguments,
765  // being called with 1 argument. Error to call it.
766  testerr("x={x x};x(1)","Passing 1 arguments to x which takes 0 arguments",9);
767  // id accepts and returns both ints and reference types (arrays).
768  test_struct("noinline_id = {x->x};(noinline_id(5)&7, #noinline_id([3]))",
770  // Should be typable with H-M
771  test_ptr("noinline_map={lst fcn -> lst ? fcn lst.1};"+
772  "in_int=(0,2);"+ // List of ints
773  "in_str=(0,\"abc\");"+ // List of strings
774  "out_str =noinline_map(in_int,str:{int->str});"+ // Map over ints with int->str conversion, returning a list of strings
775  "out_bool=noinline_map(in_str,{str -> str==\"abc\"});"+ // Map over strs with str->bool conversion, returning a list of bools
776  "(out_str,out_bool)",
777  "(*\"2\",int1)");
778  // Only odd thing here is losing not-nil-ness on list_int.
779  test_ptr("noinline_map={tup fcn -> (0,fcn tup.1)};"+
780  "lst_int=(0,2 );"+ //
781  "lst_str=(0,\"abc\");"+ //
782  "lst_istr=noinline_map(lst_int,str);"+ // Map over ints with int->str conversion, returning a list of strings
783  "lst_bool=noinline_map(lst_str,{str-> str==\"abc\"});"+ // Map over strs with str->bool conversion, returns bools
784  "(lst_istr,lst_bool)",
785  "(*(0, *\"2\")?, *(0, int1))");
786  // map being called with 2 different functions & lists
787  test("noinline_map={lst fcn -> lst ? (noinline_map(lst.0,fcn),fcn lst.1)};"+
788  "in_int=(((0,2),3),5);"+ // List of 3 ints
789  "in_str= ((0,\"abc\"),\"def\");"+ // List of 2 strings
790  "out_istr=noinline_map(in_int,str);"+ // Map over ints with int->str conversion, returning a list of strings
791  "out_bool=noinline_map(in_str,{str:str ->str==\"abc\"});"+ // Map over strs with str->bool conversion, returns bools
792  "(out_istr,out_bool)",
793  Type.ANY);
794 
795  }
796 
797  /*
798 // type variables are free in : type expressions
799 
800 // Define a pair as 2 fields "a" and "b" both with the same type T. Note that
801 // 'a' and 'b' and 'T' are all free, but the @ parses this as a struct, so 'a'
802 // and 'b' become field names and 'T' becomes a free type-var.
803 Pair = :@{ a:T, b:T }
804 
805 // Since 'A' and 'B' are free and not field names, they become type-vars.
806 MapType = :{ {A->B} List[A] -> List[B] }
807 
808 // map: no leading ':' so a function definition, not a type def
809 map:MapType = { f list -> ... }
810 
811 // A List type. Named types are not 'null', so not valid to use "List = :...?".
812 // Type List takes a type-variable 'A' (which is free in the type expr).
813 // List is a self-recursive type.
814 // Field 'next' can be null or List(A).
815 // Field 'val' is type A.
816 List = :@{ next:List?, val:A }
817  */
818 
819  /*** Fanciful attempt at a HashTable class. No resize, size, clear, etc.
820 HashTable = {@{
821  _tab = [7];
822 
823  get = { key ->
824  entry = _tab[key.hash() % #_tab];
825  entry && key.eq(entry.key) ? entry.val;
826  }
827  put = { key val ->
828  idx = key.hash() % #_tab;
829  entry = _tab[idx];
830  entry && key.eq(entry.key) ? (oldval=entry.val; entry.val:=val; ^oldval);
831  _tab[idx]= @{key=key; val=val; next=entry};
832  entry ? entry.val;
833  }
834 }}
835  */
836 
837 
838  // Caller must close TypeEnv
839  static private TypeEnv run( String program ) {
840  TypeEnv te = Exec.open(Env.file_scope(Env.top_scope()),"args",program);
841  if( te._errs != null ) System.err.println(te._errs.toString());
842  assertNull(te._errs);
843  return te;
844  }
845 
846  static private void test( String program, Type expected ) {
847  try( TypeEnv te = run(program) ) {
848  assertEquals(expected,te._t);
849  }
850  }
851  static private void test_prim( String program, String prim ) {
852  Env top = Env.top_scope();
853  Type expected = top.lookup_valtype(prim);
854  try( TypeEnv te = Exec.open(Env.file_scope(top),"args",program) ) {
855  if( te._errs != null ) System.err.println(te._errs.toString());
856  assertNull(te._errs);
857  assertEquals(expected,te._t);
858  }
859  }
860  static private void test_name( String program, Type... args ) {
861  try( TypeEnv te = run(program) ) {
862  assertTrue(te._t instanceof TypeFunPtr);
863  TypeFunPtr actual = (TypeFunPtr)te._t;
864  TypeFunPtr expected = TypeFunPtr.make(actual.fidxs(),ARG_IDX+1, TypeMemPtr.NO_DISP);
865  assertEquals(expected,actual);
866  }
867  }
868  static private void test_ptr( String program, Function<Integer,Type> expected ) {
869  try( TypeEnv te = run(program) ) {
870  TypeMemPtr actual = te._tmem.sharpen((TypeMemPtr)te._t);
871  int alias = actual.getbit(); // internally asserts only 1 bit set
872  Type t_expected = expected.apply(alias);
873  assertEquals(t_expected,actual);
874  }
875  }
876  static private void test_ptr0( String program, Function<Integer,Type> expected ) {
877  try( TypeEnv te = run(program) ) {
878  TypeMemPtr tmp = te._tmem.sharpen((TypeMemPtr)te._t);
879  BitsAlias bits = tmp._aliases;
880  assertTrue(bits.test(0));
881  int alias = bits.strip_nil().getbit(); // internally asserts only 1 bit set
882  Type t_expected = expected.apply(alias);
883  assertEquals(t_expected,tmp);
884  }
885  }
886  static private void test_obj( String program, TypeObj expected) {
887  try( TypeEnv te = run(program) ) {
888  assertTrue(te._t instanceof TypeMemPtr);
889  int alias = ((TypeMemPtr)te._t).getbit(); // internally asserts only 1 bit set
890  TypeObj actual = te._tmem.ld((TypeMemPtr)te._t);
891  assertEquals(expected,actual);
892  }
893  }
894  static private void test_struct( String program, TypeStruct expected) {
895  try( TypeEnv te = run(program) ) {
896  TypeStruct actual = (TypeStruct)te._tmem.ld((TypeMemPtr)te._t);
897  actual = actual.set_fld(0,TypeMemPtr.NO_DISP,Access.Final);
898  assertEquals(expected,actual);
899  }
900  }
901  static private void test_obj_isa( String program, TypeObj expected) {
902  try( TypeEnv te = run(program) ) {
903  int alias = ((TypeMemPtr)te._t)._aliases.strip_nil().getbit(); // internally asserts only 1 bit set
904  TypeObj actual = te._tmem.sharpen((TypeMemPtr)te._t)._obj;
905  assertTrue(actual.isa(expected));
906  }
907  }
908  static private void test_ptr( String program, String expected ) {
909  try( TypeEnv te = run(program) ) {
910  assertTrue(te._t instanceof TypeMemPtr);
911  TypeObj to = te._tmem.ld((TypeMemPtr)te._t); // Peek thru pointer
912  SB sb = to.str(new SB(),new VBitSet(),te._tmem,false); // Print what we see, with memory
913  assertEquals(expected,strip_alias_numbers(sb.toString()));
914  }
915  }
916  static private void test( String program, Function<Integer,Type> expected ) {
917  try( TypeEnv te = run(program) ) {
918  Type t_expected = expected.apply(-99); // unimpl
919  assertEquals(t_expected,te._t);
920  }
921  }
922  static private void test_isa( String program, Type expected ) {
923  try( TypeEnv te = run(program) ) {
924  Type actual = te._tmem.sharptr(te._t);
925  assertTrue(actual.isa(expected));
926  }
927  }
928  static private void testerr( String program, String err, String cursor ) {
929  System.out.println("fix test, cur_off="+cursor.length());
930  fail();
931  }
932  static void testerr( String program, String err, int cur_off ) {
933  TypeEnv te = Exec.go(Env.file_scope(Env.top_scope()),"args",program);
934  assertTrue(te._errs != null && te._errs.size()>=1);
935  String cursor = new String(new char[cur_off]).replace('\0', ' ');
936  String err2 = new SB().p("args:1:").p(err).nl().p(program).nl().p(cursor).p('^').nl().toString();
937  assertEquals(err2,strip_alias_numbers(te._errs.get(0).toString()));
938  }
939  private static String strip_alias_numbers( String err ) {
940  // Remove alias#s from the result string: *[123]@{x=1,y=2} ==> *[$]@{x=1,y=2}
941  // \\ Must use two \\ because of String escaping for every 1 in the regex.
942  // Thus replacing: \[[,0-9]* with: \[\$
943  // Regex breakdown:
944  // \\[ prevents using '[' as the start of a regex character class
945  // [,0-9] matches digits and commas
946  // * matches all the digits and commas
947  // \\[ Replacement [ because the first one got matched and replaced.
948  // \\$ Prevent $ being interpreted as a regex group start
949  return err.replaceAll("\\[[,0-9]*", "\\[\\$");
950  }
951  static private void testary( String program, String err, int cur_off ) {
952  TypeEnv te = Exec.go(Env.file_scope(Env.top_scope()),"args",program);
953  assertTrue(te._errs != null && te._errs.size()>=1);
954  String cursor = new String(new char[cur_off]).replace('\0', ' ');
955  String err2 = new SB().p("args:1:").p(err).nl().p(program).nl().p(cursor).p('^').nl().toString();
956  assertEquals(err2,te._errs.get(0).toString());
957  }
958 
959 }
com.cliffc.aa.TestParse.testParse04
void testParse04()
Definition: TestParse.java:302
com.cliffc.aa.type.TypeFld.Access.Final
Final
Definition: TypeFld.java:112
com.cliffc.aa.type.TypeMemPtr.NO_DISP
static final Type NO_DISP
Definition: TypeMemPtr.java:80
com.cliffc.aa.type.BitsAlias.RECORD_BITS0
static BitsAlias RECORD_BITS0
Definition: BitsAlias.java:27
com.cliffc.aa.type.TypeInt.INT8
static final TypeInt INT8
Definition: TypeInt.java:42
com.cliffc.aa.Exec
an implementation of language AA
Definition: Exec.java:6
com.cliffc.aa.TestParse.testParse01
void testParse01()
Definition: TestParse.java:143
com.cliffc.aa.type.TypeMem.ld
TypeObj ld(TypeMemPtr ptr)
Definition: TypeMem.java:325
com.cliffc.aa.TestParse.testParse10
void testParse10()
Definition: TestParse.java:623
com.cliffc.aa.type.TypeFunPtr
Definition: TypeFunPtr.java:23
com.cliffc.aa.type.TypeMemPtr.STRUCT0
static final TypeMemPtr STRUCT0
Definition: TypeMemPtr.java:102
com.cliffc.aa.type.BitsFun.make0
static BitsFun make0(int bit)
Definition: BitsFun.java:44
com.cliffc.aa.type.Type.isa
boolean isa(Type t)
Definition: Type.java:623
com.cliffc.aa.Env.lookup_valtype
Type lookup_valtype(String name)
Definition: Env.java:191
com.cliffc.aa.type.TypeMemPtr.OOP
static final TypeMemPtr OOP
Definition: TypeMemPtr.java:94
com.cliffc.aa.type.Type.SCALAR
static final Type SCALAR
Definition: Type.java:328
com.cliffc
com.cliffc.aa.TestParse.TEST_FUNBITS
static final BitsFun TEST_FUNBITS
Definition: TestParse.java:16
com.cliffc.aa.Env.top_scope
static Env top_scope()
Definition: Env.java:72
com.cliffc.aa.TestParse.testerr
static void testerr(String program, String err, String cursor)
Definition: TestParse.java:928
com.cliffc.aa.TestParse.testParse11
void testParse11()
Definition: TestParse.java:665
com.cliffc.aa.TestParse.testParse02
void testParse02()
Definition: TestParse.java:205
com.cliffc.aa.type.TypeMemPtr.DISP_FLD
static final TypeFld DISP_FLD
Definition: TypeMemPtr.java:77
com.cliffc.aa.type.TypeFld
Definition: TypeFld.java:12
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.TestParse.test
static void test(String program, Type expected)
Definition: TestParse.java:846
com.cliffc.aa.TestParse.test_ptr0
static void test_ptr0(String program, Function< Integer, Type > expected)
Definition: TestParse.java:876
com.cliffc.aa.type.TypeInt
Definition: TypeInt.java:9
com.cliffc.aa.type.TypeFunPtr.GENERIC_FUNPTR
static final TypeFunPtr GENERIC_FUNPTR
Definition: TypeFunPtr.java:80
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.type.TypeFlt
Definition: TypeFlt.java:9
com.cliffc.aa.TestParse.strip_alias_numbers
static String strip_alias_numbers(String err)
Definition: TestParse.java:939
com.cliffc.aa.type.BitsAlias
Definition: BitsAlias.java:8
com.cliffc.aa.type.TypeFld.Access.RW
RW
Definition: TypeFld.java:111
com.cliffc.aa.type.TypeFld.NO_DISP
static final TypeFld NO_DISP
Definition: TypeFld.java:170
com.cliffc.aa.AA.ARG_IDX
static final int ARG_IDX
Definition: AA.java:17
com.cliffc.aa.type.TypeInt.con
static TypeInt con(long con)
Definition: TypeInt.java:37
com.cliffc.aa.type.TypeFunPtr.fidxs
BitsFun fidxs()
Definition: TypeFunPtr.java:127
com.cliffc.aa.type.TypeFlt.PI
static final TypeFlt PI
Definition: TypeFlt.java:40
com.cliffc.aa.type.Type.ANY
static final Type ANY
Definition: Type.java:325
com.cliffc.aa.TestParse.testParse01a
void testParse01a()
Definition: TestParse.java:185
com.cliffc.aa.type.TypeAry
Definition: TypeAry.java:7
com.cliffc.aa.type.TypeStruct
A memory-based collection of optionally named fields.
Definition: TypeStruct.java:50
com.cliffc.aa.type.TypeFld.make
static TypeFld make(String fld, Type t, int order)
Definition: TypeFld.java:58
com.cliffc.aa.type.Bits.test
static boolean test(long[] bits, int i)
Definition: Bits.java:224
com.cliffc.aa.TestParse
Definition: TestParse.java:15
com.cliffc.aa.type.TypeStruct.at
Type at(int idx)
Definition: TypeStruct.java:1013
com.cliffc.aa.type.Type.getd
double getd()
Definition: Type.java:804
com.cliffc.aa.TestParse.testParse14
void testParse14()
Definition: TestParse.java:714
com.cliffc.aa.TestParse.test_struct
static void test_struct(String program, TypeStruct expected)
Definition: TestParse.java:894
com.cliffc.aa.TypeEnv._tmem
final TypeMem _tmem
Definition: TypeEnv.java:11
com.cliffc.aa.type.TypeInt.INT64
static final TypeInt INT64
Definition: TypeInt.java:39
com.cliffc.aa.type.Type.set_name
final T set_name(String name)
Definition: Type.java:551
com.cliffc.aa.TestParse.testParse13
void testParse13()
Definition: TestParse.java:706
com.cliffc.aa.TestParse.testParse00
void testParse00()
Definition: TestParse.java:66
com.cliffc.aa.type.TypeObj.OBJ
static final TypeObj OBJ
Definition: TypeObj.java:44
com.cliffc.aa.type.TypeObj
Definition: TypeObj.java:15
com.cliffc.aa.TestParse.test_ptr
static void test_ptr(String program, Function< Integer, Type > expected)
Definition: TestParse.java:868
com.cliffc.aa.TestParse.testerr
static void testerr(String program, String err, int cur_off)
Definition: TestParse.java:932
com.cliffc.aa.type.TypeFlt.con
static Type con(double con)
Definition: TypeFlt.java:36
com.cliffc.aa.TestParse.test_obj_isa
static void test_obj_isa(String program, TypeObj expected)
Definition: TestParse.java:901
com.cliffc.aa.TestParse.testParse12
void testParse12()
Definition: TestParse.java:682
com.cliffc.aa.type.TypeFlt.make
static Type make(int x, int z, double con)
Definition: TypeFlt.java:30
com.cliffc.aa.TestParse.test_prim
static void test_prim(String program, String prim)
Definition: TestParse.java:851
com.cliffc.aa.type.TypeStr.ABC
static final TypeStr ABC
Definition: TypeStr.java:47
com.cliffc.aa.type.TypeAry.make
static TypeAry make(String name, boolean any, TypeInt sz, Type elem, TypeObj stor)
Definition: TypeAry.java:38
com.cliffc.aa.TestParse.testParse08
void testParse08()
Definition: TestParse.java:495
com.cliffc.aa.TypeEnv._t
final Type _t
Definition: TypeEnv.java:10
com.cliffc.aa.type.TypeInt.NINT8
static final TypeInt NINT8
Definition: TypeInt.java:47
com.cliffc.aa.type.TypeMemPtr.getbit
int getbit()
Definition: TypeMemPtr.java:263
com.cliffc.aa.type.TypeObj.ISUSED
static final TypeObj ISUSED
Definition: TypeObj.java:45
com.cliffc.aa.type.TypeFld._fld
String _fld
Definition: TypeFld.java:15
com.cliffc.aa.type.TypeStr.con
static TypeStr con(String con)
Definition: TypeStr.java:42
com.cliffc.aa.type.TypeFunPtr.make
static TypeFunPtr make(BitsFun fidxs, int nargs, Type disp)
Definition: TypeFunPtr.java:67
com.cliffc.aa.type.Type.sharptr
Type sharptr(Type ptr)
Definition: Type.java:930
com.cliffc.aa.Env.file_scope
static Env file_scope(Env top_scope)
Definition: Env.java:116
com.cliffc.aa.TestParse.test_isa
static void test_isa(String program, Type expected)
Definition: TestParse.java:922
com.cliffc.aa.type.TypeStr
Definition: TypeStr.java:14
com.cliffc.aa.util.VBitSet
Definition: VBitSet.java:5
com.cliffc.aa.type.TypeStruct.tups
static TypeFld[] tups(Type t1, Type t2)
Definition: TypeStruct.java:186
com.cliffc.aa.type.BitsFun
Definition: BitsFun.java:7
com.cliffc.aa.type.TypeObj.str
SB str(SB sb, VBitSet dups, TypeMem mem, boolean debug)
Definition: TypeObj.java:34
com.cliffc.aa.util.SB
Tight/tiny StringBuilder wrapper.
Definition: SB.java:8
com.cliffc.aa.TypeEnv
Definition: TypeEnv.java:9
com.cliffc.aa.TestParse.run
static TypeEnv run(String program)
Definition: TestParse.java:839
com.cliffc.aa.type.Type.NIL
static final Type NIL
Definition: Type.java:332
com.cliffc.aa.AA
an implementation of language AA
Definition: AA.java:9
com.cliffc.aa.type.Type.is_display_ptr
boolean is_display_ptr()
Definition: Type.java:941
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.util.SB.nl
SB nl()
Definition: SB.java:48
com.cliffc.aa.type.BitsAlias.make0
static BitsAlias make0(int bit)
Definition: BitsAlias.java:72
com.cliffc.aa.TestParse.testParse06
void testParse06()
Definition: TestParse.java:375
com.cliffc.aa.type.TypeStruct.fld
TypeFld fld(int idx)
Definition: TypeStruct.java:1012
com.cliffc.aa.TestParse.testary
static void testary(String program, String err, int cur_off)
Definition: TestParse.java:951
com.cliffc.aa.type.TypeStruct.set_fld
TypeStruct set_fld(int i, Type t, Access ff)
Definition: TypeStruct.java:1030
com.cliffc.aa.TestParse.testParse
void testParse()
Definition: TestParse.java:19
com.cliffc.aa.util.SB.p
SB p(String s)
Definition: SB.java:13
com.cliffc.aa.type.TypeMemPtr._aliases
BitsAlias _aliases
Definition: TypeMemPtr.java:16
com.cliffc.aa.type.TypeInt.FALSE
static final Type FALSE
Definition: TypeInt.java:45
com.cliffc.aa.type.Bits.strip_nil
B strip_nil()
Definition: Bits.java:273
com.cliffc.aa.type.TypeStruct.make
static TypeStruct make(String fld_name, Type t)
Definition: TypeStruct.java:190
com.cliffc.aa.TestParse.FORELSE
final String FORELSE
Definition: TestParse.java:700
com.cliffc.aa.type.TypeMem.sharpen
TypeMemPtr sharpen(TypeMemPtr dull)
Definition: TypeMem.java:402
com.cliffc.aa.TestParse.testParse05
void testParse05()
Definition: TestParse.java:358
com.cliffc.aa.type.TypeMemPtr.ISUSED
static final TypeMemPtr ISUSED
Definition: TypeMemPtr.java:92
com.cliffc.aa.type.Type.XNIL
static final Type XNIL
Definition: Type.java:333
com.cliffc.aa.TestParse.testParse09
void testParse09()
Definition: TestParse.java:581
com.cliffc.aa.Exec.go
static TypeEnv go(Env top, String src, String str)
Definition: Exec.java:8
com.cliffc.aa.type.TypeFld.Access
Definition: TypeFld.java:109
com.cliffc.aa.type.TypeMemPtr.STRPTR
static final TypeMemPtr STRPTR
Definition: TypeMemPtr.java:97
com.cliffc.aa.TypeEnv._errs
final ArrayList< Node.ErrMsg > _errs
Definition: TypeEnv.java:13
com.cliffc.aa.type.TypeMemPtr.OOP0
static final TypeMemPtr OOP0
Definition: TypeMemPtr.java:93
com.cliffc.aa.TestParse.test_obj
static void test_obj(String program, TypeObj expected)
Definition: TestParse.java:886
com.cliffc.aa.TestParse.testParse15
void testParse15()
Definition: TestParse.java:735
com.cliffc.aa.type.TypeInt.TRUE
static final TypeInt TRUE
Definition: TypeInt.java:44
com.cliffc.aa.type.TypeMemPtr.make_nil
static TypeMemPtr make_nil(int alias, TypeObj obj)
Definition: TypeMemPtr.java:72
com.cliffc.aa.TestParse.test
static void test(String program, Function< Integer, Type > expected)
Definition: TestParse.java:916
com
com.cliffc.aa.TestParse.testParse03
void testParse03()
Definition: TestParse.java:247
com.cliffc.aa.Env
Definition: Env.java:12
com.cliffc.aa.TestParse.test_ptr
static void test_ptr(String program, String expected)
Definition: TestParse.java:908
com.cliffc.aa.Exec.open
static TypeEnv open(Env top, String src, String str)
Definition: Exec.java:12
com.cliffc.aa.type.TypeInt.BOOL
static final TypeInt BOOL
Definition: TypeInt.java:43
com.cliffc.aa.util.SB.toString
String toString()
Definition: SB.java:62
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.type.TypeFlt.NFLT64
static final TypeFlt NFLT64
Definition: TypeFlt.java:41
com.cliffc.aa.type.TypeMemPtr
Definition: TypeMemPtr.java:14
com.cliffc.aa.TestParse.testParse07
void testParse07()
Definition: TestParse.java:419
com.cliffc.aa.TestParse.test_name
static void test_name(String program, Type... args)
Definition: TestParse.java:860
com.cliffc.aa.type.TypeFlt.FLT64
static final TypeFlt FLT64
Definition: TypeFlt.java:38
com.cliffc.aa.TestParse.DO
final String DO
Definition: TestParse.java:704
com.cliffc.aa.type.TypeMemPtr.make
static TypeMemPtr make(BitsAlias aliases, TypeObj obj)
Definition: TypeMemPtr.java:66