Go to the documentation of this file. 1 package com.cliffc.aa.HM;
5 import org.jetbrains.annotations.
NotNull;
24 static final HashMap<String,T2>
PRIMS =
new HashMap<>();
27 public static T2 hm( String sprog ) {
64 int cnt_syns = prog.
prep_tree(
null,
null,work);
65 int init_T2s =
T2.
CNT;
67 while( work.
len()>0 ) {
71 if( work.
_cnt==DEBUG_CNT )
72 System.out.println(
"break here");
94 private static byte[]
BUF;
100 if(
skipWS() != -1 )
throw unimpl(
"Junk at end of program: "+
new String(
BUF,
X,
BUF.length-
X));
104 if(
skipWS()==-1 )
return null;
141 if( fld==
null )
throw unimpl(
"Missing term for field "+
id);
155 throw unimpl(
"Unknown syntax");
158 private static String
id() {
163 if( s.length()==0 )
throw unimpl(
"Missing id");
169 sum = sum*10+
BUF[
X++]-
'0';
172 float f = (float)sum;
173 f = f + (
BUF[
X++]-
'0')/10.0f;
178 while(
X<
BUF.length &&
BUF[
X]!=
'"' )
X++;
185 private static boolean isWS (
byte c) {
return c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r'; }
186 private static boolean isDigit (
byte c) {
return '0' <= c && c <=
'9'; }
187 private static boolean isAlpha0(
byte c) {
return (
'a'<=c && c <=
'z') || (
'A'<=c && c <=
'Z') || (c==
'_') || (c==
'*') || (c==
'?'); }
188 private static boolean isAlpha1(
byte c) {
return isAlpha0(c) || (
'0'<=c && c <=
'9') || (c==
'/'); }
189 private static <T> T
require(
char c, T t) {
if(
skipWS()!=c )
throw unimpl(
"Missing '"+c+
"'");
X++;
return t; }
192 for(
int i=0; i<s.length(); i++ )
193 if(
X+i >=
BUF.length ||
BUF[
X+i]!=s.charAt(i) )
194 throw unimpl(
"Missing '"+s+
"'");
203 private final HashSet<Syntax>
_work =
new HashSet<>();
222 for(
VStack vs =
this; vs!=
null; vs = vs.
_par )
223 vs._nongen.get_dups(dups);
232 @NotNull @Override
public Iterator<T2>
iterator() {
return new Iter(); }
233 private class Iter implements Iterator<T2> {
248 return t==
_t ? t : (
_t=t);
271 boolean no_more_work = work.
has(
this) || !
hm(
null);
282 return p2(sb.
ii(1),dups).
di(1);
295 @Override
T2 lookup(String name) {
throw unimpl(
"should not reach here"); }
317 throw new RuntimeException(
"Parse error, "+
_name+
" is undefined");
320 @Override
T2 lookup(String name) {
throw unimpl(
"should not reach here"); }
332 syn.prep_lookup_deps(
this);
351 for( String arg :
_args ) sb.
p(arg).
p(
' ');
356 for( String arg :
_args ) sb.
p(arg).
p(
' ');
357 return sb.
p(
" -> ... } ");
363 boolean progress =
false;
366 for(
int i=0; i<
_targs.length; i++ )
368 { progress=
true;
break; }
376 return old.
unify(fun,work);
379 for(
int i=0; i<
_args.length; i++ )
385 for(
int i=0; i<
_targs.length; i++ )
391 for(
int i=0; i<
_targs.length; i++ )
396 for(
int i=0; i<
_args.length; i++ )
451 @Override
SB p1(
SB sb) {
return sb.
p(
"(...)"); }
466 boolean progress =
false;
468 if(
str!=
null &&
str.is_struct() &&
str._con==
null ) {
469 if( work==
null )
return true;
481 if( work==
null )
return true;
483 for(
int i=0; i<
_args.length; i++ )
487 return tfun.
unify(nfun,work);
491 throw new RuntimeException(
"Mismatched argument lengths");
493 for(
int i=0; i<
_args.length; i++ ) {
495 if( progress && work==
null )
506 for(
Syntax arg :
_args ) cnt += arg.prep_tree(
this,nongen,work);
508 if(
str!=
null )
str.push_update(
this);
515 for(
Syntax arg :
_args )
if( !arg.more_work(work) )
return false;
531 for(
int i=0; i<
_ids.length; i++ ) {
534 if( i <
_ids.length-1 ) sb.
p(
',');
538 @Override
SB p1(
SB sb) {
return sb.
p(
"@{ ... } "); }
540 for(
int i=0; i<
_ids.length; i++ )
548 for(
int i=0; i<
_ids.length; i++ ) {
552 if( old!=
null )
return false;
557 for(
int i=0; i<
_ids.length; i++ )
568 for(
int i=0; i<
_flds.length; i++ ) {
578 if( !fld.more_work(work) )
599 return str.args(idx).unify(
find(),work);
651 private T2(@NotNull String name,
Type con, String[] ids,
T2 @NotNull ...
args) {
672 if( u==
null )
return this;
673 if( u.
no_uf() )
return u;
684 return u==uu ? uu : (
_args[i]=uu);
691 if(
this==that )
return false;
692 if( work==
null )
return true;
694 if(
_deps !=
null ) {
697 if( that._deps==
null && that.is_leaf() ) that._deps =
_deps;
711 if( work==
null )
return that.
_con==
null;
715 return union(that,work);
723 static private final HashMap<Long,T2>
DUPS =
new HashMap<>();
725 if(
this==that )
return false;
726 assert
DUPS.isEmpty();
727 boolean progress =
_unify(that,work);
737 if(
this==that )
return false;
741 if(
is_leaf() )
return union(that,work);
749 throw new RuntimeException(
"Cannot unify "+
this+
" and "+that);
752 throw new RuntimeException(
"Cannot unify "+
this+
" and "+that);
757 assert rez==
null || rez==that;
758 if( rez!=
null )
return false;
761 if( work==
null )
return true;
768 for(
int i=0; i<
_ids.length; i++ ) {
775 if(
this==that )
return true;
777 for(
int i=0; i<
_args.length; i++ )
780 return union(that,work);
785 int len =
_ids.length;
797 if( con==that.
_con )
return false;
798 if( work==
null )
return true;
802 return union(that,work);
806 if( con==that.
_con )
return false;
807 if( work==
null )
return true;
818 static private final HashMap<T2,T2>
VARS =
new HashMap<>();
820 assert
VARS.isEmpty() &&
DUPS.isEmpty();
825 throw unimpl(
"busted, made T2s but just testing");
832 T2 prior =
VARS.get(
this);
850 return work==
null ||
vput(that,that.
or0(
_fresh(nongen),work));
854 throw new RuntimeException(
"Cannot unify "+
this+
" and "+that);
858 boolean progress =
false;
862 for(
int i=0; i<
_args.length; i++ ) {
864 if( progress && work==
null )
return true;
873 if(
_con!=
null && that.
_con==
null ) {
874 if( work==
null )
return true;
877 boolean progress =
false;
878 for(
int i=0; i<
_args.length; i++ ) {
881 if( work==
null )
return true;
886 if( progress && work==
null )
return true;
891 private boolean vput(
T2 that,
boolean progress) {
VARS.put(
this,that);
return progress; }
897 if( rez!=
null )
return rez;
907 for(
int i=0; i<
_args.length; i++ )
915 if( syn==
null )
return false;
917 assert
ODUPS.isEmpty();
923 assert
ODUPS.isEmpty();
929 for( ; syn!=
null; syn=syn.
_par )
937 if( x==
this )
return true;
940 for(
int i=0; i<x.
_args.length; i++ )
947 if( syn==
null )
return false;
948 assert
ODUPS.isEmpty();
954 for(
T2 t2 : nongen )
961 static private final HashMap<T2,T2>
CDUPS =
new HashMap<>();
963 assert
CDUPS.isEmpty();
970 if(
this==t )
return true;
984 for(
int i=0; i<
_args.length; i++ )
993 for(
int i=0; i<
_args.length; i++ ) {
1013 for(
int i=0; i<
_args.length; i++ )
1014 if(
_args[i]!=
null )
1024 for(
int i=0; i<
_args.length; i++ )
1039 t._get_dups(visit,dups);
1051 boolean dup = dups.get(
_uid);
1052 if( dup ) sb.
p(
"$V").
p(
_uid);
1053 if( visit.
tset(
_uid) && dup )
return sb;
1054 if( dup ) sb.
p(
':');
1059 for(
int i=0; i<
_args.length-1; i++ )
1067 for(
int i=0; i<
_ids.length; i++ )
1084 private static final HashMap<T2,Integer>
VNAMES =
new HashMap<>();
1090 Integer ii =
VNAMES.get(
this);
1094 if( later ) sb.
p(
'$');
1095 char c = (char)(
'A'+ii);
1096 if( c<
'V' ) sb.
p(c);
else sb.
p(
"V"+ii);
1097 if(
is_leaf() || later )
return sb;
1105 for(
int i=0; i<
_args.length-1; i++ )
1106 args(i).
_p(sb,visit,dups).
p(
" ");
1107 return args(
_args.length-1).
_p(sb.
p(
"-> "),visit,dups).
p(
" }");
1113 for(
int i=0; i<
_ids.length; i++ )
1122 for(
int i=0; i<
_args.length; i++ )
args(i).
_p(sb,visit,dups).
p(
" ");
SB p2(SB sb, VBitSet dups)
boolean unify_base(T2 that, Worklist work)
SB str(SB sb, VBitSet visit, VBitSet dups)
SB _p(SB sb, VBitSet visit, VBitSet dups)
abstract boolean more_work(Worklist work)
boolean _fresh_unify_struct(T2 that, VStack nongen, Worklist work)
E push(E e)
Add element in amortized constant time.
boolean occurs_in(Syntax syn)
static int find(int[] es, int e)
static boolean eq(String s0, String s1)
void add_kids(Worklist work)
boolean hm(Worklist work)
Struct(String[] ids, Syntax[] flds)
int prep_tree(Syntax par, VStack nongen, Worklist work)
boolean hm(Worklist work)
VStack(VStack par, T2 nongen)
boolean union(T2 that, Worklist work)
void add_kids(Worklist work)
boolean more_work(Worklist work)
void add_occurs(Worklist work)
void add_kids(Worklist work)
boolean fresh_base(T2 that, Worklist work)
static void require(String s)
an implementation of language AA
static T2 make_struct(String[] ids, T2[] flds)
boolean more_work(Worklist work)
abstract int prep_tree(Syntax par, VStack nongen, Worklist work)
boolean _nongen_in(VStack nongen)
void addAll(Ary<? extends Syntax > ss)
boolean _occurs_in_type(T2 x)
static TypeInt con(long con)
boolean vput(T2 that, boolean progress)
boolean more_work(Worklist work)
boolean hm(Worklist work)
static final VBitSet UPDATE_VISIT
Lambda(Syntax body, String... args)
SB p2(SB sb, VBitSet dups)
static final HashMap< T2, T2 > VARS
static final HashMap< String, T2 > PRIMS
static T2 make_fun(T2... args)
static RuntimeException unimpl()
final void prep_tree_impl(Syntax par, VStack nongen, Worklist work, T2 t)
void prep_lookup_deps(Ident id)
SB str(SB sb, VBitSet dups)
int prep_tree(Syntax par, VStack nongen, Worklist work)
boolean hm(Worklist work)
void add_occurs(Worklist work)
T2 push_update(Ary< Syntax > as)
static final TypeInt INT64
static boolean isWS(byte c)
static Type con(double con)
void prep_lookup_deps(Ident id)
T2(@NotNull String name, Type con, String[] ids, T2 @NotNull ... args)
boolean _cycle_equals_struct(T2 t)
static final HashMap< T2, T2 > CDUPS
Apply(Syntax fun, Syntax... args)
static boolean isDigit(byte c)
static T2 make_base(Type con)
SB p2(SB sb, VBitSet dups)
boolean more_work(Worklist work)
Iterator< T2 > iterator()
abstract void prep_lookup_deps(Ident id)
void add_fld(String id, T2 fld, Worklist work)
final SB p0(SB sb, VBitSet dups)
static Syntax parse(String s)
abstract void add_kids(Worklist work)
void add_kids(Worklist work)
int prep_tree(Syntax par, VStack nongen, Worklist work)
int prep_tree(Syntax par, VStack nongen, Worklist work)
abstract boolean hm(Worklist work)
Let(String arg0, Syntax def, Syntax body)
boolean _unify(T2 that, Worklist work)
void prep_lookup_deps(Ident id)
boolean nongen_in(VStack syn)
static TypeStr con(String con)
void prep_lookup_deps(Ident id)
boolean _cycle_equals(T2 t)
boolean hm(Worklist work)
static final HashMap< T2, Integer > VNAMES
void add_occurs(Worklist work)
VBitSet _get_dups(VBitSet visit, VBitSet dups)
Tight/tiny StringBuilder wrapper.
void prep_lookup_deps(Ident id)
final HashSet< Syntax > _work
an implementation of language AA
void prep_lookup_deps(Ident id)
abstract SB p2(SB sb, VBitSet dups)
int prep_tree(Syntax par, VStack nongen, Worklist work)
boolean occurs_in_type(T2 x)
void add_kids(Worklist work)
VBitSet get_dups(VBitSet dups)
void add_deps_work(Worklist work)
void push_update(Syntax a)
void add_kids(Worklist work)
boolean or0(T2 that, Worklist work)
static boolean isAlpha0(byte c)
void add_kids(Worklist work)
SB p2(SB sb, VBitSet dups)
boolean hm(Worklist work)
SB p2(SB sb, VBitSet dups)
boolean more_work(Worklist work)
void push_update_impl(Syntax a)
void add_deps_work_impl(Worklist work)
boolean fresh_unify(T2 that, VStack nongen, Worklist work)
boolean unify(T2 that, Worklist work)
boolean cycle_equals(T2 t)
boolean _occurs_in(Syntax syn)
int prep_tree(Syntax par, VStack nongen, Worklist work)
boolean _fresh_unify(T2 that, VStack nongen, Worklist work)
final boolean more_work_impl(Worklist work)
static T2 hm(String sprog)
Field(String id, Syntax str)
static final HashMap< Long, T2 > DUPS
SB p2(SB sb, VBitSet dups)
static final TypeMemPtr STRPTR
void add_occurs(Worklist work)
void add_occurs(Worklist work)
static boolean DEBUG_LEAKS
boolean more_work(Worklist work)
static final VBitSet ODUPS
int prep_tree(Syntax par, VStack nongen, Worklist work)
static SB str(SB sb, VBitSet visit, T2 t, VBitSet dups)
static boolean isAlpha1(byte c)
static final TypeInt BOOL
boolean more_work(Worklist work)
boolean hm(Worklist work)
void prep_lookup_deps(Ident id)
static T2 prim(String name, T2... args)
static final TypeFlt FLT64
abstract T2 lookup(String name)
SB p2(SB sb, VBitSet dups)
static< T > T require(char c, T t)