Go to the documentation of this file.
7 import org.jetbrains.annotations.
NotNull;
9 import java.text.NumberFormat;
10 import java.text.ParsePosition;
78 private final NumberFormat
_nf;
79 private final ParsePosition
_pp;
85 _buf = str.getBytes();
89 _nf = NumberFormat.getInstance();
90 _nf.setGroupingUsed(
false);
91 _pp =
new ParsePosition(0);
126 for(
int i=0; i<uses.
_len; i++ ) {
147 ArrayList<
Node.
ErrMsg> errs0 =
new ArrayList<>(errs);
148 Collections.sort(errs0);
170 if(
stmt ==
null )
stmt =
stmt(lookup_current_scope_only);
171 while(
stmt !=
null ) {
175 if(
stmt ==
null )
stmt =
stmt(lookup_current_scope_only);
179 }
else if( !last.is_dead() &&
stmt != last)
kill(last);
197 String tvar =
token();
198 if( tvar ==
null || !
peek(
'=') || !
peek(
':') ) {
_x = oldx;
return null; }
199 tvar = tvar.intern();
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");
216 if( !(t instanceof
TypeObj) ) {
268 private Node stmt(
boolean lookup_current_scope_only) {
282 BitSet rs =
new BitSet();
283 boolean default_nil =
false;
289 String tok =
token();
290 if( tok ==
null )
break;
301 if(
peek(
":=") )
_x=oldx2;
302 else if(
peek(
':') && (t=
type())==
null ) {
303 if(
scope().test_if() )
_x = oldx2;
304 else err_ctrl0(
"Missing type after ':'");
309 if( lookup_current_scope_only && ts.
isEmpty() && (
peek(
';') ||
peek(
'}') ||
336 for(
int i=0; i<ts.
_len; i++ )
341 for(
int i=0; i<toks.
_len; i++ ) {
342 String tok = toks.
at(i);
382 if(
expr ==
null )
return null;
390 if( tex ==
null ) tex =
err_ctrl2(
"missing expr after '?'");
401 if( fex ==
null ) fex =
err_ctrl2(
"missing expr after ':'");
429 if(
expr ==
null )
return null;
440 if( line_last != line_now ) {
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?");
468 if( lhs==
null )
return null;
474 _x += bintok.length();
500 if( lhs !=
null ) lhs.
keep();
502 if( lhs !=
null ) lhs.
unkeep();
507 return rhs==
null ?
err_ctrl2(
"Missing term after '"+bintok+
"'") : rhs;
511 if( bintok==
null )
return false;
528 Ary<Node> old_defs = stk._defs.deepCopy();
543 for(
int i=0; i<old_defs.
_len; i++ )
544 assert old_defs.
at(i)==stk._defs.at(i);
553 if( stk.
_ts != old_ts ) {
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";
577 String uni =
token();
590 if(
term==
null ) { unifun.
unhook();
_x = oldx;
return null; }
597 String tok =
token();
600 if(
peek(
"++") && (n=
inc(tok, 1))!=
null )
return n;
601 if(
peek(
"--") && (n=
inc(tok,-1))!=
null )
return n;
607 if( n ==
null )
return null;
615 if( fldnum == -1 )
return err_ctrl2(
"Missing field name after '.'");
626 if(
stmt ==
null ) n =
err_ctrl2(
"Missing stmt after assigning field '."+fld+
"'");
634 }
else if(
peek(
'(') ) {
638 int first_arg_start =
_x;
656 n =
err_ctrl2(
"A function is being called, but "+tn+
" is not a function");
659 badargs[0] =
errMsg(oldx-1);
667 if( bfun==
null ) { n.
unkeep();
break; }
675 if( idx==
null || tok==
null ) { n.
unhook(); bfun.
unkeep();
return err_ctrl2(
"Missing stmts after '"+tok+
"'"); }
691 }
else fptr = bfun.
funptr();
694 if( fun.
nargs()==ARG_IDX+2 ) {
697 assert fun.
nargs()==ARG_IDX+3;
723 return err_ctrl2(
"Cannot re-assign final val '"+tok+
"'");
749 if(
fact==
null )
return null;
754 if( t==
null ) {
_x = oldx;
return fact; }
773 if(
skipWS() == -1 )
return null;
778 return str==
null ?
err_ctrl2(
"Unterminated string") : str;
782 int first_arg_start =
_x;
784 if( s==
null ) {
_x = oldx;
return null; }
785 if(
peek(
')') )
return s;
786 if( !
peek(
',') )
return s;
788 return tuple(oldx,s,first_arg_start);
802 if(
peek2(c,
"@{") )
return struct();
806 if( tok ==
null ) {
_x = oldx;
return null; }
809 {
_x = oldx;
return null; }
811 if(
scope ==
null ) {
815 if(
isOp(tok) ) {
_x = oldx;
return null; }
818 if( fref_env==
null ) fref_env =
_e;
827 if( def.
op_prec() > 0 ) {
_x = oldx;
return null; }
850 if( !
peek(
',') )
break;
859 for(
int i=0; i<
args._len; i++ )
877 int oldx =
_x-1;
Node ptr;
882 assert
ctrl() != e._scope;
883 ptr = e._scope.ptr().
keep();
884 e._par._scope.set_ctrl(
ctrl());
885 e._par._scope.set_mem (
mem ());
921 String tok =
token();
922 if( tok ==
null ) {
_x=oldx;
break; }
923 if(
Util.
eq((tok=tok.intern()),
"->") )
break;
924 if( !
isAlpha0((
byte)tok.charAt(0)) ) {
_x=oldx;
break; }
931 if( ids.
_len-1 <= 2 ) {
_x=oldx;
break; }
935 err_ctrl0(
peek(
',') ?
"Bad type arg, found a ',' did you mean to use a ';'?" :
"Missing or bad type arg");
956 Node clo = X.xform(
new ParmNode(DSP_IDX,
"^" ,fun,
con(tpar_disp),
null));
971 for(
int i=ARG_IDX; i<ids.
_len; i++ ) {
979 if( rez ==
null ) rez =
err_ctrl2(
"Missing function body");
983 if( e._scope.is_closure() ) rez =
merge_exits(rez);
991 return (X._ret=fptr);
1013 return (X._ret=val2);
1023 if(
ctrl ==
null ) {
1044 if( s==
null ) {
_x = oldx;
return null; }
1056 String bal =
token();
1057 if( bal==
null )
return null;
1060 if( bfun==
null || bfun.
op_prec() != 0 ) {
_x=oldx;
return null; }
1078 if(
_x >=
_buf.length )
return null;
1083 if( (c==
':' || c==
',') &&
_x-x==1 )
1084 {
_x=x;
return null; }
1085 if( c==
'-' &&
_x-x>2 &&
_buf[x+1]==
'>' )
1087 return new String(
_buf,x,
_x-x);
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;
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());
1126 while( (c=
_buf[
_x++]) !=
'"' ) {
1127 if( c==
'%' )
throw unimpl();
1128 if( c==
'\\' )
throw unimpl();
1129 if(
_x ==
_buf.length )
return null;
1131 String str =
new String(
_buf,oldx,
_x-oldx-1).intern();
1158 return t==
Type.
ANY ? null : t;
1164 if( !(t instanceof
TypeObj) )
return t;
1192 ret =
typep(type_var);
1193 if( ret ==
null )
return null;
1195 if( ts.
_len != ARG_IDX+1 )
return null;
1199 if( !
peek(
'}') )
return null;
1206 String tok =
token();
1207 if( tok ==
null )
break;
1208 final String itok = tok.intern();
1212 (t=
typep(type_var)) ==
null)
1214 if( flds.
find(fld ->
Util.
eq(fld._fld,itok) ) != -1 )
throw unimpl();
1216 if( !
peek(
';') )
break;
1230 while( (c=
skipWS()) !=
')' ) {
1233 (t=
typep(type_var)) ==
null)
1236 if( !
peek(
',') )
break;
1249 String tok =
token();
1250 if( tok==
null )
return null;
1255 if(
lookup(tok) !=
null ||
1271 if(
peek(c) )
return;
1274 err_ctrl3(
"Expected closing '"+c+
"' but "+(
_x>=
_buf.length?
"ran out of text":
"found '"+(
char)(
_buf[
_x])+
"' instead"),bad);
1277 for(
int i=0; i<s.length(); i++ )
1286 private boolean peek1(
byte c0,
char c ) {
1287 assert c0==-1 || c0==
_buf[
_x];
1288 if( c0!=c )
return false;
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;
1301 if( !
peek(s.charAt(0)) )
return false;
1302 if( !
peek_noWS(s.charAt(1)) ) {
_x--;
return false; }
1308 if( c0 != c || (
_x+1 <
_buf.length &&
_buf[
_x+1] == no) )
return false;
1313 private String
peek(String[] toks) {
1314 for( String tok : toks )
if(
peek1(tok) )
return tok;
1318 for(
int i=0; i<tok.length(); i++ )
1319 if(
_x+i >=
_buf.length ||
_buf[
_x+i] != tok.charAt(i) )
1329 while(
_x <
_buf.length ) {
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==
'_'); }
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'; }
1359 private <N extends Node> N
init( N n ) {
return n==
null ? null :
_gvn.
init(n); }
1400 for(
int i=ARG_IDX; i<
args.length; i++ )
args[i].keep();
1404 for(
int i=ARG_IDX; i<
args.length; i++ ) {
1430 for(
int i = 0; i < cepi.
nwired(); i++ )
1459 for(
int i=0; i<xs.length; i++ )
1460 Ps[i] = xs[i]==0 ?
null :
errMsg(xs[i]);
1467 if( s.charAt(0)==
'\n' )
return s;
1470 while( a > 0 &&
_buf[a-1] !=
'\n' ) --a;
1471 if(
_buf[a]==
'\r' ) a++;
1474 while( b <
_buf.length &&
_buf[b] !=
'\n' ) b++;
1475 if( b <
_buf.length ) b--;
1482 sb.
p(
new String(
_buf,a,b-a)).
nl();
1484 for(
int i=line_start; i<
_x; i++ )
1491 @Override
public boolean equals(Object loc) {
1492 if(
this==loc )
return true;
1493 if( !(loc instanceof
Parse) )
return false;
1498 return _src.hashCode()+
_x;
1502 if( x!=0 )
return x;
Node typechk(Node x, Type t, Node mem, Parse bad)
Node do_call0(boolean unpack, Parse[] bads, Node... args)
Node term()
Any number field-lookups or function applications, then an optional assignment term = id++ | id– term...
static final Type NO_DISP
boolean peek_not(char c, char no)
boolean peek1(byte c0, char c)
void remove_unknown_callers()
static TypeFld make_tup(Type t, int order)
E push(E e)
Add element in amortized constant time.
static TypeTuple make_args(Type[] ts)
byte skipWS()
Advance parse pointer to the first non-whitespace character, and return that character,...
Node check_if(boolean arm, Parse bad, GVNGCM gvn, Node ctrl, Node mem)
Ary< E > set_len(int len)
void def_if(String name, Access mutable, boolean create)
static FunPtrNode convertTypeName(TypeObj tn, Parse badargs, GVNGCM gvn)
Memory type; the state of all of memory; memory edges order memory ops.
static TypeTuple make_ret(Type trez)
static boolean eq(String s0, String s1)
void update(String tok, Access mutable, Node val)
void require(char c, int oldx)
static final TypeMem XMEM
Node apply()
Parse a lisp-like function application.
Node expr()
Parse an expression, a series of terms separated by binary operators.
void err_ctrl3(String s, Parse open)
void add_inline(FunNode n)
Type type()
Parse a type or return null type = tcon | tfun | tary | tstruct | ttuple | tvar // Type choices tcon ...
Node fact()
Parse a factor, a leaf grammar token fact = num // number fact = "string" // string fact = (stmts) //...
Node add_fun(Parse bad, String name, Node val)
static final TypeFld DISP_FLD
boolean peek_noWS(char c)
static int type_alias(int par)
static boolean isDigit(byte c)
static final TypeRPC ALL_CALL
Node early_exit(Parse P, Node val)
static final TypeFunPtr GENERIC_FUNPTR
static boolean isOp1(byte c)
Node add_work_all(Node n)
an implementation of language AA
static TypeFunSig make(String[] args, TypeTuple formals, TypeTuple ret)
void add_type(String name, ConTypeNode t)
Parse[] errMsgs(int... xs)
static final Access args_are_mutable
Parse an anonymous function; the opening '{' already parsed.
boolean _good_prec_tok(int prec, String bintok)
void nongen_push(Env par)
public< N extends Node > N keep()
Node tfact()
Parse an optionally typed factor tfact = fact[:type].
static TypeInt con(long con)
static boolean isAlpha0(byte c)
ConTypeNode lookup_type(String name)
static final TypeMem ALLMEM
Node bfact(int oldx, UnOrFunPtrNode bfun)
A balanced operator as a fact().
A memory-based collection of optionally named fields.
static TypeFld make(String fld, Type t, int order)
String peek(String[] toks)
static TV2 make_leaf_ns(UQNodes ns, @NotNull String alloc_site)
Node[] args(Node a0, Node a1, Node a2, Node a3)
Node _expr_higher_require(int prec, String bintok, Node lhs)
Node ifex()
Parse an if-expression, with lazy eval on the branches.
static final TypeInt INT64
final T set_name(String name)
static final TypeMemPtr DISP_SIMPLE
static Type con(double con)
public< N extends Node > N unkeep()
public< N extends Node > N unhook()
Ary< E > add(E e)
Add element in amortized constant time.
static ErrMsg syntax(Parse loc, String msg)
void close_display(GVNGCM gvn)
MrgProjNode make_mem_proj(NewNode nn, Node mem)
ErrNode err_ctrl1(Node.ErrMsg msg)
String dumprpo(boolean prims, boolean plive)
static final TypeMem FULL
void require(String s, int oldx)
static TypeAry make(String name, boolean any, TypeInt sz, Type elem, TypeObj stor)
boolean equals(Object loc)
static boolean isAlpha1(byte c)
static ErrMsg trailingjunk(Parse loc)
String errLocMsg(String s)
Node _short_circuit_expr(Node lhs, int prec, String bintok, Node op, int opx, int lhsx, int rhsx)
Node merge_exits(Node rez)
static final TypeObj ISUSED
static boolean isOp0(byte c)
void def_fref(Type t, Env e)
static String[][] PREC_TOKS
void set_nongens(TV2[] nongens)
static PrimNode convertTypeName(Type from, Type to, Parse badargs)
Node do_call(Parse[] bads, Node... args)
static TypeStruct open(Type tdisp)
static FunPtrNode forward_ref(GVNGCM gvn, String name, Parse unkref, Env e)
Node stmts(boolean lookup_current_scope_only)
AryInt push(int e)
Add element in amortized constant time.
void prog()
Parse a top-level: prog = stmts END.
void create(String name, Node val, Access mutable)
Node insert(int idx, Node n)
Node string()
Parse a String; _x is at '"'.
Tight/tiny StringBuilder wrapper.
Node _expr_higher(int prec, Node lhs)
static String[] PRIM_TOKS
static boolean isOp(String s)
void create(String tok, Node n, Access mutable)
Node do_exit(ScopeNode s, Node rez)
an implementation of language AA
Node get_display_ptr(ScopeNode scope)
private< N extends Node > N set_ctrl(N n)
boolean is_mutable(String name)
boolean peek2(byte c0, String s2)
Type typep(boolean type_var)
void gcp(Mode mode, ScopeNode rez)
Node set_def(int idx, Node n)
public< N extends Node > N add_reduce(N n)
void walkerr_def(HashSet< ErrMsg > errs, VBitSet bs)
static TypeStruct make(String fld_name, Type t)
static boolean isWS(byte c)
Return true if c passes a test.
void create_active(String name, Node val, Access mutable)
static final TypeMemPtr ISUSED
Node inc(String tok, int d)
public< N extends Node > N add_flow(N n)
Node nongen_pop(Node ret)
private< N extends Node > N init(N n)
static FunPtrNode convertTypeNameStruct(TypeStruct to, int alias, Parse bad)
int find(E e)
Find the first matching element using ==, or -1 if none.
public< N extends Node > N set_ctrl(N n)
Node tuple(int oldx, Node s, int first_arg_start)
Parse a tuple; first stmt but not the ',' parsed.
boolean is_mutable(String name)
Env lookup_fref(String tok)
FunPtrNode as_fun(GVNGCM gvn)
static ErrMsg forward_ref(Parse loc, FunPtrNode fun)
UnOrFunPtrNode bal_open()
Node[] args(Node a0, Node a1)
String add_var(String fld, TV2 tv)
ErrNode err_ctrl2(String msg)
ScopeNode lookup_scope(String tok, boolean lookup_current_scope_only)
boolean peek1(String tok)
UnOrFunPtrNode lookup_filter_fresh(String name, int nargs, Node ctrl)
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.
Parse(String src, Env env, String str)
public< N extends Node > N init(N n)
abstract FunPtrNode funptr()
an implementation of language AA
Node[] args(Node a0, Node a1, Node a2)
Node stmts()
Parse a list of statements; final semi-colon is optional.
Node tstmt()
A type-statement assigns a type to a type variable.
ScopeNode lookup_scope(String name, boolean lookup_current_scope_only)
void replace_mem(Node st)
Type type0(boolean type_var)
Node[] _args(Node[] args)
static TypeMemPtr make(BitsAlias aliases, TypeObj obj)