1
1
mirror of https://github.com/tweag/nickel.git synced 2024-09-20 16:08:14 +03:00

Fixed some reviews

Going from the `ifte` way to the different rules would be better if `typecheck`
wouldn't have two responsibilities, to typecheck and to traverse the
AST looking for `Promise()`.
This commit is contained in:
Teodoro Freund 2019-09-12 10:45:40 +02:00
parent 60c439e7fd
commit 5256d54944
3 changed files with 49 additions and 26 deletions

View File

@ -35,7 +35,7 @@ eval (ebinop E1 Op E2) V :-
eval_binop Op V1 V2 V.
eval_binop add (eint N1) (eint N2) (eint N) :- plus N1 N2 N.
eval_binop sub (eint N1) (eint N2) (eint N) :- plus N2 N N1, if (lessthan N 0 true) then (log_error _ `no negatives allowed`, failure) else success.
eval_binop sub (eint N1) (eint N2) (eint N) :- plus N2 N N1.
eval_binop mul (eint N1) (eint N2) (eint N) :- mult N1 N2 N.
eval_unop : unop -> expr -> expr -> prop.

View File

@ -1,12 +1,14 @@
print "Simple example without let" ?
print "Return 6" ?
interpreter "
(fun x => x + x) 3
" V T ?
print "Promises are check before running, assumes after" ?
print "Typecheck fail" ?
interpreter "
let ( id = fun t => t ) in
@ -15,6 +17,7 @@ Ifte( ( Promise(Bool -> Bool, id) ) true, 3, Promise(Num, true))
)
" V T ?
print "Return 3" ?
interpreter "
let ( id = fun t => t ) in
@ -23,6 +26,7 @@ Ifte( ( Promise(Bool -> Bool, id) ) true, 3, Assume(Num, true))
)
" V T ?
print "Blame" ?
interpreter "
let ( id = fun t => t ) in
@ -31,6 +35,7 @@ Ifte( ( Promise(Bool -> Bool, id) ) false, 3, Assume(Num, true))
)
" V T ?
print "Return 5" ?
interpreter "
let ( id = fun t => t ) in
@ -39,25 +44,29 @@ Ifte( ( Promise(Bool -> Bool, id) ) false, 3, Assume(Num, 5))
)
" V T ?
print " We don't have let polymorphism (any) " ?
print "Typecheck fail" ?
interpreter "
let (id = fun x => x) in
Ifte(true, Promise(Num, id 3), Promise(Bool, id true))
" V T ?
print "Return 3" ?
interpreter "
let (id = fun x => x) in
Ifte(true, Promise(Num, id 3), Assume(Bool, id true))
" V T ?
print "Return true" ?
interpreter "
let (id = fun x => x) in
Ifte(false, Promise(Num, id 3), Assume(Bool, id true))
" V T ?
print "This is bad because order matters!!" ?
print "Typecheck fail" ?
interpreter "
let (id = fun x => x) in
Ifte(true, Assume(Bool, id true), Promise(Num, id 3))
@ -65,6 +74,7 @@ Ifte(true, Assume(Bool, id true), Promise(Num, id 3))
print "We can still use Assume(...)s" ?
print "Return 3" ?
interpreter "
let (id = fun x => x) in
Ifte(true, Promise( Num , id 3), Promise( Bool, Assume( Bool -> Bool , id ) true))

View File

@ -16,27 +16,35 @@ typecheck (lam (bind _ B)) (tarrow S T) :-
).
typecheck (app A B) T :-
typecheck A ATy,
typecheck A (tarrow S T),
typecheck B S.
typecheck (app A B) tdyn :-
typecheck A (tarrow S _),
typecheck B BTy,
ifte (eq ATy (tarrow S T'))
(ifte (eq BTy S)
(eq T' T)
(eq tdyn T))
(eq tdyn T).
not (eq S BTy).
typecheck (app A B) tdyn :-
typecheck A ATy,
not (eq ATy (tarrow _ _)),
typecheck B _.
typecheck (eint _) tnum.
typecheck (ebool _) tbool.
typecheck (estr _) tstr.
typecheck (ite C T E) Ty :-
typecheck C CTy,
typecheck C tbool,
typecheck T Ty,
typecheck E Ty.
typecheck (ite C T E) tdyn :-
typecheck C tbool,
typecheck T TTy,
typecheck E ETy,
ifte (eq CTy tbool)
(ifte (eq TTy ETy)
(eq Ty TTy)
(eq Ty tdyn))
(eq Ty tdyn).
not (eq TTy ETy).
typecheck (ite C T E) tdyn :-
typecheck C CTy,
not (eq Cty tbool),
typecheck T _,
typecheck E _.
typecheck (eunop blame _) _.
@ -44,19 +52,24 @@ typecheck (eunop isNum _) tbool.
typecheck (eunop isBool _) tbool.
typecheck (eunop isFun _) tbool.
typecheck (ebinop A _ B) Ty :-
typecheck A ATy,
typecheck B BTy,
ifte (eq ATy tnum)
(ifte (eq BTy tnum)
(eq Ty tnum)
(eq Ty tdyn))
(eq Ty tdyn).
typecheck (ebinop A _ B) tnum :-
typecheck A tnum,
typecheck B tnum.
typecheck (ebinop A _ B) tdyn :-
typecheck A tnum,
typecheck B Bty,
not (eq Bty tnum).
typecheck (ebinop A _ B) tdyn :-
typecheck A Aty,
not (eq Aty tnum),
typecheck B _.
typecheck (promise Ty E) T :-
ifte (typecheck E Ty)
(eq T Ty)
(and (log_error Ty `Couldnt check Promise(...)`) failure).
typecheck (promise Ty E) Ty :-
typecheck E Ty.
typecheck (promise Ty E) _ :-
not (typecheck E Ty),
log_error Ty `Couldnt check Promise(...)`,
failure.
(* The type of an Assume construct doesn't depend on the term *)
typecheck (assume Ty _ E) Ty :-