aa
Parse.java
Go to the documentation of this file.
1 package com.cliffc.aa;
2 
3 import com.cliffc.aa.node.*;
4 import com.cliffc.aa.type.*;
5 import com.cliffc.aa.tvar.TV2;
6 import com.cliffc.aa.util.*;
7 import org.jetbrains.annotations.NotNull;
8 
9 import java.text.NumberFormat;
10 import java.text.ParsePosition;
11 import java.util.*;
12 
13 import static com.cliffc.aa.AA.*;
14 import static com.cliffc.aa.type.TypeFld.Access;
15 
68 public class Parse implements Comparable<Parse> {
69  private final String _src; // Source for error messages; usually a file name
70  private Env _e; // Lookup context; pushed and popped as scopes come and go
71  private final byte[] _buf; // Bytes being parsed
72  private int _x; // Parser index
73  private int _lastNWS; // Index of last non-white-space char
74  private final AryInt _lines; // char offset of each line
75  public final GVNGCM _gvn; // Pessimistic types
76 
77  // Fields strictly for Java number parsing
78  private final NumberFormat _nf;
79  private final ParsePosition _pp;
80  private final String _str;
81 
82  Parse( String src, Env env, String str ) {
83  _src = src;
84  _e = env;
85  _buf = str.getBytes();
86  _x = 0;
87 
88  // Set fields strictly for Java number parsing
89  _nf = NumberFormat.getInstance();
90  _nf.setGroupingUsed(false);
91  _pp = new ParsePosition(0);
92  _str = str; // Keep a complete string copy for java number parsing
93  _lines = new AryInt();//
94  _lines.push(0); // Line 0 at offset 0
95  _gvn = Env.GVN; // Pessimistic during parsing
96  }
97  String dump() { return scope().dump(99); }// debugging hook
98  String dumprpo() { return Env.START.dumprpo(false,false); }// debugging hook
99 
100  // Parse the string in the given lookup context, and return an executable
101  // program. Called in a whole-program context; passed in an empty ScopeNode
102  // and nothing survives since there is no next call. Used by the Exec to do
103  // whole-compilation-unit typing.
104  TypeEnv go( ) {
105  prog(); // Parse a program
106  // Delete names at the top scope before starting optimization.
107  _e._scope.keep();
109  _gvn.iter(GVNGCM.Mode.PesiNoCG); // Pessimistic optimizations; might improve error situation
111  _gvn.gcp (GVNGCM.Mode.Opto,scope()); // Global Constant Propagation
112  _gvn.iter(GVNGCM.Mode.PesiCG); // Re-check all ideal calls now that types have been maximally lifted
113  _gvn.gcp (GVNGCM.Mode.Opto,scope()); // Global Constant Propagation
114  _gvn.iter(GVNGCM.Mode.PesiCG); // Re-check all ideal calls now that types have been maximally lifted
115  _e._scope.unkeep();
116  //assert Type.intern_check();
117  return gather_errors();
118  }
119 
120  private void remove_unknown_callers() {
121  Ary<Node> uses = Env.ALL_CTRL._uses;
122  // For all unknown uses of functions, they will all be known after GCP.
123  // Remove the hyper-conservative ALL_CTRL edge. Note that I canNOT run the
124  // pessimistic iter() at this point, as GCP needs to discover all the
125  // actual call-graph edges and install them directly on the FunNodes.
126  for( int i=0; i<uses._len; i++ ) {
127  Node use = uses.at(i);
128  if( !use.is_prim() ) {
129  assert use instanceof FunNode;
130  assert use.in(1)==Env.ALL_CTRL;
131  use.set_def(1,Env.XCTRL);
132  i--;
133  }
134  }
135  // No longer force all memory alive
136  Env.DEFMEM.unkeep();
138  }
139 
140  private TypeEnv gather_errors() {
141  // Hunt for typing errors in the alive code
142  assert _e._par._par==null; // Top-level only
143  HashSet<Node.ErrMsg> errs = new HashSet<>();
144  VBitSet bs = new VBitSet();
145  scope().walkerr_def(errs,bs);
146  if( skipWS() != -1 ) errs.add(Node.ErrMsg.trailingjunk(this));
147  ArrayList<Node.ErrMsg> errs0 = new ArrayList<>(errs);
148  Collections.sort(errs0);
149 
150  Type res = scope().rez()._val; // New and improved result
151  Type mem = scope().mem()._val;
152  return new TypeEnv(res, mem instanceof TypeMem ? (TypeMem)mem : mem.oob(TypeMem.ALLMEM),_e,errs0.isEmpty() ? null : errs0);
153  }
154 
157  private void prog() {
159  Node res = stmts();
160  if( res == null ) res = con(Type.ANY);
161  scope().set_rez(res); // Hook result
162  }
163 
167  private Node stmts() { return stmts(false); }
168  private Node stmts(boolean lookup_current_scope_only) {
169  Node stmt = tstmt(), last = null;
170  if( stmt == null ) stmt = stmt(lookup_current_scope_only);
171  while( stmt != null ) {
172  if( !peek(';') ) return stmt;
173  last = stmt.keep();
174  stmt = tstmt();
175  if( stmt == null ) stmt = stmt(lookup_current_scope_only);
176  Env.GVN.add_flow(last.unkeep());
177  if( stmt == null ) {
178  if( peek(';') ) { _x--; stmt=last; } // Ignore empty statement
179  } else if( !last.is_dead() && stmt != last) kill(last); // prior expression result no longer alive in parser
180  }
181  return last;
182  }
183 
195  private Node tstmt() {
196  int oldx = _x;
197  String tvar = token(); // Scan for tvar
198  if( tvar == null || !peek('=') || !peek(':') ) { _x = oldx; return null; }
199  tvar = tvar.intern();
200  // Must be a type-variable assignment
201  Type t = typev();
202  if( t==null ) return err_ctrl2("Missing type after ':'");
203  if( peek('?') ) return err_ctrl2("Named types are never nil");
204  if( lookup(tvar) != null ) return err_ctrl2("Cannot re-assign val '"+tvar+"' as a type");
205  Parse bad = errMsg();
206  // Single-inheritance & vtables & RTTI:
207  // "Objects know thy Class"
208  // Which means a TypeObj knows its Name. It's baked into the vtable.
209  // Which means TypeObj is named and not the pointer-to-TypeObj.
210  // "Point= :@{x,y}" declares "Point" to be a type Name for "@{x,y}".
211  Type named = t.set_name((tvar+":").intern()); // Add a name
212  ConTypeNode tn = _e.lookup_type(tvar);
213  if( tn == null ) {
214  // If this is a primitive type, there is no recursion and
215  // no special issues. Make a constructor and be done.
216  if( !(t instanceof TypeObj) ) {
217  // Make a ConType with a named Type
218  tn = (ConTypeNode)gvn(new ConTypeNode(tvar,named,scope()));
219  _e.add_type(tvar,tn); // Add a type mapping
220  PrimNode cvt = PrimNode.convertTypeName(t,named,bad);
221  return _e.add_fun(bad,tvar,gvn(cvt.as_fun(_gvn)));
222  }
223 
224  // Always wrap Objs with a TypeMemPtr and a unique alias.
226  // Make a ConType with a named Type
227  tn = (ConTypeNode)gvn(new ConTypeNode(tvar,tmp,scope()));
228  _e.add_type(tvar,tn); // Add a type mapping
229  }
230 
231  // A forward-ref ConTypeNode. Close the cycle.
232  tn.def_fref(named,_e);
233 
234  // Add a copy of constructor functions.
235 
236  // Build a constructor taking a pointer-to-TypeObj - and the associated
237  // memory state, i.e. takes a ptr-to-@{x,y} and returns a ptr to
238  // Named:@{x,y}. This stores a v-table ptr into an object. The alias#
239  // does not change, but a TypeMem[alias#] would now map to the Named
240  // variant.
241  TypeStruct ts = (TypeStruct)((TypeMemPtr)tn._val)._obj;
243  Node rez = _e.add_fun(bad,tvar,epi1); // Return type-name constructor
244  // Add a second constructor taking an expanded arg list
246  _e.add_fun(bad,tvar,epi2); // type-name constructor with expanded arg list
247 
248  return rez;
249  }
250 
268  private Node stmt(boolean lookup_current_scope_only) {
269  if( peek('^') ) { // Early function exit
270  Node ifex = ifex();
271  if( ifex==null ) ifex=Env.XNIL;
272  if( _e._par._par==null )
273  return err_ctrl1(Node.ErrMsg.syntax(this,"Function exit but outside any function"));
274  return _e.early_exit(this,ifex);
275  }
276 
277  // Gather ids in x = y = z = ....
278  Ary<String> toks = new Ary<>(new String[1],0);
279  Ary<Type > ts = new Ary<>(new Type [1],0);
280  Ary<Parse > badfs= new Ary<>(new Parse [1],0);
281  Ary<Parse > badts= new Ary<>(new Parse [1],0);
282  BitSet rs = new BitSet();
283  boolean default_nil = false;
284  _e.nongen_push(_e);
285  while( true ) {
286  skipWS();
287  int oldx = _x; // Unwind token parse point
288  Parse badf = errMsg(); // Capture location in case of field error
289  String tok = token(); // Scan for 'id = ...'
290  if( tok == null ) break; // Out of ids
291  int oldx2 = _x; // Unwind assignment flavor point
292  Type t = null;
293  // x =: ... type assignment, handled before we get here
294  // x = ... final assignment
295  // x := ... var assignment
296  // x : type = ... typed final assignment
297  // x : type := ... typed var assignment
298  // x : nontype = ... error, missing type
299  // p? x : nontype ... part of trinary
300  Parse badt = errMsg(); // Capture location in case of type error
301  if( peek(":=") ) _x=oldx2; // Avoid confusion with typed assignment test
302  else if( peek(':') && (t=type())==null ) { // Check for typed assignment
303  if( scope().test_if() ) _x = oldx2; // Grammar ambiguity, resolve p?a:b from a:int
304  else err_ctrl0("Missing type after ':'");
305  }
306  if( peek(":=") ) rs.set(toks._len); // Re-assignment parse
307  else if( !peek_not('=','=') ) { // Not any assignment
308  // For structs, allow a bare id as a default def of nil
309  if( lookup_current_scope_only && ts.isEmpty() && (peek(';') || peek('}') ||
310  // These next two tokens are syntactically invalid, but a semi-common error situation:
311  // @{ fld;fld;fld;... fld ); // Incorrect closing paren. Go ahead and allow a bare id.
312  peek(']') || peek(')' ))) {
313  _x--; // Push back statement end
314  default_nil=true; // Shortcut def of nil
315  rs.set(toks._len); // Shortcut mutable
316  } else {
317  _x = oldx; // Unwind the token parse, and try an expression parse
318  break; // Done parsing assignment tokens
319  }
320  }
321 
322  toks .add(_e._nongen.add_var(tok.intern(),TV2.make_leaf_ns(null,"Env.add_var")));
323  ts .add(t );
324  badfs.add(badf);
325  badts.add(badt);
326  }
327 
328  // Normal statement value parse
329  Node ifex = default_nil ? Env.XNIL : ifex(); // Parse an expression for the statement value
330  // Check for no-statement after start of assignment, e.g. "x = ;"
331  if( ifex == null ) { // No statement?
332  if( toks._len == 0 ) return _e.nongen_pop(null);
333  ifex = err_ctrl2("Missing ifex after assignment of '"+toks.last()+"'");
334  }
335  // Honor all type requests, all at once, by inserting type checks on the ifex.
336  for( int i=0; i<ts._len; i++ )
337  ifex = typechk(ifex,ts.at(i),mem(),badts.at(i));
338  ifex.keep();
339 
340  // Assign tokens to value
341  for( int i=0; i<toks._len; i++ ) {
342  String tok = toks.at(i); // Token being assigned
343  Access mutable = rs.get(i) ? Access.RW : Access.Final; // Assignment is mutable or final
344  // Find scope for token. If not defining struct fields, look for any
345  // prior def. If defining a struct, tokens define a new field in this scope.
346  ScopeNode scope = lookup_scope(tok,lookup_current_scope_only);
347  if( scope==null ) { // Token not already bound at any scope
348  if( ifex instanceof FunPtrNode && !ifex.is_forward_ref() )
349  ((FunPtrNode)ifex).bind(tok); // Debug only: give name to function
350  create(tok,Env.XNIL,Access.RW); // Create at top of scope as undefined
351  scope = scope(); // Scope is the current one
352  scope.def_if(tok,mutable,true); // Record if inside arm of if (partial def error check)
353  }
354  // Handle re-assignments and forward referenced function definitions.
355  Node n = scope.stk().get(tok); // Get prior direct binding
356  if( n.is_forward_ref() ) { // Prior is a f-ref
357  assert !scope.stk().is_mutable(tok) && scope == scope();
358  if( ifex instanceof FunPtrNode )
359  ((FunPtrNode)n).merge_ref_def(tok,(FunPtrNode)ifex,scope.stk());
360  else ; // Can be here if already in-error
361 
362  } else { // Store into scope/NewObjNode/display
363 
364  // Assign into display, changing an existing def
365  Node ptr = get_display_ptr(scope); // Pointer, possibly loaded up the display-display
366  StoreNode st = new StoreNode(mem(),ptr,ifex,mutable,tok,badfs.at(i));
367  scope().replace_mem(st);
368  scope.def_if(tok,mutable,false); // Note 1-side-of-if update
369  }
370  }
371 
372  return _e.nongen_pop(ifex.unkeep());
373  }
374 
380  private Node ifex() {
381  Node expr = apply();
382  if( expr == null ) return null; // Expr is required, so missing expr implies not any ifex
383  if( !peek('?') ) return expr; // No if-expression
384 
385  scope().push_if(); // Start if-expression tracking new defs
386  Node ifex = init(new IfNode(ctrl(),expr));
387  set_ctrl(gvn(new CProjNode(ifex,1))); // Control for true branch
388  Node old_mem = mem().keep(2); // Keep until parse false-side
389  Node tex = stmt(false); // Parse true expression
390  if( tex == null ) tex = err_ctrl2("missing expr after '?'");
391  tex.keep(2); // Keep until merge point
392  Node t_ctrl= ctrl().keep(2); // Keep until merge point
393  Node t_mem = mem ().keep(2); // Keep until merge point
394 
395  scope().flip_if(); // Flip side of tracking new defs
397  set_ctrl(gvn(new CProjNode(ifex,0))); // Control for false branch
399  set_mem(old_mem.unkeep(2)); // Reset memory to before the IF
400  Node fex = peek(':') ? stmt(false) : Env.XNIL;
401  if( fex == null ) fex = err_ctrl2("missing expr after ':'");
402  fex.keep(2); // Keep until merge point
403  Node f_ctrl= ctrl().keep(2); // Keep until merge point
404  Node f_mem = mem ().keep(2); // Keep until merge point
405 
406  Parse bad = errMsg();
407  t_mem = scope().check_if(true ,bad,_gvn,t_ctrl,t_mem); // Insert errors if created only 1 side
408  f_mem = scope().check_if(false,bad,_gvn,f_ctrl,f_mem); // Insert errors if created only 1 side
409  scope().pop_if(); // Pop the if-scope
410  RegionNode r = set_ctrl(init(new RegionNode(null,t_ctrl.unkeep(2),f_ctrl.unkeep(2))));
411  r._val = Type.CTRL;
412  _gvn.add_reduce(t_ctrl);
413  _gvn.add_reduce(f_ctrl);
414  if( t_ctrl._val==Type.XCTRL ) _gvn.add_flow(t_mem);
415  if( f_ctrl._val==Type.XCTRL ) _gvn.add_flow(f_mem);
416  set_mem( gvn(new PhiNode(TypeMem.FULL,bad,r ,t_mem.unkeep(2),f_mem.unkeep(2))));
417  Node rez = gvn(new PhiNode(Type.SCALAR ,bad,r.unkeep(2),tex.unkeep(2), fex.unkeep(2))) ; // Ifex result
418  _gvn.add_work_all(r);
419  return rez;
420  }
421 
427  private Node apply() {
428  Node expr = expr();
429  if( expr == null ) return null;
430  while( true ) {
431  skipWS();
432  int oldx = _x;
433  int old_last = _lastNWS;
434  expr.keep(2); // Keep alive across argument parse
435  Node arg = expr();
436  if( arg==null ) return expr.unkeep(2);
437  // To avoid the common bug of forgetting a ';', these must be on the same line.
438  int line_last = _lines.binary_search(old_last);
439  int line_now = _lines.binary_search(_x);
440  if( line_last != line_now ) {
441  _x = oldx; _lastNWS = old_last; expr.unhook();
442  return err_ctrl2("Lisp-like function application split between lines "+line_last+" and "+line_now+", but must be on the same line; possible missing semicolon?");
443  }
444  expr = do_call(errMsgs(oldx,oldx),args(expr.unkeep(2),arg)); // Pass the 1 arg
445  }
446  }
447 
459  private Node expr() {
460  skipWS(); // Invariant: WS already skipped before & after each expr depth
461  return _expr(1);
462  }
463 
464  // Invariant: WS already skipped before & after each _expr depth
465  private Node _expr(int prec) {
466  int lhsx = _x; // Invariant: WS already skipped
467  Node lhs = _expr_higher(prec,null);
468  if( lhs==null ) return null;
469  while( true ) { // Kleene star at this precedence
470  // Look for a binop at this precedence level
471  int opx = _x; // Invariant: WS already skipped
472  String bintok = peek(PrimNode.PRIM_TOKS);
473  if( !_good_prec_tok(prec,bintok) ) return lhs; // No token at this precedence
474  _x += bintok.length();
475  skipWS();
476  int rhsx = _x; // Invariant: WS already skipped
477  lhs.keep();
478  // Get the matching FunPtr (or Unresolved).
479  // This is a primitive lookup and always returns a FRESH copy (see HM.Ident).
480  UnOrFunPtrNode op = _e.lookup_filter_fresh(bintok.intern(),2,ctrl()); // BinOp, or null
481  assert op!=null; // Since found valid token, must find matching primnode
482  FunNode sfun = op.funptr().fun();
483  assert sfun._op_prec == prec;
484  // Check for Thunking the RHS
485  if( sfun._thunk_rhs ) {
486  lhs = _short_circuit_expr(lhs.unkeep(),prec,bintok,op,opx,lhsx,rhsx);
487  } else { // Not a thunk! Eager evaluation of RHS
488  op.keep();
489  Node rhs = _expr_higher_require(prec,bintok,lhs.unkeep());
490  // Emit the call to both terms
491  // LHS in unhooked prior to optimizing/replacing.
492  lhs = do_call(errMsgs(opx,lhsx,rhsx), args(op.unkeep(),lhs,rhs));
493  }
494  // Invariant: LHS is unhooked
495  }
496  }
497 
498  // Get an expr at the next higher precedence, or a term, or null
499  private Node _expr_higher( int prec, Node lhs ) {
500  if( lhs != null ) lhs.keep();
501  Node rhs = prec+1 == PrimNode.PREC_TOKS.length ? term() : _expr(prec+1);
502  if( lhs != null ) lhs.unkeep();
503  return rhs;
504  }
505  private Node _expr_higher_require( int prec, String bintok, Node lhs ) {
506  Node rhs = _expr_higher(prec,lhs);
507  return rhs==null ? err_ctrl2("Missing term after '"+bintok+"'") : rhs;
508  }
509  // Check that this token is valid for this precedence level
510  private boolean _good_prec_tok(int prec, String bintok) {
511  if( bintok==null ) return false;
512  for( String tok : PrimNode.PREC_TOKS[prec] ) if( Util.eq(bintok,tok) ) return true;
513  return false;
514  }
515 
516  // Short-circuit 'thunks' the RHS operator and passes it to a thunk-aware
517  // primitive. The primitive is required to fully inline & optimize out the
518  // Thunk before we exit here. However, the primitive can do pretty much what
519  // it wants with the Thunk (currently nil-check LHS, then optionally Call the
520  // thunk).
521  private Node _short_circuit_expr(Node lhs, int prec, String bintok, Node op, int opx, int lhsx, int rhsx) {
522  // Capture state so we can unwind after parsing delayed execution
523  NewObjNode stk = scope().stk(); // Display
524  Node old_ctrl = ctrl().keep(2);
525  Node old_mem = mem ().keep(2);
526  op.keep(2);
527  TypeStruct old_ts = stk._ts;
528  Ary<Node> old_defs = stk._defs.deepCopy();
529  lhs.keep(2);
530 
531  // Insert a thunk header to capture the delayed execution
532  ThunkNode thunk = (ThunkNode)gvn(new ThunkNode(mem()));
533  set_ctrl(thunk);
534  set_mem (gvn(new ParmNode(MEM_IDX,"mem",thunk.keep(2),TypeMem.MEM,Env.DEFMEM,null)));
535 
536  // Delayed execution parse of RHS
537  Node rhs = _expr_higher_require(prec,bintok,lhs);
538 
539  // Insert thunk tail, unwind memory state
540  ThretNode thet = gvn(new ThretNode(ctrl(),mem(),rhs,Env.GVN.add_flow(thunk.unkeep(2)))).keep(2);
541  set_ctrl(old_ctrl.unkeep(2));
542  set_mem (old_mem .unkeep(2));
543  for( int i=0; i<old_defs._len; i++ )
544  assert old_defs.at(i)==stk._defs.at(i); // Nothing peeked thru the Thunk & updated outside
545 
546  // Emit the call to both terms. Both the emitted call and the thunk MUST
547  // inline right now.
548  lhs = do_call(errMsgs(opx,lhsx,rhsx), args(op.unkeep(2),lhs.unkeep(2),thet.unkeep(2)));
549  assert thunk.is_dead() && thet.is_dead(); // Thunk, in fact, inlined
550 
551  // Extra variables in the thunk not available after the thunk.
552  // Set them to Err.
553  if( stk._ts != old_ts ) {
554  lhs.keep(2);
555  for( int i=old_defs._len; i<stk._defs._len; i++ ) {
556  String fname = stk._ts.fld(i-1)._fld;
557  String msg = "'"+fname+"' not defined prior to the short-circuit";
558  Parse bad = errMsg(rhsx);
559  Node err = gvn(new ErrNode(ctrl(),bad,msg));
560  set_mem(gvn(new StoreNode(mem(),scope().ptr(),err,Access.Final,fname,bad)));
561  }
562  lhs.unkeep(2);
563  }
564  return lhs;
565  }
566 
574  // Invariant: WS already skipped before & after term
575  private Node term() {
576  int oldx = _x;
577  String uni = token();
578  if( uni!=null ) {
579  // This is a primitive lookup and always returns a FRESH copy (see HM.Ident).
580  UnOrFunPtrNode unifun = _e.lookup_filter_fresh(uni.intern(),1,ctrl()); // UniOp, or null
581  FunPtrNode ptr = unifun==null ? null : unifun.funptr();
582  if( ptr==null || ptr.fun()._op_prec <= 0 ) _x=oldx; // Not a uniop
583  else {
584  // Token might have been longer than the filtered name; happens if a
585  // bunch of operator characters are adjacent but we can make an operator
586  // out of the first few.
587  _x = oldx+ptr.fun().fptr()._name.length();
588  unifun.keep();
589  Node term = term();
590  if( term==null ) { unifun.unhook(); _x = oldx; return null; }
591  unifun.unkeep();
592  return do_call(errMsgs(0,oldx),args(unifun,term));
593  }
594  }
595 
596  // Check for id++ / id--
597  String tok = token();
598  if( tok != null ) {
599  Node n;
600  if( peek("++") && (n=inc(tok, 1))!=null ) return n;
601  if( peek("--") && (n=inc(tok,-1))!=null ) return n;
602  }
603  _x = oldx;
604 
605  // Normal term expansion
606  Node n = tfact();
607  if( n == null ) return null;
608  while( true ) { // Repeated application or field lookup is fine
609  if( peek('.') ) { // Field?
610  skipWS(); //
611  int fld_start=_x; // Get field start
612  String fld = token0(); // Field name
613  if( fld == null ) { // Not a token, check for a field number
614  int fldnum = field_number();
615  if( fldnum == -1 ) return err_ctrl2("Missing field name after '.'");
616  fld = ""+fldnum; // Convert to a field name
617  }
618  fld=fld.intern();
619 
620  Node castnn = gvn(new CastNode(ctrl(),n,TypeMemPtr.ISUSED)); // Remove nil choice
621 
622  // Store or load against memory
623  if( peek(":=") || peek_not('=','=')) {
624  Access fin = _buf[_x-2]==':' ? Access.RW : Access.Final;
625  Node stmt = stmt(false);
626  if( stmt == null ) n = err_ctrl2("Missing stmt after assigning field '."+fld+"'");
627  else scope().replace_mem( new StoreNode(mem(),castnn,n=stmt.keep(),fin,fld ,errMsg(fld_start)));
628  skipWS();
629  return n.unkeep();
630  } else {
631  n = gvn(new LoadNode(mem(),castnn,fld,errMsg(fld_start)));
632  }
633 
634  } else if( peek('(') ) { // Attempt a function-call
635  oldx = _x; // Just past paren
636  skipWS(); // Skip to start of 1st arg
637  n.keep(); // Keep alive across arg parse
638  int first_arg_start = _x;
639  Node arg = tuple(oldx-1,stmts(),first_arg_start); // Parse argument list
640  if( arg == null ) // tfact but no arg is just the tfact
641  { _x = oldx; return n.unkeep(); }
642  Type tn = n._val;
643  boolean may_fun = tn.isa(TypeFunPtr.GENERIC_FUNPTR);
644  if( !may_fun && arg.op_prec() >= 0 ) { _x=oldx; return n.unkeep(); }
645  if( !may_fun &&
646  // Notice the backwards condition: n was already tested for !(tn instanceof TypeFun).
647  // Now we test the other way: the generic function can never be an 'n'.
648  // Only if we cannot 'isa' in either direction do we bail out early
649  // here. Otherwise, e.g. 'n' might be an unknown function argument
650  // and during GCP be 'lifted' to a function; if we bail out now we
651  // may disallow a legal program with function arguments. However,
652  // if 'n' is a e.g. Float there's no way it can 'lift' to a function.
653  !TypeFunPtr.GENERIC_FUNPTR.isa(tn) ) {
654  kill(arg);
655  n.unhook();
656  n = err_ctrl2("A function is being called, but "+tn+" is not a function");
657  } else {
658  Parse[] badargs = ((NewObjNode)arg.in(0))._fld_starts; // Args from tuple
659  badargs[0] = errMsg(oldx-1); // Base call error reported at the opening paren
660  n = do_call0(false,badargs,args(n.unkeep(),arg)); // Pass the tuple
661  }
662 
663  } else {
664  // Check for balanced op
665  n.keep();
666  UnOrFunPtrNode bfun = bal_open(); // Balanced op read
667  if( bfun==null ) { n.unkeep(); break; } // Not a balanced op
668 
669  oldx = _x-1; // Token start
670  skipWS();
671  bfun.keep(); // Keep alive across arg parse
672  int oldx2 = _x;
673  Node idx = stmts(); // Index expression
674  tok = token();
675  if( idx==null || tok==null ) { n.unhook(); bfun.unkeep(); return err_ctrl2("Missing stmts after '"+tok+"'"); }
676  _x -= tok.length(); // Unwind, since token length depends on match
677 
678  // Need to find which balanced op close. Find the longest matching name
679  FunPtrNode fptr=null;
680  UnresolvedNode unr = ((UnOrFunPtrNode)bfun.unkeep()).unk();
681  if( unr!=null ) { // Unresolved of balanced ops?
682  for( Node def : unr._defs ) {
683  FunPtrNode def0 = (FunPtrNode)def;
684  if( tok.startsWith(def0.fun()._bal_close) &&
685  (fptr==null || fptr.fun()._bal_close.length() < def0.fun()._bal_close.length()) )
686  fptr = def0; // Found best match
687  }
688  Env.GVN.add_dead(Env.GVN.add_reduce(bfun)); // Dropping any new FreshNode, and replacing with this one
689  idx.keep();
690  bfun = (UnOrFunPtrNode)gvn(new FreshNode(_e._nongen,ctrl(),fptr));
691  } else fptr = bfun.funptr(); // Just the one balanced op
692  FunNode fun = fptr.fun();
693  require(fun._bal_close,oldx);
694  if( fun.nargs()==ARG_IDX+2 ) { // array, index
695  n = do_call(errMsgs(0,oldx,oldx2),args(bfun,n.unkeep(),idx.unkeep()));
696  } else {
697  assert fun.nargs()==ARG_IDX+3; // array, index, value
698  skipWS();
699  int oldx3 = _x;
700  bfun.keep();
701  Node val = stmt(false);
702  if( val==null ) { n.unhook(); return err_ctrl2("Missing stmt after '"+fun._bal_close+"'"); }
703  n = do_call(errMsgs(0,oldx,oldx2,oldx3),args(bfun.unkeep(),n.unkeep(),idx.unkeep(),val));
704  }
705  }
706  }
707  return n;
708  }
709 
710  // Handle post-increment/post-decrement operator.
711  // Does not define a field in structs: "@{ x++; y=2 }" - syntax error, no such field x
712  // Skips trailing WS
713  private Node inc(String tok, int d) {
714  skipWS();
715  ScopeNode scope = lookup_scope(tok=tok.intern(),false); // Find prior scope of token
716  // Need a load/call/store sensible options
717  Node n;
718  if( scope==null ) { // Token not already bound to a value
719  create(tok,Env.XNIL,Access.RW);
720  scope = scope();
721  } else { // Check existing token for mutable
722  if( !scope.is_mutable(tok) )
723  return err_ctrl2("Cannot re-assign final val '"+tok+"'");
724  }
725 
726  // Scope is discovered by walking lexical display stack.
727  // Pointer to the proper display is found via ptr-walking live display stack.
728  // Now properly load from the display.
729  // This does a HM.Ident lookup, producing a FRESH tvar every time.
730  Node ptr = get_display_ptr(scope);
731  n = gvn(new FreshNode(_e._nongen,ctrl(),gvn(new LoadNode(mem(),ptr,tok,null))));
732  if( n.is_forward_ref() ) // Prior is actually a forward-ref
733  return err_ctrl1(Node.ErrMsg.forward_ref(this,((FunPtrNode)n)));
734  // Do a full lookup on "+", and execute the function
735  n.keep();
736  // This is a primitive lookup and always returns a FRESH copy (see HM.Ident).
737  Node plus = _e.lookup_filter_fresh("+",2,ctrl());
738  Node sum = do_call(errMsgs(0,_x,_x),args(plus,n,con(TypeInt.con(d))));
739  // Active memory for the chosen scope, after the call to plus
740  scope().replace_mem(new StoreNode(mem(),ptr,sum,Access.RW,tok,errMsg()));
741  return n.unkeep(); // Return pre-increment value
742  }
743 
747  private Node tfact() {
748  Node fact = fact();
749  if( fact==null ) return null;
750  int oldx = _x;
751  Parse bad = errMsg();
752  if( !peek(':') ) { _x = oldx; return fact; }
753  Type t = type();
754  if( t==null ) { _x = oldx; return fact; } // No error for missing type, because can be ?: instead
755  return typechk(fact,t,mem(),bad);
756  }
757 
772  private Node fact() {
773  if( skipWS() == -1 ) return null;
774  byte c = _buf[_x];
775  if( isDigit(c) ) return con(number());
776  if( '"' == c ) {
777  Node str = string();
778  return str==null ? err_ctrl2("Unterminated string") : str;
779  }
780  int oldx = _x;
781  if( peek1(c,'(') ) { // a nested statement or a tuple
782  int first_arg_start = _x;
783  Node s = stmts();
784  if( s==null ) { _x = oldx; return null; } // A bare "()" pair is not a statement
785  if( peek(')') ) return s; // A (grouped) statement
786  if( !peek(',') ) return s; // Not a tuple, probably a syntax error
787  _x --; // Reparse the ',' in tuple
788  return tuple(oldx,s,first_arg_start); // Parse a tuple
789  }
790  // Anonymous function or operator
791  if( peek1(c,'{') ) {
792  String tok = token0();
793  Node op = tok == null ? null : _e.lookup(tok.intern());
794  if( peek('}') && op != null && op.op_prec() > 0 )
795  // This is a primitive operator lookup as a function constant, and
796  // makes a FRESH copy like HM.Ident.
797  return gvn(new FreshNode(_e._nongen,ctrl(),op));
798  _x = oldx+1; // Back to the opening paren
799  return func(); // Anonymous function
800  }
801  // Anonymous struct
802  if( peek2(c,"@{") ) return struct();
803 
804  // Check for a valid 'id'
805  String tok = token0();
806  if( tok == null ) { _x = oldx; return null; }
807  tok = tok.intern();
808  if( Util.eq(tok,"=") || Util.eq(tok,"^") )
809  { _x = oldx; return null; } // Disallow '=' as a fact, too easy to make mistakes
810  ScopeNode scope = lookup_scope(tok,false);
811  if( scope == null ) { // Assume any unknown id is a forward-ref of a recursive function
812  // Ops cannot be forward-refs, so are just 'not a fact'. Cannot declare
813  // them as a undefined forward-ref right now, because the op might be the
814  // tail-half of a balanced-op, which is parsed by term() above.
815  if( isOp(tok) ) { _x = oldx; return null; }
816  // Must be a forward reference
817  Env fref_env = _e.lookup_fref(tok=tok.intern());
818  if( fref_env==null ) fref_env = _e;
819  Node fref = gvn(FunPtrNode.forward_ref(_gvn,tok,errMsg(oldx),fref_env));
820  // Place in nearest enclosing closure scope, this will keep promoting until we find the actual scope
821  fref_env._scope.stk().create(tok,fref,Access.Final);
822  return fref;
823  }
824  Node def = scope.get(tok); // Get top-level value; only sane if no stores allowed to modify it
825  // Disallow uniop and binop functions as factors. Only possible if trying
826  // to use an operator as a factor, such as "plus = {+}" or "f(1,{+},2)".
827  if( def.op_prec() > 0 ) { _x = oldx; return null; }
828  // Balanced ops are similar to "{}", "()" or "@{}".
829  if( def.op_prec()==0 && def._val instanceof TypeFunPtr )
830  return bfact(oldx,(UnOrFunPtrNode)def);
831 
832  // Else must load against most recent display update. Get the display to
833  // load against. If the scope is local, we load against it directly,
834  // otherwise the display is passed in as a hidden argument.
835  // This does a HM.Ident lookup, producing a FRESH tvar every time.
836  Node ptr = get_display_ptr(scope);
837  return gvn(new FreshNode(_e._nongen,ctrl(),gvn(new LoadNode(mem(),ptr,tok.intern(),null))));
838  }
839 
843  private Node tuple(int oldx, Node s, int first_arg_start) {
844  Parse bad = errMsg(first_arg_start);
845  Ary<Parse> bads = new Ary<>(new Parse[1],1);
846  Ary<Node > args = new Ary<>(new Node [1],0);
847  while( s!= null ) { // More args
848  bads.push(bad); // Collect arg & arg start
849  args.push(s.keep());
850  if( !peek(',') ) break; // Final comma is optional
851  skipWS(); // Skip to arg start before recording arg start
852  bad = errMsg(); // Record arg start
853  s=stmts(); // Parse arg
854  }
855  require(')',oldx); // Balanced closing paren
856 
857  // Build the tuple from gathered args
859  for( int i=0; i<args._len; i++ )
860  nn.create_active((""+i).intern(),args.at(i).unkeep(),Access.Final);
861  nn._fld_starts = bads.asAry();
862  nn.no_more_fields();
863  init(nn);
864  nn.xval();
865 
866  // NewNode returns a TypeMem and a TypeMemPtr (the reference).
868  return gvn(new ProjNode(nn.unkeep(2),REZ_IDX));
869  }
870 
876  private Node struct() {
877  int oldx = _x-1; Node ptr; // Opening @{
878  try( Env e = new Env(_e,errMsg(oldx-1), false,ctrl(),mem()) ) { // Nest an environment for the local vars
879  _e = e; // Push nested environment
880  stmts(true); // Create local vars-as-fields
881  require('}',oldx); // Matched closing }
882  assert ctrl() != e._scope;
883  ptr = e._scope.ptr().keep(); // A pointer to the constructed object
884  e._par._scope.set_ctrl(ctrl()); // Carry any control changes back to outer scope
885  e._par._scope.set_mem (mem ()); // Carry any memory changes back to outer scope
886  _e = e._par; // Pop nested environment
887  } // Pop lexical scope around struct
888  return ptr.unkeep();
889  }
890 
896  private static final Access args_are_mutable=Access.Final; // Args mutable or r/only by default
897  private Node func() {
898  int oldx = _x; // Past opening '{'
899  Ary<String> ids = new Ary<>(new String[1],0);
900  Ary<Type > ts = new Ary<>(new Type [1],0);
901  Ary<Parse > bads= new Ary<>(new Parse [1],0);
902 
903  // Push an extra hidden display argument. Similar to java inner-class ptr
904  // or when inside of a struct definition: 'this'.
905  Node parent_display = scope().ptr();
906  TypeMemPtr tpar_disp = (TypeMemPtr) parent_display._val; // Just a TMP of the right alias
907  Node fresh_disp = gvn(new FreshNode(_e._nongen,ctrl(),parent_display)).keep();
908 
909  ids .push(" ctl");
910  ts .push(Type.CTRL);
911  bads.push(null);
912  ids .push(" mem");
913  ts .push(TypeMem.MEM);
914  bads.push(null);
915  ids .push("^");
916  ts .push(tpar_disp);
917  bads.push(null);
918 
919  // Parse arguments
920  while( true ) {
921  String tok = token();
922  if( tok == null ) { _x=oldx; break; } // not a "[id]* ->"
923  if( Util.eq((tok=tok.intern()),"->") ) break; // End of argument list
924  if( !isAlpha0((byte)tok.charAt(0)) ) { _x=oldx; break; } // not a "[id]* ->"
925  Type t = Type.SCALAR; // Untyped, most generic type
926  Parse bad = errMsg(); // Capture location in case of type error
927  if( peek(':') && // Has type annotation?
928  (t=type())==null ) { // Get type
929  // If no type, might be "{ x := ...}" or "{ fun arg := ...}" which can
930  // be valid stmts, hence this may be a no-arg function.
931  if( ids._len-1 <= 2 ) { _x=oldx; break; }
932  else {
933  // Might be: "{ x y z:bad -> body }" which cannot be any stmt. This
934  // is an error in any case. Treat as a bad type on a valid function.
935  err_ctrl0(peek(',') ? "Bad type arg, found a ',' did you mean to use a ';'?" : "Missing or bad type arg");
936  t = Type.SCALAR;
937  skipNonWS(); // Skip possible type sig, looking for next arg
938  }
939  }
940  ids .add(tok); // Accumulate args
941  ts .add(t );
942  bads.add(bad);
943  }
944  // If this is a no-arg function, we may have parsed 1 or 2 tokens as-if
945  // args, and then reset. Also reset to just the mem & display args.
946  if( _x == oldx ) { ids.set_len(ARG_IDX); ts.set_len(ARG_IDX); bads.set_len(ARG_IDX); }
947 
948  try( GVNGCM.Build<Node> X = _gvn.new Build<>()) { // Nest an environment for the local vars
949  // Build the FunNode header
950  FunNode fun = (FunNode)X.xform(new FunNode(ids.asAry(),ts.asAry()).add_def(Env.ALL_CTRL));
951  // Record H-M VStack in case we clone
952  fun.set_nongens(_e._nongen.compact());
953  // Build Parms for system incoming values
954  Node rpc = X.xform(new ParmNode(0 ,"rpc" ,fun,con(TypeRPC.ALL_CALL),null));
955  Node mem = X.xform(new ParmNode(MEM_IDX," mem",fun,TypeMem.MEM,Env.DEFMEM,null));
956  Node clo = X.xform(new ParmNode(DSP_IDX,"^" ,fun,con(tpar_disp),null));
957 
958  // Increase scope depth for function body.
959  try( Env e = new Env(_e,errMsg(oldx-1), true, fun, mem) ) { // Nest an environment for the local vars
960  _e = e; // Push nested environment
961  // Display is special: the default is simply the outer lexical scope.
962  // But here, in a function, the display is actually passed in as a hidden
963  // extra argument and replaces the default.
964  NewObjNode stk = e._scope.stk();
965  stk.update(0,Access.Final,clo);
966  // Add a nongen memory arg
967  _e._nongen.add_var(" mem",mem.tvar());
968 
969  // Parms for all arguments
970  Parse errmsg = errMsg(); // Lazy error message
971  for( int i=ARG_IDX; i<ids._len; i++ ) { // User parms start
972  Node parm = X.xform(new ParmNode(i,ids.at(i),fun,con(Type.SCALAR),errmsg));
973  _e._nongen.add_var(ids.at(i),parm.tvar());
974  create(ids.at(i),parm, args_are_mutable);
975  }
976 
977  // Parse function body
978  Node rez = stmts(); // Parse function body
979  if( rez == null ) rez = err_ctrl2("Missing function body");
980  require('}',oldx-1); // Matched with opening {}
981 
982  // Merge normal exit into all early-exit paths
983  if( e._scope.is_closure() ) rez = merge_exits(rez);
984  // Standard return; function control, memory, result, RPC. Plus a hook
985  // to the function for faster access.
986  RetNode ret = (RetNode)X.xform(new RetNode(ctrl(),mem(),rez,rpc,fun));
987  // The FunPtr builds a real display; any up-scope references are passed in now.
988  Node fptr = X.xform(new FunPtrNode(null,ret,fresh_disp.unhook()));
989 
990  _e = _e._par; // Pop nested environment; pops nongen also
991  return (X._ret=fptr); // Return function; close-out and DCE 'e'
992  }
993  }
994  }
995 
996  private Node merge_exits(Node rez) {
997  rez.keep();
998  ScopeNode s = scope();
999  Node ctrl = s.early_ctrl();
1000  Node mem = s.early_mem ();
1001  Node val = s.early_val ();
1002  s.early_kill();
1003  if( ctrl == null ) return rez.unkeep(); // No other exits to merge into
1004  try(GVNGCM.Build<Node> X = _gvn.new Build<>()) {
1005  ctrl = ctrl.add_def(ctrl()).unkeep();
1006  ctrl._val = Type.CTRL;
1007  set_ctrl(ctrl=X.init(ctrl));
1008  mem.unkeep().set_def(0,ctrl);
1009  val.unkeep().set_def(0,ctrl);
1010  Node mem2 = X.xform(mem.add_def(mem()));
1011  Node val2 = X.xform(val.add_def(rez.unkeep()));
1012  set_mem(mem2);
1013  return (X._ret=val2);
1014  }
1015  }
1016 
1017  // Merge this early exit path into all early exit paths being recorded in the
1018  // current Env/Scope.
1020  Node ctrl = s.early_ctrl();
1021  Node mem = s.early_mem ();
1022  Node val = s.early_val ();
1023  if( ctrl == null ) {
1024  s.set_def(4,ctrl=new RegionNode((Node)null).keep()); ctrl._val=Type.CTRL;
1025  s.set_def(5,mem =new PhiNode(TypeMem.MEM, null,(Node)null).keep());
1026  s.set_def(6,val =new PhiNode(Type.SCALAR, null,(Node)null).keep());
1027  }
1028  ctrl.add_def(ctrl());
1029  mem .add_def(mem ());
1030  val .add_def(rez );
1031  set_ctrl(Env.XCTRL);
1032  set_mem (con(TypeMem.XMEM));
1033  return Env.XNIL;
1034  }
1035 
1040  Node bfact(int oldx, UnOrFunPtrNode bfun) {
1041  skipWS();
1042  int oldx2 = _x; // Start of stmts
1043  Node s = stmts();
1044  if( s==null ) { _x = oldx; return null; } // A bare "()" pair is not a statement
1045  if( peek(',') ) {
1046  _x --; // Reparse the ',' in tuple
1047  throw unimpl();
1048  }
1049  require(bfun.funptr().fun()._bal_close,oldx);
1050  return do_call(errMsgs(oldx,oldx2),args(bfun,s));
1051  }
1052 
1053  // Lookup a balanced open function of 2 or 3 arguments.
1055  int oldx = _x;
1056  String bal = token();
1057  if( bal==null ) return null;
1058  // This is a primitive lookup and always returns a FRESH copy (see HM.Ident).
1059  UnOrFunPtrNode bfun = _e.lookup_filter_fresh(bal.intern(),0,ctrl()); // No nargs filtering
1060  if( bfun==null || bfun.op_prec() != 0 ) { _x=oldx; return null; }
1061  // Actual minimal length uniop might be smaller than the parsed token
1062  // (greedy algo vs not-greed)
1063  _x = oldx+bfun.funptr()._name.length();
1064  return bfun;
1065  }
1066 
1067  // Add a typecheck into the graph, with a shortcut if trivially ok.
1068  private Node typechk(Node x, Type t, Node mem, Parse bad) {
1069  return t == null || x._val.isa(t) ? x : gvn(new AssertNode(mem,x,t,bad,_e));
1070  }
1071 
1072  private String token() { skipWS(); return token0(); }
1073  // Lexical tokens. Any alpha, followed by any alphanumerics is a alpha-
1074  // token; alpha-tokens end with WS or any operator character. Any collection
1075  // of the classic operator characters are a token, except that they will break
1076  // un-ambiguously.
1077  private String token0() {
1078  if( _x >= _buf.length ) return null;
1079  byte c=_buf[_x]; int x = _x;
1080  if( isAlpha0(c) ) while( _x < _buf.length && isAlpha1(_buf[_x]) ) _x++;
1081  else if( isOp0(c) ) while( _x < _buf.length && isOp1 (_buf[_x]) ) _x++;
1082  else return null; // Not a token; specifically excludes e.g. all bytes >= 128, or most bytes < 32
1083  if( (c==':' || c==',') && _x-x==1 ) // Disallow bare ':' as a token; ambiguous with ?: and type annotations; same for ','
1084  { _x=x; return null; } // Unwind, not a token
1085  if( c=='-' && _x-x>2 && _buf[x+1]=='>' ) // Disallow leading "->", confusing with function parameter list end; eg "not={x->!x}"
1086  _x=x+2; // Just return the "->"
1087  return new String(_buf,x,_x-x);
1088  }
1089  static boolean isOp(String s) {
1090  if( !isOp0((byte)s.charAt(0)) ) return false;
1091  for( int i=1; i<s.length(); i++ )
1092  if( !isOp1((byte)s.charAt(i)) ) return false;
1093  return true;
1094  }
1095 
1096  // Parse a number; WS already skipped and sitting at a digit. Relies on
1097  // Javas number parsing.
1098  private Type number() {
1099  _pp.setIndex(_x);
1100  Number n = _nf.parse(_str,_pp);
1101  _x = _pp.getIndex();
1102  if( n instanceof Long ) return n.longValue()==0 ? Type.XNIL : TypeInt.con(n. longValue());
1103  if( n instanceof Double ) return TypeFlt.con(n.doubleValue());
1104  throw new RuntimeException(n.getClass().toString()); // Should not happen
1105  }
1106  // Parse a small positive integer; WS already skipped and sitting at a digit.
1107  private int field_number() {
1108  byte c = _buf[_x];
1109  if( !isDigit(c) ) return -1;
1110  _x++;
1111  int sum = c-'0';
1112  while( _x < _buf.length && isDigit(c=_buf[_x]) ) {
1113  _x++;
1114  sum = sum*10+c-'0';
1115  }
1116  return sum;
1117  }
1118 
1123  private Node string() {
1124  int oldx = ++_x;
1125  byte c;
1126  while( (c=_buf[_x++]) != '"' ) {
1127  if( c=='%' ) throw unimpl();
1128  if( c=='\\' ) throw unimpl();
1129  if( _x == _buf.length ) return null;
1130  }
1131  String str = new String(_buf,oldx,_x-oldx-1).intern();
1132  // Convert to ptr-to-constant-memory-string
1133  NewNode nnn = (NewNode)gvn( new NewStrNode.ConStr(str) );
1134  if( Env.DEFMEM._defs.atX(nnn._alias)==null )
1136  return gvn( new ProjNode(nnn,REZ_IDX));
1137  }
1138 
1152  private Type type() { return typep(false); }
1153  // Returning a type variable assignment result or null. Flag to allow
1154  // unknown type variables as forward-refs.
1155  private Type typev() {
1156  Type t = type0(true);
1157  // Type.ANY is a flag for '->' which is not a type.
1158  return t==Type.ANY ? null : t;
1159  }
1160  // TypeObjs get wrapped in a pointer, and the pointer is returned instead.
1161  private Type typep(boolean type_var) {
1162  Type t = type0(type_var);
1163  if( t instanceof TypeMemPtr ) return typeq(t); // Named type is already a TMP
1164  if( !(t instanceof TypeObj) ) return t; // Primitives are not wrapped
1165  // Automatically convert unnamed structs to refs.
1166  // Make a reasonably precise alias.
1167  int type_alias = t instanceof TypeStruct ? BitsAlias.REC : (t instanceof TypeStr ? BitsAlias.STR : BitsAlias.AARY);
1168  TypeMemPtr tmp = TypeMemPtr.make(type_alias,(TypeObj)t);
1169  return typeq(tmp); // And check for null-ness
1170  }
1171  // Wrap in a nullable if there is a trailing '?'. No spaces allowed
1172  private Type typeq(Type t) { return peek_noWS('?') ? t.meet_nil(Type.XNIL) : t; }
1173 
1174  // No mod is r/w. ':=' is read-write, '=' is final.
1175  // Currently '-' is ambiguous with function arrow ->.
1176  private Access tmod() {
1177  if( peek_not('=','=') ) { _x--; return Access.Final ; } // final , leaving trailing '='
1178  if( peek(":=" ) ) { _x--; return Access.RW ; } // read-write, leaving trailing '='
1179  if( peek("==" ) ) { _x--; return Access.ReadOnly; } // read-only , leaving trailing '='
1180  // Default for unnamed field mod
1181  return Access.RW;
1182  }
1183 
1184  // Type or null or Type.ANY for '->' token
1185  private Type type0(boolean type_var) {
1186  if( peek('{') ) { // Function type
1188  while( (t=typep(type_var)) != null && t != Type.ANY )
1189  ts.add(t); // Collect arg types
1190  Type ret;
1191  if( t==Type.ANY ) { // Found ->, expect return type
1192  ret = typep(type_var);
1193  if( ret == null ) return null; // should return TypeErr missing type after ->
1194  } else { // Allow no-args and simple return type
1195  if( ts._len != ARG_IDX+1 ) return null; // should return TypeErr missing -> in tfun
1196  ret = ts.pop(); // e.g. { int } Get single return type
1197  }
1198  TypeTuple targs = TypeTuple.make_args(ts.asAry());
1199  if( !peek('}') ) return null;
1200  return typeq(TypeFunSig.make(TypeTuple.make_ret(ret),targs));
1201  }
1202 
1203  if( peek("@{") ) { // Struct type
1204  Ary<TypeFld> flds = new Ary<>(new TypeFld[]{TypeMemPtr.DISP_FLD});
1205  while( true ) {
1206  String tok = token(); // Scan for 'id'
1207  if( tok == null ) break; // end-of-struct-def
1208  final String itok = tok.intern(); // Only 1 copy
1209  Type t = Type.SCALAR; // Untyped, most generic field type
1210  Access tmodf = tmod(); // Field access mod; trailing '=' left for us
1211  if( peek('=') && // Has type annotation?
1212  (t=typep(type_var)) == null) // Parse type, wrap ptrs
1213  t = Type.SCALAR; // No type found, assume default
1214  if( flds.find(fld -> Util.eq(fld._fld,itok) ) != -1 ) throw unimpl(); // cannot use same field name twice
1215  flds.add(TypeFld.make(itok,t,tmodf,flds._len));
1216  if( !peek(';') ) break; // Final semi-colon is optional
1217  }
1218  return peek('}') ? TypeStruct.make("",false,flds.asAry(),true) : null;
1219  }
1220 
1221  // "()" is the zero-entry tuple
1222  // "( ,)" is a 1-entry tuple
1223  // "(int )" is a 1-entry tuple (optional trailing comma)
1224  // "(int,)" is a 1-entry tuple (optional trailing comma)
1225  // "(,int)" is a 2-entry tuple
1226  // "(, , )" is a 2-entry tuple
1227  if( peek('(') ) { // Tuple type
1228  Ary<TypeFld> flds = new Ary<>(new TypeFld[]{TypeMemPtr.DISP_FLD});
1229  byte c;
1230  while( (c=skipWS()) != ')' ) { // No more types...
1231  Type t = Type.SCALAR; // Untyped, most generic field type
1232  if( c!=',' && // Has type annotation?
1233  (t=typep(type_var)) == null) // Parse type, wrap ptrs
1234  return null; // not a type
1235  flds.add(TypeFld.make_tup(t,flds._len));
1236  if( !peek(',') ) break; // Final comma is optional
1237  }
1238  return peek(')') ? TypeStruct.make("",false,flds.asAry(),true) : null;
1239  }
1240 
1241  if( peek('[') ) {
1242  Type e = typep(type_var);
1243  if( e==null ) e=Type.SCALAR;
1244  return peek(']') ? TypeAry.make(TypeInt.INT64,e,TypeObj.OBJ) : null;
1245  }
1246 
1247  // Primitive type
1248  int oldx = _x;
1249  String tok = token();
1250  if( tok==null ) return null;
1251  tok = tok.intern();
1252  if( Util.eq(tok,"->") ) return Type.ANY; // Found -> return sentinel
1253  ConTypeNode t = _e.lookup_type(tok);
1254  if( t==null ) { // Not a known type var
1255  if( lookup(tok) != null || // Yes a known normal var; resolve as a normal var
1256  !type_var ) { // Or not inside a type-var assignment
1257  _x = oldx; // Unwind if not a known type var
1258  return null; // Not a type
1259  }
1260  // Make a forward-ref ConType and return its type
1261  int alias = BitsAlias.type_alias(BitsAlias.REC);
1262  TypeMemPtr tmp = TypeMemPtr.make(alias,(TypeObj)TypeObj.ISUSED.set_name((tok+":").intern()));
1263  _e.add_type(tok,(ConTypeNode)gvn(new ConTypeNode(tok,tmp,scope())));
1264  return tmp;
1265  }
1266  return t._val;
1267  }
1268 
1269  // Require a closing character (after skipping WS) or polite error
1270  private void require( char c, int oldx ) {
1271  if( peek(c) ) return;
1272  Parse bad = errMsg(); // Generic error
1273  bad._x = oldx; // Openning point
1274  err_ctrl3("Expected closing '"+c+"' but "+(_x>=_buf.length?"ran out of text":"found '"+(char)(_buf[_x])+"' instead"),bad);
1275  }
1276  private void require( String s, int oldx ) {
1277  for( int i=0; i<s.length(); i++ )
1278  require(s.charAt(i),oldx);
1279  }
1280 
1281  // Skip WS, return true&skip if match, false & do not skip if miss.
1282  private boolean peek( char c ) { return peek1(skipWS(),c); }
1283  private boolean peek_noWS( char c ) { return peek1(_x >= _buf.length ? -1 : _buf[_x],c); }
1284  // Already skipped WS & have character;
1285  // return true & skip if match, false& do not skip if miss.
1286  private boolean peek1( byte c0, char c ) {
1287  assert c0==-1 || c0== _buf[_x];
1288  if( c0!=c ) return false;
1289  _x++; // Skip peeked character
1290  return true;
1291  }
1292  // Already skipped WS & have character;
1293  // return true&skip if match, false & do not skip if miss.
1294  private boolean peek2( byte c0, String s2 ) {
1295  if( c0 != s2.charAt(0) ) return false;
1296  if( _x+1 >= _buf.length || _buf[_x+1] != s2.charAt(1) ) return false;
1297  _x+=2; // Skip peeked characters
1298  return true;
1299  }
1300  private boolean peek( String s ) {
1301  if( !peek(s.charAt(0)) ) return false;
1302  if( !peek_noWS(s.charAt(1)) ) { _x--; return false; }
1303  return true;
1304  }
1305  // Peek 'c' and NOT followed by 'no'
1306  private boolean peek_not( char c, char no ) {
1307  byte c0 = skipWS();
1308  if( c0 != c || (_x+1 < _buf.length && _buf[_x+1] == no) ) return false;
1309  _x++;
1310  return true;
1311  }
1312  // Match any of these, and return the match or null
1313  private String peek(String[] toks) {
1314  for( String tok : toks ) if( peek1(tok) ) return tok;
1315  return null;
1316  }
1317  private boolean peek1(String tok) {
1318  for( int i=0; i<tok.length(); i++ )
1319  if( _x+i >= _buf.length || _buf[_x+i] != tok.charAt(i) )
1320  return false;
1321  return true;
1322  }
1323 
1324 
1327  private byte skipWS() {
1328  int oldx = _x;
1329  while( _x < _buf.length ) {
1330  byte c = _buf[_x];
1331  if( c=='/' && _x+1 < _buf.length && _buf[_x+1]=='/' ) { skipEOL() ; continue; }
1332  if( c=='/' && _x+1 < _buf.length && _buf[_x+1]=='*' ) { skipBlock(); continue; }
1333  if( c=='\n' && _x+1 > _lines.last() ) _lines.push(_x+1);
1334  if( !isWS(c) ) {
1335  if( oldx-1 > _lastNWS && !isWS(_buf[oldx-1]) ) _lastNWS = oldx-1;
1336  return c;
1337  }
1338  _x++;
1339  }
1340  return -1;
1341  }
1342  private void skipEOL () { while( _x < _buf.length && _buf[_x] != '\n' ) _x++; }
1343  private void skipBlock() { throw unimpl(); }
1344  // Advance parse pointer to next WS. Used for parser syntax error recovery.
1345  private void skipNonWS() {
1346  while( _x < _buf.length && !isWS(_buf[_x]) ) _x++;
1347  }
1348 
1350  private static boolean isWS (byte c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; }
1351  private static boolean isAlpha0(byte c) { return ('a'<=c && c <= 'z') || ('A'<=c && c <= 'Z') || (c=='_'); }
1352  private static boolean isAlpha1(byte c) { return isAlpha0(c) || ('0'<=c && c <= '9'); }
1353  private static boolean isOp0 (byte c) { return "!#$%*+,-.=<>^[]~/&|".indexOf(c) != -1; }
1354  private static boolean isOp1 (byte c) { return isOp0(c) || ":?".indexOf(c) != -1; }
1355  public static boolean isDigit (byte c) { return '0' <= c && c <= '9'; }
1356 
1357  // Utilities to shorten code for common cases
1358  public Node gvn (Node n) { return n==null ? null : _gvn.xform(n); }
1359  private <N extends Node> N init( N n ) { return n==null ? null : _gvn.init(n); }
1360  private void kill( Node n ) {
1361  if( n._uses._len==0 ) n.kill();
1362  }
1363  public Node ctrl() { return scope().ctrl(); }
1364  // Set and return a new control
1365  private <N extends Node> N set_ctrl(N n) { return scope().set_ctrl(n); }
1366  private Node mem() { return scope().mem(); }
1367  private void set_mem( Node n) { scope().set_mem(n); }
1368 
1369  private @NotNull ConNode con( Type t ) { return (ConNode)Node.con(t); }
1370 
1371  // Lookup & extend scopes
1372  public Node lookup( String tok ) { return _e.lookup(tok); }
1373  private ScopeNode lookup_scope( String tok, boolean lookup_current_scope_only ) { return _e.lookup_scope(tok,lookup_current_scope_only); }
1374  public ScopeNode scope( ) { return _e._scope; }
1375  private void create( String tok, Node n, Access mutable ) { scope().stk().create(tok,n,mutable); }
1376 
1377  // Get the display pointer. The function call
1378  // passed in the display as a hidden argument which we return here.
1380  // Issue Loads against the Display, until we get the correct scope. The
1381  // Display is a linked list of displays, and we already checked that token
1382  // exists at scope up in the display.
1383  Env e = _e;
1384  Node ptr = e._scope.ptr();
1385  Node mmem = mem();
1386  while( true ) {
1387  if( scope == e._scope ) return ptr;
1388  ptr = gvn(new LoadNode(mmem,ptr,"^",null)); // Gen linked-list walk code, walking display slot
1389  assert ptr.sharptr(mmem).is_display_ptr();
1390  e = e._par; // Walk linked-list in parser also
1391  }
1392  }
1393 
1394  // Wiring for call arguments
1395  private Node[] args(Node a0, Node a1 ) { return _args(new Node[]{null,null,a0,a1,a0}); }
1396  private Node[] args(Node a0, Node a1, Node a2 ) { return _args(new Node[]{null,null,a0,a1,a2,a0}); }
1397  private Node[] args(Node a0, Node a1, Node a2, Node a3) { return _args(new Node[]{null,null,a0,a1,a2,a3,a0}); }
1398  private Node[] _args(Node[] args) {
1399  //args[MEM_IDX] = gvn(new FreshNode(_e._nongen,ctrl(),mem())).keep(); // Always memory
1400  for( int i=ARG_IDX; i<args.length; i++ ) args[i].keep(); // Hook all args before reducing display
1401  args[DSP_IDX] = gvn(new FreshNode(_e._nongen,ctrl(),gvn(new FP2DispNode(args[DSP_IDX])))); // Reduce display
1402  args[CTL_IDX] = ctrl(); // Always control
1403  args[MEM_IDX] = mem(); // Always memory
1404  for( int i=ARG_IDX; i<args.length; i++ ) {
1405  args[i].unkeep();
1406  // Generally might want this in unkeep(), except for cost
1407  if( args[i]._val.is_con() ) Env.GVN.add_reduce(args[i]);
1408  }
1409  return args;
1410  }
1411 
1412  // Insert a call, with memory splits. Wiring happens later, and when a call
1413  // is wired it picks up projections to merge at the Fun & Parm nodes.
1414  private Node do_call( Parse[] bads, Node... args ) { return do_call0(true,bads,args); }
1415  private Node do_call0( boolean unpack, Parse[] bads, Node... args ) {
1416  CallNode call0 = new CallNode(unpack,bads,args);
1417  CallNode call = (CallNode)gvn(call0);
1418  // Call Epilog takes in the call which it uses to track wireable functions.
1419  // CallEpi internally tracks all wired functions.
1420 
1421  CallEpiNode cepi = (CallEpiNode)gvn(new CallEpiNode(call,Env.DEFMEM));
1422  Node ctrl = gvn(new CProjNode(cepi.keep()));
1423  if( ctrl.is_copy(0)!=null ) ctrl = ctrl.is_copy(0); // More aggressively fold, so Thunks can more aggressively assert
1424  set_ctrl(ctrl);
1425  set_mem(gvn(new MProjNode(cepi))); // Return memory from all called functions
1426  // As soon as CEPI is unkeep, a whole lotta things are allowed, including
1427  // e.g. inlining
1428  if( !cepi._is_copy ) {
1429  Env.GVN.add_work_all(cepi);
1430  for( int i = 0; i < cepi.nwired(); i++ )
1431  Env.GVN.add_inline(cepi.wired(i).fun());
1432  } else Env.GVN.add_flow(cepi);
1433  return gvn(new ProjNode(cepi.unkeep(),REZ_IDX));
1434  }
1435 
1436  // Whack current control with a syntax error
1437  private ErrNode err_ctrl1( Node.ErrMsg msg ) { return init(new ErrNode(Env.START,msg)); }
1438  private ErrNode err_ctrl2( String msg ) { return init(new ErrNode(ctrl(),errMsg(),msg)).unkeep(); }
1439  private void err_ctrl0(String s) { err_ctrl3(s,errMsg()); }
1440  private void err_ctrl3(String s, Parse open) {
1441  set_ctrl(gvn(new ErrNode(ctrl(),open,s)));
1442  }
1443 
1444  // Make a private clone just for delayed error messages
1445  private Parse( Parse P ) {
1446  _src = P._src;
1447  _buf = P._buf;
1448  _x = P._x;
1449  _lines= P._lines;
1450  _gvn = P._gvn;
1451  _lastNWS = P._lastNWS;
1452  _e = null; _nf = null; _pp = null; _str = null;
1453  }
1454  // Delayed error message, just record line/char index and share code buffer
1455  Parse errMsg() { return errMsg(_x); }
1456  Parse errMsg(int x) { Parse P = new Parse(this); P._x=x; return P; }
1457  Parse[] errMsgs(int... xs) {
1458  Parse[] Ps = new Parse[xs.length];
1459  for( int i=0; i<xs.length; i++ )
1460  Ps[i] = xs[i]==0 ? null : errMsg(xs[i]);
1461  return Ps;
1462  }
1463 
1464  // Build a string of the given message, the current line being parsed,
1465  // and line of the pointer to the current index.
1466  public String errLocMsg(String s) {
1467  if( s.charAt(0)=='\n' ) return s;
1468  // find line start
1469  int a=_x;
1470  while( a > 0 && _buf[a-1] != '\n' ) --a;
1471  if( _buf[a]=='\r' ) a++; // do not include leading \n or \n\r
1472  // find line end
1473  int b=_x;
1474  while( b < _buf.length && _buf[b] != '\n' ) b++;
1475  if( b < _buf.length ) b--; // do not include trailing \n or \n\r
1476  // Find line number. Bin-search returns the insertion-point, which is the NEXT
1477  // line unless _x is exactly a line start.
1478  int line = _lines.binary_search(_x); // Find zero-based line insertion point
1479  if( line == _lines._len || _lines.at(line)>_x ) line--;
1480  // error message using 1-based line
1481  SB sb = new SB().p(_src).p(':').p(line+1).p(':').p(s).nl();
1482  sb.p(new String(_buf,a,b-a)).nl();
1483  int line_start = a;
1484  for( int i=line_start; i<_x; i++ )
1485  sb.p(' ');
1486  return sb.p('^').nl().toString();
1487  }
1488  // Handy for the debugger to print
1489 
1490  @Override public String toString() { return new String(_buf,_x,_buf.length-_x); }
1491  @Override public boolean equals(Object loc) {
1492  if( this==loc ) return true;
1493  if( !(loc instanceof Parse) ) return false;
1494  Parse p = (Parse)loc;
1495  return _x==p._x && _src.equals(p._src);
1496  }
1497  @Override public int hashCode() {
1498  return _src.hashCode()+_x;
1499  }
1500  @Override public int compareTo(Parse loc) {
1501  int x = _src.compareTo(loc._src);
1502  if( x!=0 ) return x;
1503  return _x - loc._x;
1504  }
1505 }
com.cliffc.aa.Parse.mem
Node mem()
Definition: Parse.java:1366
com.cliffc.aa.Parse.gather_errors
TypeEnv gather_errors()
Definition: Parse.java:140
com.cliffc.aa.util.Ary.at
E at(int i)
Definition: Ary.java:25
com.cliffc.aa.Parse.typechk
Node typechk(Node x, Type t, Node mem, Parse bad)
Definition: Parse.java:1068
com.cliffc.aa.type.TypeFld.Access.Final
Final
Definition: TypeFld.java:112
com.cliffc.aa.Parse.do_call0
Node do_call0(boolean unpack, Parse[] bads, Node... args)
Definition: Parse.java:1415
com.cliffc.aa.Parse.term
Node term()
Any number field-lookups or function applications, then an optional assignment term = id++ | id– term...
Definition: Parse.java:575
com.cliffc.aa.type.TypeMemPtr.NO_DISP
static final Type NO_DISP
Definition: TypeMemPtr.java:80
com.cliffc.aa.Parse.peek_not
boolean peek_not(char c, char no)
Definition: Parse.java:1306
com.cliffc.aa.Parse.scope
ScopeNode scope()
Definition: Parse.java:1374
com.cliffc.aa.Parse.peek1
boolean peek1(byte c0, char c)
Definition: Parse.java:1286
com.cliffc.aa.Parse.remove_unknown_callers
void remove_unknown_callers()
Definition: Parse.java:120
com.cliffc.aa.type.TypeFld.make_tup
static TypeFld make_tup(Type t, int order)
Definition: TypeFld.java:65
com.cliffc.aa.type.TypeFunPtr
Definition: TypeFunPtr.java:23
com.cliffc.aa.node.ThretNode
Definition: ThretNode.java:14
com.cliffc.aa.node.PrimNode
Definition: PrimNode.java:20
com.cliffc.aa.Parse.err_ctrl0
void err_ctrl0(String s)
Definition: Parse.java:1439
com.cliffc.aa.util.Ary.push
E push(E e)
Add element in amortized constant time.
Definition: Ary.java:58
com.cliffc.aa.type.TypeTuple.make_args
static TypeTuple make_args(Type[] ts)
Definition: TypeTuple.java:106
com.cliffc.aa.Parse.skipWS
byte skipWS()
Advance parse pointer to the first non-whitespace character, and return that character,...
Definition: Parse.java:1327
com.cliffc.aa.node.NewObjNode.no_more_fields
void no_more_fields()
Definition: NewObjNode.java:48
com.cliffc.aa.util.Ary.isEmpty
boolean isEmpty()
Definition: Ary.java:20
com.cliffc.aa.type.Type.isa
boolean isa(Type t)
Definition: Type.java:623
com.cliffc.aa.node.ScopeNode.check_if
Node check_if(boolean arm, Parse bad, GVNGCM gvn, Node ctrl, Node mem)
Definition: ScopeNode.java:196
com.cliffc.aa.util.Ary.set_len
Ary< E > set_len(int len)
Definition: Ary.java:140
com.cliffc.aa.node.ScopeNode.def_if
void def_if(String name, Access mutable, boolean create)
Definition: ScopeNode.java:191
com.cliffc.aa.node.IntrinsicNode.convertTypeName
static FunPtrNode convertTypeName(TypeObj tn, Parse badargs, GVNGCM gvn)
Definition: IntrinsicNode.java:35
com.cliffc.aa.Env.XCTRL
static ConNode XCTRL
Definition: Env.java:21
com.cliffc.aa.type.TypeMem
Memory type; the state of all of memory; memory edges order memory ops.
Definition: TypeMem.java:53
com.cliffc.aa.type.TypeTuple.make_ret
static TypeTuple make_ret(Type trez)
Definition: TypeTuple.java:120
com.cliffc.aa.Parse._str
final String _str
Definition: Parse.java:80
com.cliffc.aa.util.Util.eq
static boolean eq(String s0, String s1)
Definition: Util.java:16
com.cliffc.aa.node.NewObjNode.update
void update(String tok, Access mutable, Node val)
Definition: NewObjNode.java:64
com.cliffc.aa.Parse.require
void require(char c, int oldx)
Definition: Parse.java:1270
com.cliffc.aa.type.TypeMem.XMEM
static final TypeMem XMEM
Definition: TypeMem.java:225
com.cliffc.aa.Parse.apply
Node apply()
Parse a lisp-like function application.
Definition: Parse.java:427
com.cliffc.aa.Parse.hashCode
int hashCode()
Definition: Parse.java:1497
com.cliffc.aa.GVNGCM.Mode.PesiCG
PesiCG
Definition: GVNGCM.java:18
com.cliffc.aa.Parse.expr
Node expr()
Parse an expression, a series of terms separated by binary operators.
Definition: Parse.java:459
com.cliffc.aa.node.FunNode._op_prec
final byte _op_prec
Definition: FunNode.java:65
com.cliffc.aa.Parse.err_ctrl3
void err_ctrl3(String s, Parse open)
Definition: Parse.java:1440
com.cliffc.aa.GVNGCM.add_inline
void add_inline(FunNode n)
Definition: GVNGCM.java:53
com.cliffc.aa.Parse.type
Type type()
Parse a type or return null type = tcon | tfun | tary | tstruct | ttuple | tvar // Type choices tcon ...
Definition: Parse.java:1152
com.cliffc.aa.type.Type.SCALAR
static final Type SCALAR
Definition: Type.java:328
com.cliffc
com.cliffc.aa.node.ScopeNode.early_kill
void early_kill()
Definition: ScopeNode.java:82
com.cliffc.aa.Parse.kill
void kill(Node n)
Definition: Parse.java:1360
com.cliffc.aa.type.BitsAlias.AARY
static final int AARY
Definition: BitsAlias.java:25
com.cliffc.aa.Parse.fact
Node fact()
Parse a factor, a leaf grammar token fact = num // number fact = "string" // string fact = (stmts) //...
Definition: Parse.java:772
com.cliffc.aa.Env.add_fun
Node add_fun(Parse bad, String name, Node val)
Definition: Env.java:218
com.cliffc.aa.type.TypeMemPtr.DISP_FLD
static final TypeFld DISP_FLD
Definition: TypeMemPtr.java:77
com.cliffc.aa.Parse.peek_noWS
boolean peek_noWS(char c)
Definition: Parse.java:1283
com.cliffc.aa.Parse.ctrl
Node ctrl()
Definition: Parse.java:1363
com.cliffc.aa.util.Ary.pop
E pop()
Definition: Ary.java:41
com.cliffc.aa.Parse.gvn
Node gvn(Node n)
Definition: Parse.java:1358
com.cliffc.aa.node.IfNode
Definition: IfNode.java:9
com.cliffc.aa.Parse.Parse
Parse(Parse P)
Definition: Parse.java:1445
com.cliffc.aa.type.BitsAlias.type_alias
static int type_alias(int par)
Definition: BitsAlias.java:76
com.cliffc.aa.Parse.isDigit
static boolean isDigit(byte c)
Definition: Parse.java:1355
com.cliffc.aa.type.TypeFld
Definition: TypeFld.java:12
com.cliffc.aa.node.ScopeNode
Definition: ScopeNode.java:17
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.type.TypeRPC.ALL_CALL
static final TypeRPC ALL_CALL
Definition: TypeRPC.java:31
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.node.ScopeNode.ctrl
Node ctrl()
Definition: ScopeNode.java:44
com.cliffc.aa.Env.early_exit
Node early_exit(Parse P, Node val)
Definition: Env.java:121
com.cliffc.aa.type.TypeInt
Definition: TypeInt.java:9
com.cliffc.aa.node.UnOrFunPtrNode
Definition: UnOrFunPtrNode.java:6
com.cliffc.aa.type.TypeFunPtr.GENERIC_FUNPTR
static final TypeFunPtr GENERIC_FUNPTR
Definition: TypeFunPtr.java:80
com.cliffc.aa.Parse.func
Node func()
Definition: Parse.java:897
com.cliffc.aa.Parse.isOp1
static boolean isOp1(byte c)
Definition: Parse.java:1354
com.cliffc.aa.node.FP2DispNode
Definition: FP2DispNode.java:7
com.cliffc.aa.GVNGCM.add_work_all
Node add_work_all(Node n)
Definition: GVNGCM.java:73
com.cliffc.aa.tvar
Definition: TV2.java:1
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.type.TypeFunSig.make
static TypeFunSig make(String[] args, TypeTuple formals, TypeTuple ret)
Definition: TypeFunSig.java:71
com.cliffc.aa.node.NewStrNode.ConStr
Definition: NewStrNode.java:32
com.cliffc.aa.Env.add_type
void add_type(String name, ConTypeNode t)
Definition: Env.java:234
com.cliffc.aa.type.TypeFlt
Definition: TypeFlt.java:9
com.cliffc.aa.node.StoreNode
Definition: StoreNode.java:14
com.cliffc.aa.Parse.errMsgs
Parse[] errMsgs(int... xs)
Definition: Parse.java:1457
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.node.PhiNode
Definition: PhiNode.java:9
com.cliffc.aa.node.CProjNode
Definition: CProjNode.java:10
com.cliffc.aa.Parse.args_are_mutable
static final Access args_are_mutable
Parse an anonymous function; the opening '{' already parsed.
Definition: Parse.java:896
com.cliffc.aa.type.BitsAlias
Definition: BitsAlias.java:8
com.cliffc.aa.Parse._good_prec_tok
boolean _good_prec_tok(int prec, String bintok)
Definition: Parse.java:510
com.cliffc.aa.type.Type.meet_nil
Type meet_nil(Type nil)
Definition: Type.java:904
com.cliffc.aa.Parse.skipNonWS
void skipNonWS()
Definition: Parse.java:1345
com.cliffc.aa.type.TypeTuple
Definition: TypeTuple.java:11
com.cliffc.aa.type.TypeFld.Access.RW
RW
Definition: TypeFld.java:111
com.cliffc.aa.Env.nongen_push
void nongen_push(Env par)
Definition: Env.java:255
com.cliffc.aa.node.Node.keep
public< N extends Node > N keep()
Definition: Node.java:228
com.cliffc.aa.util.Ary._len
int _len
Definition: Ary.java:13
com.cliffc.aa.Parse.tfact
Node tfact()
Parse an optionally typed factor tfact = fact[:type].
Definition: Parse.java:747
com.cliffc.aa.type.TypeInt.con
static TypeInt con(long con)
Definition: TypeInt.java:37
com.cliffc.aa.Parse.isAlpha0
static boolean isAlpha0(byte c)
Definition: Parse.java:1351
com.cliffc.aa.Env.lookup_type
ConTypeNode lookup_type(String name)
Definition: Env.java:222
com.cliffc.aa.type.TypeMem.ALLMEM
static final TypeMem ALLMEM
Definition: TypeMem.java:228
com.cliffc.aa.node.Node._val
Type _val
Definition: Node.java:88
com.cliffc.aa.node.LoadNode
Definition: LoadNode.java:13
com.cliffc.aa.node.ScopeNode.rez
Node rez()
Definition: ScopeNode.java:47
com.cliffc.aa.Parse.bfact
Node bfact(int oldx, UnOrFunPtrNode bfun)
A balanced operator as a fact().
Definition: Parse.java:1040
com.cliffc.aa.Env.XNIL
static ConNode XNIL
Definition: Env.java:22
com.cliffc.aa.Parse._x
int _x
Definition: Parse.java:72
com.cliffc.aa.type.Type.ANY
static final Type ANY
Definition: Type.java:325
com.cliffc.aa.node.Node.ErrMsg
Definition: Node.java:888
com.cliffc.aa.node.ConNode
Definition: ConNode.java:9
com.cliffc.aa.node.Node.add_def
Node add_def(Node n)
Definition: Node.java:152
com.cliffc.aa.node.ScopeNode.ptr
Node ptr()
Definition: ScopeNode.java:46
com.cliffc.aa.node.FunPtrNode
Definition: FunPtrNode.java:40
com.cliffc.aa.type.TypeAry
Definition: TypeAry.java:7
com.cliffc.aa.node.RetNode
Definition: RetNode.java:19
com.cliffc.aa.type.TypeStruct
A memory-based collection of optionally named fields.
Definition: TypeStruct.java:50
com.cliffc.aa.node.CallNode
Definition: CallNode.java:86
com.cliffc.aa.type.TypeFld.make
static TypeFld make(String fld, Type t, int order)
Definition: TypeFld.java:58
com.cliffc.aa.Parse._e
Env _e
Definition: Parse.java:70
com.cliffc.aa.Parse.set_mem
void set_mem(Node n)
Definition: Parse.java:1367
com.cliffc.aa.Parse.peek
String peek(String[] toks)
Definition: Parse.java:1313
com.cliffc.aa.Parse.typeq
Type typeq(Type t)
Definition: Parse.java:1172
com.cliffc.aa.tvar.TV2.make_leaf_ns
static TV2 make_leaf_ns(UQNodes ns, @NotNull String alloc_site)
Definition: TV2.java:130
com.cliffc.aa.node.MProjNode
Definition: MProjNode.java:10
com.cliffc.aa.Parse.args
Node[] args(Node a0, Node a1, Node a2, Node a3)
Definition: Parse.java:1397
com.cliffc.aa.Parse._expr_higher_require
Node _expr_higher_require(int prec, String bintok, Node lhs)
Definition: Parse.java:505
com.cliffc.aa.Env.START
static StartNode START
Definition: Env.java:14
com.cliffc.aa.GVNGCM.Mode.PesiNoCG
PesiNoCG
Definition: GVNGCM.java:16
com.cliffc.aa.Env.lookup
Node lookup(String name)
Definition: Env.java:186
com.cliffc.aa.Parse._src
final String _src
Definition: Parse.java:69
com.cliffc.aa.Parse.peek
boolean peek(String s)
Definition: Parse.java:1300
com.cliffc.aa.node.Node.is_prim
boolean is_prim()
Definition: Node.java:260
com.cliffc.aa.GVNGCM.xform
Node xform(Node n)
Definition: GVNGCM.java:126
com.cliffc.aa.type.BitsAlias.REC
static final int REC
Definition: BitsAlias.java:25
com.cliffc.aa.Parse.ifex
Node ifex()
Parse an if-expression, with lazy eval on the branches.
Definition: Parse.java:380
com.cliffc.aa.util.Ary.asAry
E[] asAry()
Definition: Ary.java:172
com.cliffc.aa.node.ScopeNode.flip_if
void flip_if()
Definition: ScopeNode.java:183
com.cliffc.aa.Parse._nf
final NumberFormat _nf
Definition: Parse.java:78
com.cliffc.aa.node.AssertNode
Definition: AssertNode.java:18
com.cliffc.aa.Env.GVN
static final GVNGCM GVN
Definition: Env.java:13
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.type.TypeObj.OBJ
static final TypeObj OBJ
Definition: TypeObj.java:44
com.cliffc.aa.type.TypeMemPtr.DISP_SIMPLE
static final TypeMemPtr DISP_SIMPLE
Definition: TypeMemPtr.java:105
com.cliffc.aa.type.TypeObj
Definition: TypeObj.java:15
com.cliffc.aa.type.TypeFlt.con
static Type con(double con)
Definition: TypeFlt.java:36
com.cliffc.aa.node.FunNode.fptr
FunPtrNode fptr()
Definition: FunNode.java:908
com.cliffc.aa.node.Node.unkeep
public< N extends Node > N unkeep()
Definition: Node.java:232
com.cliffc.aa.node.Node.unhook
public< N extends Node > N unhook()
Definition: Node.java:239
com.cliffc.aa.Parse.dump
String dump()
Definition: Parse.java:97
com.cliffc.aa.Parse.errMsg
Parse errMsg(int x)
Definition: Parse.java:1456
com.cliffc.aa.node.NewObjNode.get
Node get(String name)
Definition: NewObjNode.java:37
com.cliffc.aa.util.Ary.add
Ary< E > add(E e)
Add element in amortized constant time.
Definition: Ary.java:49
com.cliffc.aa.node.Node.ErrMsg.syntax
static ErrMsg syntax(Parse loc, String msg)
Definition: Node.java:900
com.cliffc.aa.node.Node.is_dead
boolean is_dead()
Definition: Node.java:820
com.cliffc.aa.Env.close_display
void close_display(GVNGCM gvn)
Definition: Env.java:128
com.cliffc.aa.Parse.dumprpo
String dumprpo()
Definition: Parse.java:98
com.cliffc.aa.node.Node.kill
Node kill()
Definition: Node.java:211
com.cliffc.aa.node.ScopeNode.mem
Node mem()
Definition: ScopeNode.java:45
com.cliffc.aa.node.DefMemNode.make_mem_proj
MrgProjNode make_mem_proj(NewNode nn, Node mem)
Definition: DefMemNode.java:59
com.cliffc.aa.Parse.err_ctrl1
ErrNode err_ctrl1(Node.ErrMsg msg)
Definition: Parse.java:1437
com.cliffc.aa.Parse.toString
String toString()
Definition: Parse.java:1490
com.cliffc.aa.node.ConTypeNode.alias
int alias()
Definition: ConTypeNode.java:28
com.cliffc.aa.node.ErrNode
Error nodes.
Definition: ErrNode.java:10
com.cliffc.aa.node.Node.dumprpo
String dumprpo(boolean prims, boolean plive)
Definition: Node.java:358
com.cliffc.aa.Parse.errMsg
Parse errMsg()
Definition: Parse.java:1455
com.cliffc.aa.type.TypeMem.FULL
static final TypeMem FULL
Definition: TypeMem.java:222
com.cliffc.aa.Parse.require
void require(String s, int oldx)
Definition: Parse.java:1276
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.node.NewStrNode
Definition: NewStrNode.java:11
com.cliffc.aa.Parse.equals
boolean equals(Object loc)
Definition: Parse.java:1491
com.cliffc.aa.util.Util
Definition: Util.java:5
com.cliffc.aa.type.Type.CTRL
static final Type CTRL
Definition: Type.java:326
com.cliffc.aa.node.Node.is_copy
Node is_copy(int idx)
Definition: Node.java:827
com.cliffc.aa.Parse.isAlpha1
static boolean isAlpha1(byte c)
Definition: Parse.java:1352
com.cliffc.aa.Parse._expr
Node _expr(int prec)
Definition: Parse.java:465
com.cliffc.aa.node.Node.ErrMsg.trailingjunk
static ErrMsg trailingjunk(Parse loc)
Definition: Node.java:941
com.cliffc.aa.Parse.errLocMsg
String errLocMsg(String s)
Definition: Parse.java:1466
com.cliffc.aa.Parse._short_circuit_expr
Node _short_circuit_expr(Node lhs, int prec, String bintok, Node op, int opx, int lhsx, int rhsx)
Definition: Parse.java:521
com.cliffc.aa.Parse.merge_exits
Node merge_exits(Node rez)
Definition: Parse.java:996
com.cliffc.aa.type.TypeObj.ISUSED
static final TypeObj ISUSED
Definition: TypeObj.java:45
com.cliffc.aa.Parse.isOp0
static boolean isOp0(byte c)
Definition: Parse.java:1353
com.cliffc.aa.node.ConTypeNode.def_fref
void def_fref(Type t, Env e)
Definition: ConTypeNode.java:31
com.cliffc.aa.node.Node.in
Node in(int i)
Definition: Node.java:126
com.cliffc.aa.node.PrimNode.PREC_TOKS
static String[][] PREC_TOKS
Definition: PrimNode.java:38
com.cliffc.aa.Parse.skipEOL
void skipEOL()
Definition: Parse.java:1342
com.cliffc.aa.node.FunNode.set_nongens
void set_nongens(TV2[] nongens)
Definition: FunNode.java:192
com.cliffc.aa.node.PrimNode.convertTypeName
static PrimNode convertTypeName(Type from, Type to, Parse badargs)
Definition: PrimNode.java:129
com.cliffc.aa.Env._nongen
VStack _nongen
Definition: Env.java:36
com.cliffc.aa.Parse.do_call
Node do_call(Parse[] bads, Node... args)
Definition: Parse.java:1414
com.cliffc.aa.type.Type.XCTRL
static final Type XCTRL
Definition: Type.java:327
com.cliffc.aa.GVNGCM
Definition: GVNGCM.java:12
com.cliffc.aa.node.CallEpiNode._is_copy
boolean _is_copy
Definition: CallEpiNode.java:25
com.cliffc.aa.util.Ary.last
E last()
Definition: Ary.java:35
com.cliffc.aa.node.ScopeNode.get
Node get(String name)
Definition: ScopeNode.java:76
com.cliffc.aa.type.TypeStruct.open
static TypeStruct open(Type tdisp)
Definition: TypeStruct.java:210
com.cliffc.aa.node.FunPtrNode.forward_ref
static FunPtrNode forward_ref(GVNGCM gvn, String name, Parse unkref, Env e)
Definition: FunPtrNode.java:205
com.cliffc.aa.Parse.stmts
Node stmts(boolean lookup_current_scope_only)
Definition: Parse.java:168
com.cliffc.aa.util.AryInt.push
AryInt push(int e)
Add element in amortized constant time.
Definition: AryInt.java:45
com.cliffc.aa.type.TypeStr
Definition: TypeStr.java:14
com.cliffc.aa.Parse.prog
void prog()
Parse a top-level: prog = stmts END.
Definition: Parse.java:157
com.cliffc.aa.node.FreshNode
Definition: FreshNode.java:11
com.cliffc.aa.node.ProjNode
Definition: ProjNode.java:11
com.cliffc.aa.node.NewObjNode.create
void create(String name, Node val, Access mutable)
Definition: NewObjNode.java:51
com.cliffc.aa.node.NewNode._ts
T _ts
Definition: NewNode.java:25
com.cliffc.aa.util.VBitSet
Definition: VBitSet.java:5
Comparable
com.cliffc.aa.Parse.compareTo
int compareTo(Parse loc)
Definition: Parse.java:1500
com.cliffc.aa.Parse._lastNWS
int _lastNWS
Definition: Parse.java:73
com.cliffc.aa.util.AryInt.binary_search
int binary_search(int e)
Definition: AryInt.java:150
com.cliffc.aa.node.NewObjNode
Definition: NewObjNode.java:20
com.cliffc.aa.node.Node.insert
Node insert(int idx, Node n)
Definition: Node.java:165
com.cliffc.aa.Parse.string
Node string()
Parse a String; _x is at '"'.
Definition: Parse.java:1123
NotNull
com.cliffc.aa.util.SB
Tight/tiny StringBuilder wrapper.
Definition: SB.java:8
com.cliffc.aa.TypeEnv
Definition: TypeEnv.java:9
com.cliffc.aa.Parse._expr_higher
Node _expr_higher(int prec, Node lhs)
Definition: Parse.java:499
com.cliffc.aa.node.Node.con
static Node con(Type t)
Definition: Node.java:670
com.cliffc.aa.node.Node._uses
Ary< Node > _uses
Definition: Node.java:245
com.cliffc.aa.node.PrimNode.PRIM_TOKS
static String[] PRIM_TOKS
Definition: PrimNode.java:39
com.cliffc.aa.node.ScopeNode.pop_if
void pop_if()
Definition: ScopeNode.java:186
com.cliffc.aa.Parse.skipBlock
void skipBlock()
Definition: Parse.java:1343
com.cliffc.aa.node.FunNode.nargs
int nargs()
Definition: FunNode.java:190
com.cliffc.aa.Parse.isOp
static boolean isOp(String s)
Definition: Parse.java:1089
com.cliffc.aa.Parse.create
void create(String tok, Node n, Access mutable)
Definition: Parse.java:1375
com.cliffc.aa.Parse.do_exit
Node do_exit(ScopeNode s, Node rez)
Definition: Parse.java:1019
com.cliffc.aa.Parse.go
TypeEnv go()
Definition: Parse.java:104
com.cliffc.aa.AA
an implementation of language AA
Definition: AA.java:9
com.cliffc.aa.node.ScopeNode.early_mem
PhiNode early_mem()
Definition: ScopeNode.java:80
com.cliffc.aa.Parse._pp
final ParsePosition _pp
Definition: Parse.java:79
com.cliffc.aa.util.AryInt.at
int at(int i)
Definition: AryInt.java:21
com.cliffc.aa.Parse.tmod
Access tmod()
Definition: Parse.java:1176
com.cliffc.aa.Parse.get_display_ptr
Node get_display_ptr(ScopeNode scope)
Definition: Parse.java:1379
com.cliffc.aa.Env._par
final Env _par
Definition: Env.java:34
com.cliffc.aa.Parse.typev
Type typev()
Definition: Parse.java:1155
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.type.TypeFld.Access.ReadOnly
ReadOnly
Definition: TypeFld.java:110
com.cliffc.aa.node.ConTypeNode
Definition: ConTypeNode.java:18
com.cliffc.aa.node.UnresolvedNode
Definition: UnresolvedNode.java:13
com.cliffc.aa.util.SB.nl
SB nl()
Definition: SB.java:48
com.cliffc.aa.node.ScopeNode.set_rez
void set_rez(Node n)
Definition: ScopeNode.java:51
com.cliffc.aa.Parse.lookup
Node lookup(String tok)
Definition: Parse.java:1372
com.cliffc.aa.Parse.set_ctrl
private< N extends Node > N set_ctrl(N n)
Definition: Parse.java:1365
com.cliffc.aa.node.NewNode
Definition: NewNode.java:17
com.cliffc.aa.node.ScopeNode.stk
NewObjNode stk()
Definition: ScopeNode.java:48
com.cliffc.aa.node.CastNode
Definition: CastNode.java:11
com.cliffc.aa.node.ScopeNode.is_mutable
boolean is_mutable(String name)
Definition: ScopeNode.java:77
com.cliffc.aa.Parse.peek2
boolean peek2(byte c0, String s2)
Definition: Parse.java:1294
com.cliffc.aa.Parse.typep
Type typep(boolean type_var)
Definition: Parse.java:1161
com.cliffc.aa.Parse.peek
boolean peek(char c)
Definition: Parse.java:1282
com.cliffc.aa.node.ScopeNode.early_ctrl
RegionNode early_ctrl()
Definition: ScopeNode.java:79
com.cliffc.aa.node.CallEpiNode.wired
RetNode wired(int x)
Definition: CallEpiNode.java:38
com.cliffc.aa.util.AryInt.last
int last()
Definition: AryInt.java:31
com.cliffc.aa.node.Node.is_forward_ref
boolean is_forward_ref()
Definition: Node.java:830
com.cliffc.aa.node.FunPtrNode._name
String _name
Definition: FunPtrNode.java:41
com.cliffc.aa.util.SB.p
SB p(String s)
Definition: SB.java:13
com.cliffc.aa.GVNGCM.gcp
void gcp(Mode mode, ScopeNode rez)
Definition: GVNGCM.java:217
com.cliffc.aa.node.CallEpiNode.nwired
int nwired()
Definition: CallEpiNode.java:37
com.cliffc.aa.node.Node.set_def
Node set_def(int idx, Node n)
Definition: Node.java:154
com.cliffc.aa.type.TypeFunSig
Definition: TypeFunSig.java:10
com.cliffc.aa.node.ThunkNode
Definition: ThunkNode.java:16
com.cliffc.aa.Parse._gvn
final GVNGCM _gvn
Definition: Parse.java:75
com.cliffc.aa.node.Node.sharptr
Type sharptr(Node mem)
Definition: Node.java:855
com.cliffc.aa.GVNGCM.add_reduce
public< N extends Node > N add_reduce(N n)
Definition: GVNGCM.java:49
com.cliffc.aa.Parse.number
Type number()
Definition: Parse.java:1098
com.cliffc.aa.Parse.field_number
int field_number()
Definition: Parse.java:1107
com.cliffc.aa.node.CallEpiNode
Definition: CallEpiNode.java:24
com.cliffc.aa.node.ParmNode
Definition: ParmNode.java:14
com.cliffc.aa.node.Node.walkerr_def
void walkerr_def(HashSet< ErrMsg > errs, VBitSet bs)
Definition: Node.java:771
com.cliffc.aa.tvar.TV2
Definition: TV2.java:23
com.cliffc.aa.node.FunNode._bal_close
String _bal_close
Definition: FunNode.java:60
com.cliffc.aa.type.TypeStruct.make
static TypeStruct make(String fld_name, Type t)
Definition: TypeStruct.java:190
com.cliffc.aa.GVNGCM.Mode.Opto
Opto
Definition: GVNGCM.java:17
com.cliffc.aa.Parse.isWS
static boolean isWS(byte c)
Return true if c passes a test.
Definition: Parse.java:1350
com.cliffc.aa.type.TypeRPC
Definition: TypeRPC.java:7
com.cliffc.aa.Parse.token0
String token0()
Definition: Parse.java:1077
com.cliffc.aa.node.NewObjNode.create_active
void create_active(String name, Node val, Access mutable)
Definition: NewObjNode.java:57
com.cliffc.aa.node.RetNode.fun
FunNode fun()
Definition: RetNode.java:32
com.cliffc.aa.GVNGCM._opt_mode
Mode _opt_mode
Definition: GVNGCM.java:22
com.cliffc.aa.Parse.con
ConNode con(Type t)
Definition: Parse.java:1369
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.Parse.inc
Node inc(String tok, int d)
Definition: Parse.java:713
com.cliffc.aa.Env._scope
final ScopeNode _scope
Definition: Env.java:35
com.cliffc.aa.GVNGCM.Build
Definition: GVNGCM.java:356
com.cliffc.aa.GVNGCM.add_flow
public< N extends Node > N add_flow(N n)
Definition: GVNGCM.java:50
com.cliffc.aa.Env.nongen_pop
Node nongen_pop(Node ret)
Definition: Env.java:254
com.cliffc.aa.node.ScopeNode.push_if
void push_if()
Definition: ScopeNode.java:178
com.cliffc.aa.GVNGCM.add_dead
void add_dead(Node n)
Definition: GVNGCM.java:48
com.cliffc.aa.Parse.init
private< N extends Node > N init(N n)
Definition: Parse.java:1359
com.cliffc.aa.node.NewNode._alias
int _alias
Definition: NewNode.java:20
com.cliffc.aa.node.Node.dump
String dump(int max)
Definition: Node.java:286
com.cliffc.aa.node.IntrinsicNode.convertTypeNameStruct
static FunPtrNode convertTypeNameStruct(TypeStruct to, int alias, Parse bad)
Definition: IntrinsicNode.java:133
com.cliffc.aa.node.IntrinsicNode
Definition: IntrinsicNode.java:15
com.cliffc.aa.GVNGCM.iter
void iter(Mode opt_mode)
Definition: GVNGCM.java:147
com.cliffc.aa.util.Ary.find
int find(E e)
Find the first matching element using ==, or -1 if none.
Definition: Ary.java:192
com.cliffc.aa.type.TypeFld.Access
Definition: TypeFld.java:109
com.cliffc.aa.node.FunPtrNode.fun
FunNode fun()
Definition: FunPtrNode.java:64
com.cliffc.aa.node.Node.tvar
TV2 tvar()
Definition: Node.java:96
com.cliffc.aa.node.ScopeNode.set_ctrl
public< N extends Node > N set_ctrl(N n)
Definition: ScopeNode.java:49
com.cliffc.aa.Parse.tuple
Node tuple(int oldx, Node s, int first_arg_start)
Parse a tuple; first stmt but not the ',' parsed.
Definition: Parse.java:843
com.cliffc.aa.node.NewObjNode.is_mutable
boolean is_mutable(String name)
Definition: NewObjNode.java:39
com.cliffc.aa.node.FunNode
Definition: FunNode.java:58
com.cliffc.aa.Env.lookup_fref
Env lookup_fref(String tok)
Definition: Env.java:311
com.cliffc.aa.node.PrimNode.as_fun
FunPtrNode as_fun(GVNGCM gvn)
Definition: PrimNode.java:178
com.cliffc.aa.node.RegionNode
Definition: RegionNode.java:11
com.cliffc.aa.Parse._buf
final byte[] _buf
Definition: Parse.java:71
com.cliffc.aa.node.Node.ErrMsg.forward_ref
static ErrMsg forward_ref(Parse loc, FunPtrNode fun)
Definition: Node.java:896
com.cliffc.aa.util.AryInt
Definition: AryInt.java:8
com.cliffc.aa.Parse.bal_open
UnOrFunPtrNode bal_open()
Definition: Parse.java:1054
com.cliffc.aa.Parse.args
Node[] args(Node a0, Node a1)
Definition: Parse.java:1395
com.cliffc.aa.Env.ANY
static ConNode ANY
Definition: Env.java:24
com.cliffc.aa.Env.VStack.add_var
String add_var(String fld, TV2 tv)
Definition: Env.java:261
com
com.cliffc.aa.Parse.err_ctrl2
ErrNode err_ctrl2(String msg)
Definition: Parse.java:1438
com.cliffc.aa.node.NewObjNode._fld_starts
Parse[] _fld_starts
Definition: NewObjNode.java:22
com.cliffc.aa.Parse.lookup_scope
ScopeNode lookup_scope(String tok, boolean lookup_current_scope_only)
Definition: Parse.java:1373
com.cliffc.aa.util.AryInt._len
int _len
Definition: AryInt.java:10
com.cliffc.aa.Parse.peek1
boolean peek1(String tok)
Definition: Parse.java:1317
com.cliffc.aa.type.TypeMem.MEM
static final TypeMem MEM
Definition: TypeMem.java:224
com.cliffc.aa.Env.DEFMEM
static DefMemNode DEFMEM
Definition: Env.java:19
com.cliffc.aa.Env.lookup_filter_fresh
UnOrFunPtrNode lookup_filter_fresh(String name, int nargs, Node ctrl)
Definition: Env.java:203
com.cliffc.aa.node.Node.op_prec
byte op_prec()
Definition: Node.java:533
com.cliffc.aa.Env
Definition: Env.java:12
com.cliffc.aa.type.BitsAlias.STR
static final int STR
Definition: BitsAlias.java:25
com.cliffc.aa.GVNGCM.Mode.Parse
Parse
Definition: GVNGCM.java:15
com.cliffc.aa.util.SB.toString
String toString()
Definition: SB.java:62
com.cliffc.aa.node.ScopeNode.set_mem
Node set_mem(Node n)
Definition: ScopeNode.java:54
com.cliffc.aa.Parse.stmt
Node stmt(boolean lookup_current_scope_only)
A statement is a list of variables to final-assign or re-assign, and an ifex for the value.
Definition: Parse.java:268
com.cliffc.aa.Env.VStack.compact
TV2[] compact()
Definition: Env.java:267
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.Parse.Parse
Parse(String src, Env env, String str)
Definition: Parse.java:82
com.cliffc.aa.GVNGCM.init
public< N extends Node > N init(N n)
Definition: GVNGCM.java:99
com.cliffc.aa.node.Node._defs
Ary< Node > _defs
Definition: Node.java:124
com.cliffc.aa.node.UnOrFunPtrNode.funptr
abstract FunPtrNode funptr()
com.cliffc.aa.node.FunNode._thunk_rhs
final boolean _thunk_rhs
Definition: FunNode.java:68
com.cliffc.aa.type.TypeMemPtr
Definition: TypeMemPtr.java:14
com.cliffc.aa.Parse
an implementation of language AA
Definition: Parse.java:68
com.cliffc.aa.Parse.args
Node[] args(Node a0, Node a1, Node a2)
Definition: Parse.java:1396
com.cliffc.aa.Env.ALL_CTRL
static ConNode ALL_CTRL
Definition: Env.java:20
com.cliffc.aa.Parse.stmts
Node stmts()
Parse a list of statements; final semi-colon is optional.
Definition: Parse.java:167
com.cliffc.aa.Parse.tstmt
Node tstmt()
A type-statement assigns a type to a type variable.
Definition: Parse.java:195
com.cliffc.aa.node
Definition: AssertNode.java:1
com.cliffc.aa.GVNGCM.Mode
Definition: GVNGCM.java:14
com.cliffc.aa.Env.lookup_scope
ScopeNode lookup_scope(String name, boolean lookup_current_scope_only)
Definition: Env.java:177
com.cliffc.aa.node.ScopeNode.replace_mem
void replace_mem(Node st)
Definition: ScopeNode.java:69
com.cliffc.aa.Parse.token
String token()
Definition: Parse.java:1072
com.cliffc.aa.Parse.type0
Type type0(boolean type_var)
Definition: Parse.java:1185
com.cliffc.aa.Parse._lines
final AryInt _lines
Definition: Parse.java:74
com.cliffc.aa.node.ScopeNode.early_val
PhiNode early_val()
Definition: ScopeNode.java:81
com.cliffc.aa.Parse._args
Node[] _args(Node[] args)
Definition: Parse.java:1398
com.cliffc.aa.type.TypeMemPtr.make
static TypeMemPtr make(BitsAlias aliases, TypeObj obj)
Definition: TypeMemPtr.java:66