Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Haskell compiler

Haskell compiler

Haskell compiler
Institute of Computer Science, University of Wrocław
Seminar: Implementing compilers of functional languages
28.01.2016

Rafał Łasocha

January 28, 2016
Tweet

More Decks by Rafał Łasocha

Other Decks in Programming

Transcript

  1. Spineless Tagless G-Machine Rewriting rules {−# RULES ”map/map” forall f

    g xs. map f (map g xs) = map (f.g) xs ”map/append” forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys #−} Rafal Lasocha Haskell compiler
  2. Spineless Tagless G-Machine Operational semantics map f [] = []

    map f (y:ys) = (f y) : (map f ys) map = {} \n {f,xs} -> case xs of Nil {} -> Nil {} Cons {y,ys} -> let fy = {f,y} \u {} -> f {y} mfy = {f,ys} \u {} -> map {f,ys} in Cons {fy,mfy} Lambda form: free vars X args -> expression Rafal Lasocha Haskell compiler
  3. Spineless Tagless G-Machine Operational semantics constructors are always saturated no

    types on the RHS of let(rec) there are only lambda forms only thing which may force us to evaluate, is case expression Rafal Lasocha Haskell compiler
  4. Spineless Tagless G-Machine Operational semantics Updateable flag: boolean, either ”u”

    (updatable) or ”n” (not updatable) Our language is lazy, so after evaluation of suspended computation, we should update something, to not evaluate the same code again but maybe already during compilation we can deduce, that we won’t have to update some closures? functions with non-empty argument list - they don’t need updating partial applications - the same ( vs \n {} -> f {x1, ..., xm} ) saturated constructor - the same thunks - these are rather updatable Rafal Lasocha Haskell compiler
  5. Spineless Tagless G-Machine Operational semantics few stacks: argument stack, return

    stack, update stack, heap, global environment value, on the argument stack are either heap addresses or primitive integers 4 possible states of compiler Eval e p - evaluate expression e in environemnt p Enter a - apply the closure at address a to the arguments on the argument stack ReturnCon c ws - Return the constructor c applied to values ws to the continuation on the return stack ReturnInt k - Return the primitive integer k to the continuation on the return stack Rafal Lasocha Haskell compiler
  6. Spineless Tagless G-Machine Operational semantics Function application Eval e p

    - evaluate expression e in environment p Rafal Lasocha Haskell compiler
  7. Spineless Tagless G-Machine Operational semantics Enter non-updatable closure Enter a

    - apply the closure at address a to the arguments on the argument stack Rafal Lasocha Haskell compiler
  8. Spineless Tagless G-Machine Operational semantics Evaluate case statement ReturnCon c

    ws - Return the constructor c applied to values ws to the continuation on the return stack Rafal Lasocha Haskell compiler
  9. Spineless Tagless G-Machine Operational semantics Applying updatable closures assuming a

    is an address of the updatable closure we try to Enter (Enter a) clean argument and return stacks, and save triple (”update frame”) (as, rs, a) to the update frames stack now just evaluate and wait until our program ”crash” because lack of values in either return stack or argument stack Rafal Lasocha Haskell compiler
  10. Spineless Tagless G-Machine Operational semantics Generating code target language will

    be C it’s not perfect, it’s not very efficient, but it works mapping haskell functions to C functions doesn’t work each closure becomes C function, but without arguments stacks will be managed by us but subsequently entering functions will cause our stack to grow... while (TRUE) { cont = (*cont)(); } Rafal Lasocha Haskell compiler
  11. Spineless Tagless G-Machine Operational semantics Garbage collection two space GC

    evacuating code handles moving specific closure from 1st space to 2nd it also overrides in 1st space with forwarding pointer ... and returns new closure address to the caller scavenging code knows how to iterate evacuating code on each pointer in closure it also replace old pointers with new ones forwarding pointers - simple return of associated pointer Rafal Lasocha Haskell compiler
  12. Spineless Tagless G-Machine Operational semantics Something about translating to C

    STG has two stack pointers - one for integers, and one for pointers. # apply3 = {} \n {f,x} -> f {x,x,x} Node = SpA[0] t = SpA[1] SpA[0] = t SpA[-1] = t SpA = SpA - 1 ENTER( Node ) # Node is a closure, not code ptr Rafal Lasocha Haskell compiler