320 likes | 417 Views
Zelfgemaakt datatype voor bomen. data Tree a = Bin ( Tree a ) ( Tree a ) | Leaf a. Met functies. foldTree :: Tree a b foldTree (b,lf) ( Bin le ri) = b (foldTree (b,lf) le) (foldTree (b,lf) ri) foldTree (b,lf) ( Leaf x) = lf x.
E N D
Zelfgemaakt datatypevoor bomen dataTreea = Bin (Treea) (Treea) | Leaf a • Met functies foldTree :: Treea bfoldTree (b,lf) (Bin le ri) = b (foldTree (b,lf) le) (foldTree (b,lf) ri) foldTree (b,lf) (Leaf x) = lf x foldTree :: (bbb , ab)Treea bfoldTree (b,lf)= f wheref (Bin le ri) = b (f le) (f ri) f (Leaf x)= lf x ( , ) bbb ab
Voorbeelden van algebras dataTreea = Bin (Treea) (Treea) | Leaf a type TreeAlgebraa b = ( b b b , a b ) dataExpr = Add Expr Expr | MulExpr Expr | Con Int dataExpr = Add Expr Expr | MulExpr Expr | Con Int | Var String type ExprAlgebrab = ( b b b , b b b , Int b ) type ExprAlgebrab = ( b b b , b b b , Int b , String b )
Definitie “een algebra” • Een algebrabestaat uit • een type • functies in een tupel • Een algebrabestaat uit • een type dat het resultaat is van een fold, die • functies in een tupel neerzet in plaats van constructorfuncties • Een algebra voor een datatypebestaat uit • een type dat het resultaat is van een fold, die • functies in een tupel neerzet in plaats van constructorfuncties van dat datatype “carrier set” “semantiek” countLeafsFuns :: TreeAlgebra aInt countLeafsFuns = ( (+) , \x1 )
Algebras voor wederzijdsrecursieve datatypes dataStat a = Assign String (Expra) | Print (Expra) | Block [Stata] dataExpr a = Con a | Var String | Add (Expra) (Expra) type StatExprAlgebraase = ( ( String e s , e s , [ s ] s ) , (a e ,String e ,e e e ) ) foldStatExpr :: StatExprAlgebraas eStat a s foldStatExpr ((f1,f2,f3),(g1,g2,g3)) = f where f (Assign x e) = f1 x (g e) f (Print e) = f2 (g e) f (Block ss) = f3 (map f ss) g (Con c) = g1 c g (Var x) = g2 x g (Add e1 e2) = g3 (g e1) (g e2)
Definitie van foldExpr dataExpr = Add Expr Expr | MulExpr Expr | Con Int type ExprAlgebrab = ( b b b , b b b , Int b ) foldExpr :: ExprAlgebrabExpr b foldExpr (a,m,c) = f where f (Add e1 e2) = a (f e1) (f e2) f (Mul e1 e2) = m (f e1) (f e2) f (Con n) = c n
Gebruik van ExprAlgebra dataExpr = Add Expr Expr | MulExpr Expr | Con Int type ExprAlgebrab = ( b b b , b b b , Int b ) evalExpr :: Expr Int evalExpr = foldExpr evalExprAlgebra evalExprAlgebra :: ExprAlgebraInt evalExprAlgebra = ( (+) , (*) , id )
parseExpr evalExpr Taal: syntax en semantiek “3 + 4 * 5” = start p where p = …<|>…<*>… Add (Con 3) (Mul (Con 4) (Con 5)) = fold a where a = (…,…,…,…) 23
Compositionaliteit • Een semantiek is compositioneel als de betekenis van een geheel een functie is van de betekenissen van de delen eval (Add x y) = add (eval x) (eval y) • Een compositionele semantiekkun je schrijven als fold over de expressiewaarbij een algebra vervangingen geeftvoor de constructoren
parseExpr evalExpr compileExpr runExpr Verschillende semantieken “3 + 4 * 5” :: String Add (Con 3) (Mul (Con 4) (Con 5)) :: Expr = fold a where a = (…,…,…,…) a::ExprAlgebra Int = fold a where a = (…,…,…,…) a::ExprAlgebra Code 23 Push 3 Push 4 Push 5 Apply (*) Apply (+) :: Int :: Code
De compileer-semantiek • Wat is “machinecode” ? type Code = [ Instr ] • Wat is een “machine-instructie” ? data Instr = Push Int | Apply (IntIntInt)
Compiler:genereren van Code dataExpr = Add Expr Expr | MulExpr Expr | Con Int type ExprAlgebrab = ( b b b , b b b , Int b ) evalExpr :: Expr Int evalExpr = foldExpr evalExprAlgebra where evalExprAlgebra :: ExprAlgebraInt evalExprAlgebra = ( (+) , (*) , id ) compExpr :: Expr Code compExpr = foldExpr compExprAlgebra where compExprAlgebra :: ExprAlgebraCode compExprAlgebra = ( add , mul , con ) mul :: Code Code Code mul c1 c2 = c1 ++ c2 ++ [Apply (*)] con n = [ Push n ]
parseExpr evalExpr compileExpr runExpr Verschillende semantieken “3 + 4 * 5” :: String Add (Con 3) (Mul (Con 4) (Con 5)) :: Expr = fold a where a = (…,…,…,…) a::ExprAlgebra Int = fold a where a = (…,…,…,…) a::ExprAlgebra Code 23 Push 3 Push 4 Push 5 Apply (*) Apply (+) :: Int :: Code
Runner:simulatie van processor run :: Code Stack Stack run [ ] stack = stack run (instr:rest) stack = exec instr stack run rest ( ) exec :: Instr Stack Stack exec (Push x) stack = x : stack exec (Apply f) (y:x:stack) = f x y : stack runExpr :: Code Int runExpr prog = run prog [ ] head ( )
“3 + 4 * 5” parseExpr Add (Con 3) (Mul (Con 4) (Con 5)) evalExpr compileExpr 23 Push 3 Push 4 Push 5 Apply (*) Apply (+) runExpr Compiler correctheid runExpr (compileExpr e)= evalExpr e
dataExpr = Add Expr Expr | MulExpr Expr | Con Int | Var String type ExprAlgebrab = ( b b b , b b b , Int b , String b ) Uitrekenen vanexpressies met variabelen dataExpr = Add Expr Expr | MulExpr Expr | Con Int type ExprAlgebrab = ( b b b , b b b , Int b ) evalExpr :: Expr Int evalExpr = foldExpr eAlgebra where eAlgebra :: ExprAlgebraInt eAlgebra = ( (+) , (*) , id ) evalExpr :: EnvExpr Int evalExpr env = foldExpr eAlgebra where eAlgebra :: ExprAlgebraInt eAlgebra = ( (+) , (*) , id , ???? ) , ???? ) , (env ?) ) BAD !!!
dataExpr = Add Expr Expr | MulExpr Expr | Con Int | Var String type ExprAlgebrab = ( b b b , b b b , Int b , String b ) Uitrekenen vanexpressies met variabelen evalExpr :: Expr EnvInt evalExpr env = foldExpr eAlgebra where eAlgebra :: ExprAlgebraInt eAlgebra = ( (+) , (*) , id , (env?) ) evalExpr :: Expr (EnvInt)evalExpr = foldExpr eAlgebra where eAlgebra :: ExprAlgebraInt eAlgebra = ( add, mul, con, var ) (EnvInt) (EnvInt) evalExpr’ :: Expr Int evalExpr’ expr = evalExpr expr [ ]
dataExpr = Add Expr Expr | MulExpr Expr | Con Int | Var String dataExpr = Add Expr Expr | MulExpr Expr | Con Int | Var String | Def String Expr Expr type ExprAlgebrab = ( b b b , b b b , Int b , String b ) type ExprAlgebrab = ( b b b , b b b , Int b , String b , Stringbb b ) Uitrekenen vanexpressies met definities evalExpr :: Expr EnvInt evalExpr env = foldExpr eAlgebra where eAlgebra :: ExprAlgebra(EnvInt) eAlgebra = ( add , mul , con , var ) , def )
Env Int mul :: b b b Env Int con :: Int b Env Int var :: String b Env Int (EnvInt) (EnvInt) (EnvInt) def :: String b b b Env Int (EnvInt) (EnvInt) (EnvInt) (EnvInt) (EnvInt) (EnvInt) Uitrekenen vanexpressies met definities add :: b b b add f g e = f e + g e mul f g e = f e * g e con = const con n e = n var = flip (?) var x e = e ? x def = (<:=>) def x fd fb e = fb e ( : ) (x, ) fd e
parseExpr evalExpr compileExpr runExpr Verschillende semantieken “3 + 4 * 5” :: String Add (Con 3) (Mul (Con 4) (Con 5)) :: Expr = fold a where a = (…,…,…,…) a::ExprAlgebra Int = fold a where a = (…,…,…,…) a::ExprAlgebra Code 23 Push 3 Push 4 Push 5 Apply (*) Apply (+) :: Int :: Code
add :: b b b (EnvCode) (EnvCode) Env Code mul :: b b b (EnvCode) (EnvCode) Env Code con :: Int b Env Code var :: String b Env Code def :: String b b b (EnvCode) (EnvCode) Env Code Compileren vanexpressies met definities add f g e = f e ++ g e ++ [Apply (+)] mul f g e = f e ++ g e ++ [Apply (*)] con n e = [ Push n ] var x e = e ? x def x fd fb e = fb ( (x, fd e) : e )
Wat zit er in het Env ? • evalExpr • compExpr type Env = [ (String, Int) ] type Env = [ (String, Code) ]
“3 + 4 * 5” parseExpr Add (Con 3) (Mul (Con 4) (Con 5)) evalExpr compileExpr 23 Push 3 Push 4 Push 5 Apply (*) Apply (+) runExpr Compiler correctheidexpressies met definities hd (run (compileExpr e) s)= evalExpr e runExpr (compileExpr e env)= evalExpr e env
“let x=2+2 in 3+x*5 ” parseExpr parseExpr x compileExpr compileExpr Push 2 Push 2 Apply (+) Voorbeeld compileren van expressie “ 3+4*5 ” Push 3 Push 4 Push 5 Apply (*) Apply (+) Push 3 Push 2 Push 2 Apply (+) Push 5 Apply (*) Apply (+)
“let x=2+2 in 3+x*5 ” “let x=2+2 in 3+x*x ” parseExpr parseExpr x compileExpr compileExpr Push 2 Push 2 Apply (+) Voorbeeld compileren van expressie Push 3 Push 2 Push 2 Apply (+) Push 5 Apply (*) Apply (+) Push 3 Push 2 Push 2 Apply (+) Push 2 Push 2 Apply (+) Apply (*) Apply (+)
Aanpassing van De compileer-semantiek • Wat is “machinecode” ? type Code = [ Instr ] • Wat is een “machine-instructie” ? data Instr = Push Int | Apply (IntIntInt) data Instr = Push Int | Apply (IntIntInt) | Load Adres | Store Adres
add :: b b b (EnvCode) (EnvCode) Env Code mul :: b b b (EnvCode) (EnvCode) Env Code con :: Int b Env Code var :: String b Env Code def :: String b b b (EnvCode) (EnvCode) Env Code Efficient compileren vanexpressies met definities add f g e = f e ++ g e ++ [Apply (+)] mul f g e = f e ++ g e ++ [Apply (*)] con n e = [ Push n ] [ Load (e?x) ] var x e = e ? x where a = length e def x fd fb e = fd e ++ [Store a] ++ fb ((x,a):e) fb ( (x, fd e) : e )
Wat zit er in het Env ? • evalExpr • compExpr • efficientCompExpr type Env = [ (String, Int) ] type Env = [ (String, Code) ] type Env = [ (String, Adres) ]
Runner:simulatie van processor run :: Code Stack Stack run [ ] stack = stack run (instr:rest) stack = exec instr stack run rest ( ) exec :: Instr Stack Stack exec (Push x) stack = x : stack exec (Apply f) (y:x:stack) = f x y : stack runExpr :: Code Int runExpr prog = run prog [ ] head ( )
Runner: aangepastesimulatie van processor run :: Code (Mem,Stack) (Mem,Stack) run [ ] ms = ms run (instr:rest) ms = exec instr ms run rest ( ) exec :: Instr (Mem,Stack) (Mem,Stack) exec (Push x) (m, st) = (m, x : st ) exec (Apply f) (m, y:x:st) = (m, f x y : st ) exec (Load a) (m, st) = (m, m!a : st ) exec (Store a) (m, x: st) = (update m a x, st )
parse compile Voorbeeld Blokgestructureerde talen Enter (0,2) Access(0,0) Enter (1,2) Access (1,1) Access (0,1) Access (1,0) Leave (1,2) Access(0,1) Leave (0,2) “use x ;dcl x ;{ use z ; use y ; dcl x ; dcl z ; use x } ;dcl y ;use y ”
Definitie van Block-type, -algebra & -fold dataBlock = Cons Stat Block | Empty dataStat = Decl Naam | Use Naam | Blk Block type BlockAlgebrabs = ( ( s b b , b ) , (Naam s ,Naam s , b s ) ) foldBlock :: BlockAlgebrab sBlock b foldBlock ((c,e),(d,u,b)) = f where f (Cons (s:b)) = c (g s) (f b) f Empty = e g (Decl x) = d x g (Use x) = u x g (Blk n) = b (f n)
(GEnv LEnv(LEnv,Code)) (GEnv LEnvCode) (GEnv LEnv(LEnv,Code)) (GEnv LEnvCode) Inheritedattribuut Inheritedattribuut Inheritedattribuut Synthesizedattribuut Compileren van een Block compBlock :: Block Code compBlock = foldBlock cAlg where cAlg :: BlockAlgebra Code cAlg = ( (c,e), (d,u,b)) where c = … e = … d = … u = … b = … Env Code (EnvCode)