Skip to content

Commit

Permalink
adds simple pattern matching & some binary perators
Browse files Browse the repository at this point in the history
  • Loading branch information
nachivpn committed Mar 14, 2018
1 parent 6d9000f commit 776efa3
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 30 deletions.
36 changes: 21 additions & 15 deletions etc/src/etc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,9 @@ infer (Env,Node) ->
clause ->
ClausePatterns = clause_patterns(Node),
L = element(2,Node),
% Type assumption for every argument
EnvEntries = lists:map(
fun(Pattern) ->
case Pattern of
{var, L, X} -> {X,hm:fresh(L)}
end
end, ClausePatterns),
Env_ = lists:foldr(
fun({X,T}, AccEnv) -> env:extend(X,T,AccEnv) end, Env, EnvEntries),
% Infer types of arguments (which are in the form of patterns)
% Env_ is Env extended with arg variables
{ArgTypes, Env_, CsArgs, PsArgs} = inferPatterns(Env,ClausePatterns),
% ClauseGaurds = clause_guard(Node),
Body = clause_body(Node),
{Env__, CsBody, PsBody} =lists:foldl(
Expand All @@ -108,11 +102,9 @@ infer (Env,Node) ->
{Ei_, Csi ++ Csi_, Psi ++ Psi_}
end, {Env_,[],[]}, lists:droplast(Body)),
{ReturnType, CsLast, PsLast} = infer(Env__, lists:last(Body)),
{hm:funt(
lists:map (fun ({_,Typ}) -> Typ end, EnvEntries)
, ReturnType,L)
, CsBody ++ CsLast
, PsBody ++ PsLast};
{hm:funt(ArgTypes,ReturnType,L)
, CsArgs ++ CsBody ++ CsLast
, PsArgs ++ PsBody ++ PsLast};
variable ->
{var, L, X} = Node,
{T, Ps} = lookup(X, Env, L),
Expand Down Expand Up @@ -161,7 +153,21 @@ checkExpr(Env,ExprNode) ->
{_,Constraints,Ps} = infer(Env, ExprNode),
{Env,Constraints,Ps}.


-spec inferPatterns(hm:env(),[erl_syntax:syntaxTree()]) -> {[hm:types()],hm:env(),[hm:constraint()],[hm:predicate()]}.
inferPatterns(Env,ClausePatterns) ->
lists:foldr(
fun(Pattern,{AccTs,AccEnv,AccCs,AccPs}) ->
case Pattern of
{var, L, X} ->
FreshT = hm:fresh(L),
AccEnv_ = env:extend(X,FreshT,AccEnv),
{[FreshT | AccTs], AccEnv_, AccCs, AccPs};
_ ->
%empty env is used for inference because?
{InfT, InfCs, InfPs} = infer(env:empty(),Pattern),
{[InfT | AccTs], AccEnv, InfCs ++ AccCs, InfPs ++ AccPs}
end
end, {[],Env,[],[]} ,ClausePatterns).
%%%%%%%%%%%%%%%%%% Utilities

% "pseudo unify" which returns constraints
Expand Down
10 changes: 9 additions & 1 deletion etc/src/rt.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,13 @@ defaultEnv() ->
{'or', hm:funt([hm:bt(boolean,-1),hm:bt(boolean,-2)],hm:bt(boolean,0),0)},
{'xor', hm:funt([hm:bt(boolean,-1),hm:bt(boolean,-2)],hm:bt(boolean,0),0)},
{'orelse', hm:funt([hm:bt(boolean,-1),hm:bt(boolean,-2)],hm:bt(boolean,0),0)},
{'andalso', hm:funt([hm:bt(boolean,-1),hm:bt(boolean,-2)],hm:bt(boolean,0),0)}
{'andalso', hm:funt([hm:bt(boolean,-1),hm:bt(boolean,-2)],hm:bt(boolean,0),0)},
{'==', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'/=', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'=<', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'<', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'>=', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'>', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'=:=', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)},
{'=/=', hm:funt([hm:tvar(a,-1),hm:tvar(b,-2)],hm:bt(boolean,0),0)}
]).
10 changes: 5 additions & 5 deletions test/good/g2.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
% Simple (straight forward) boolean expressions
% benot(X) -> not X.

% beand (X,Y) -> X and Y.
beand (X,Y) -> X and Y.

% beor (X,Y) -> X or Y.
beor (X,Y) -> X or Y.

% bexor (X,Y) -> X xor Y.
bexor (X,Y) -> X xor Y.

% beorelse (X,Y) -> X orelse Y.
beorelse (X,Y) -> X orelse Y.

% beandalso (X,Y) -> X andalso Y.
beandalso (X,Y) -> X andalso Y.



26 changes: 18 additions & 8 deletions test/good/g3.erl
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
-module(g3).
-compile({parse_transform, etc}).

% ceq(X,Y) -> X == Y.
ceq(X,Y) -> X == Y.

% cne(X,Y) -> X /= Y.
cne(X,Y) -> X /= Y.

% clte(X,Y) -> X =< Y.
clte(X,Y) -> X =< Y.

% clt(X,Y) -> X < Y.
clt(X,Y) -> X < Y.

% cgte(X,Y) -> X >= Y.
cgte(X,Y) -> X >= Y.

% cgt (X,Y) -> X > Y.
cgt (X,Y) -> X > Y.

% cee (X,Y) -> X =:= Y.
cee (X,Y) -> X =:= Y.

% cene (X,Y) -> X =/= Y.
cene (X,Y) -> X =/= Y.

foo1() -> "hello" == "world".

foo2() -> "hello" =:= 1.

foo3() -> 1.0 =/= 1.

foo5() ->
X = 1 div 5,
X >= 5.0.
9 changes: 8 additions & 1 deletion test/good/g5.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ foo1() -> foo1().

foo2() -> foo1().

foo(X,Y) -> foo(X,X) + foo(Y,Y).
fib(0) -> 0;
fib(1) -> 1;
fib(N) -> fib(N-1) + fib(N-2).

fac(0) -> 1;
fac(N) -> N * fac(N-1).


14 changes: 14 additions & 0 deletions test/good/g7.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-module(g7).
-compile({parse_transform, etc}).

% simple mutually recursive functions

foo() -> ind(), bar().
bar() -> foo().
ind() -> 3.


even(N) -> (N == 0) or odd(N - 1).

odd(N) -> (N > 0) and even(N - 1).

0 comments on commit 776efa3

Please sign in to comment.