diff options
Diffstat (limited to 'fp2')
| -rw-r--r-- | fp2/week45/camil/RefactorX.dcl | 18 | ||||
| -rw-r--r-- | fp2/week45/camil/RefactorX.icl | 82 | 
2 files changed, 100 insertions, 0 deletions
| diff --git a/fp2/week45/camil/RefactorX.dcl b/fp2/week45/camil/RefactorX.dcl new file mode 100644 index 0000000..3ddc8a4 --- /dev/null +++ b/fp2/week45/camil/RefactorX.dcl @@ -0,0 +1,18 @@ +definition module RefactorX
 +
 +import StdEnv
 +
 +::	Expr			= NR   Int
 +					| VAR  Name
 +					| OP   Expr Operator Expr
 +					| LET  Name     Expr Expr
 +::	Name		  :== String
 +::	Operator		= PLUS | MIN | MUL | DIV
 +::	Val				= Result Int | Undef
 +
 +from StdClass import class toString
 +
 +instance toString Expr
 +free				:: Expr -> [Name]
 +remove_unused_lets	:: Expr -> Expr
 +eval				:: Expr -> Val
 diff --git a/fp2/week45/camil/RefactorX.icl b/fp2/week45/camil/RefactorX.icl new file mode 100644 index 0000000..3f273e0 --- /dev/null +++ b/fp2/week45/camil/RefactorX.icl @@ -0,0 +1,82 @@ +implementation module RefactorX
 +
 +import StdEnv
 +
 +Start = map eval [E1,E2,E3,E4,E5]
 +
 +E1 = OP (LET "x" (OP (NR 42) MIN (NR 3)) (OP (VAR "x") DIV (NR 0)))
 +	PLUS
 +	(LET "y" (NR 6) (OP (VAR "y") MUL (VAR "y")))
 +E2 = LET "x" (NR 42) (OP (VAR "x") PLUS (LET "x" (NR 58) (VAR "x")))
 +E3 = LET "x" (NR 1) (LET "y" (NR 2) (LET "x" (NR 3) (NR 4)))
 +E4 = LET "x" (NR 1) (OP (VAR "x") PLUS (VAR "y"))
 +E5 = OP (LET "x" (NR 1) (VAR "x")) MUL (VAR "x")
 +
 +::	Expr							= NR   Int
 +									| VAR  Name
 +									| OP   Expr Operator Expr
 +									| LET  Name     Expr Expr
 +::	Name							:== String
 +::	Operator						= PLUS | MIN | MUL | DIV
 +::	Val								= Result Int | Undef
 +
 +(<+) infixl 9 :: String a -> String | toString a
 +(<+) str a = str +++ toString a
 +
 +instance toString Operator where
 +	toString PLUS = "+"
 +	toString MIN = "-"
 +	toString MUL = "*"
 +	toString DIV = "/"
 +
 +//  expressies afdrukken:
 +instance toString Expr where
 +	toString (NR n) = toString n
 +	toString (VAR s) = s
 +	toString (LET s e1 e2) = "let " <+ s <+ " = " <+ e1 <+ " in " <+ e2
 +	toString (OP e1 o e2) = bracket e1 <+ o <+ bracket e2
 +	where
 +		bracket :: Expr -> String
 +		bracket (OP e1 o e2) = "(" <+ e1 <+ o <+ e2 <+ ")"
 +		bracket (LET s e1 e2) = "(" <+ (LET s e1 e2) <+ ")"
 +		bracket x = toString x
 +
 +//	vrije variabelen:
 +free								:: Expr -> [Name]
 +free (NR _) = []
 +free (VAR s) = [s]
 +free (LET s _ e2) = [n \\ n <- free e2 | n <> s]
 +free (OP e1 _ e2) = (free e1) ++ (free e2)
 +
 +//	verwijder deelexpressies met ongebruikte let-variabelen:
 +remove_unused_lets					:: Expr -> Expr
 +remove_unused_lets (LET s e1 e2)
 +| isMember s (free e2) = (LET s (remove_unused_lets e1) (remove_unused_lets e2))
 +| otherwise = remove_unused_lets e2
 +remove_unused_lets (OP e1 o e2) = OP (remove_unused_lets e1) o (remove_unused_lets e2)
 +remove_unused_lets x = x
 +
 +//	evaluator met tabel van naam-waarde paren:
 +eval								:: Expr -> Val
 +eval e = fst (eval` e [])
 +where
 +	eval` :: Expr [(Name, Val)] -> (Val, [(Name, Val)])
 +	eval` (NR n) vs = (Result n, [])
 +	eval` (VAR s) vs = (find s vs, [])
 +	where
 +		find :: Name [(Name, Val)] -> Val
 +		find _ [] = Undef
 +		find s [(t,v):vs]
 +		| s == t = v
 +		| otherwise = find s vs
 +	eval` (LET s e1 e2) vs = eval` e2 [(s,fst (eval` e1 vs)):vs]
 +	eval` (OP e1 o e2) vs = (op o (fst (eval` e1 vs)) (fst (eval` e2 vs)), [])
 +	where
 +		op :: Operator Val Val -> Val
 +		op _ Undef _ = Undef
 +		op _ _ Undef = Undef
 +		op PLUS (Result x) (Result y) = Result (x + y)
 +		op MIN (Result x) (Result y) = Result (x - y)
 +		op MUL (Result x) (Result y) = Result (x * y)
 +		op DIV _ (Result 0) = Undef
 +		op DIV (Result x) (Result y) = Result (x / y)
 | 
