core-in-racket/semantics.rkt

104 lines
3 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang typed/racket
(require "ast.rkt")
(: prelude CoreProgram)
(define prelude
'((define (I x) x) (define (K x y) x) (define (K1 x y) y) (define (S f g x) ((f x) (g x))) (define (compose f g x) (f (g x))) (define (twice f) ((compose f) f))))
(struct State ([stack : Stack] [dump : Dump] [heap : Heap] [globals : Globals] [stats : Stats]))
(define-type Addr Symbol)
(define-type Stack (Listof Addr))
(define-type Dump Null)
(define-type Heap (Immutable-HashTable Addr Node))
(define-type Node ( (List Addr Addr) CoreScDefn Integer))
(define-type Globals (Immutable-HashTable Name Addr))
(define-type Stats Nonnegative-Integer)
(: empty-heap Heap)
(define empty-heap
(make-immutable-hash))
(: empty-globals Globals)
(define empty-globals
(make-immutable-hash))
(: new-addr (-> Addr))
(define (new-addr)
(gensym))
(: empty-dump Dump)
(define empty-dump '())
(: empty-stats Stats)
(define empty-stats 0)
(: empty-stack Stack)
(define empty-stack '())
(: incr-stats (-> Stats Stats))
(define incr-stats add1)
(: update-globals (-> Globals Name Addr Globals))
(define (update-globals globals name addr)
(hash-set globals name addr))
(: update-stats (-> (-> Stats Stats) State State))
(define (update-stats f mstate)
(struct-copy State mstate [stats (f (State-stats mstate))]))
(: update-stack (-> (-> Stack Stack) State State))
(define (update-stack f mstate)
(struct-copy State mstate [stack (f (State-stack mstate))]))
(: allocate-node (-> Heap Node (Values Heap Addr)))
(define (allocate-node heap node)
(let ([addr (new-addr)])
(values (hash-set heap addr node) addr)))
(: lookup-node (-> Heap Addr Node))
(define lookup-node hash-ref)
(: initialize-heap (-> (Listof CoreScDefn) (Values Heap Globals)))
(define (initialize-heap scs)
(for/fold ([heap : Heap empty-heap]
[globals : Globals empty-globals])
([sc : CoreScDefn scs])
(let-values ([(new-heap addr) (allocate-node heap sc)])
(values new-heap
(update-globals globals (scdefn-name sc) addr)))))
(: compile-core (-> (Listof CoreScDefn) State))
(define (compile-core scdefs)
(let-values ([(heap globals) (initialize-heap (append scdefs prelude))])
(State empty-stack empty-dump heap globals empty-stats)))
(: data-node? (-> Node Boolean))
(define data-node? integer?)
(: final-state? (-> State Boolean))
(define (final-state? st)
(match (State-stack st)
[(list n) (data-node? (lookup-node (State-heap st) n))]
[_ #f]))
(: step (-> State State))
(define (step state)
(let ([stack (State-stack state)])
(match stack
[(cons addr _)
(step-node state (lookup-node (State-heap state) addr))]
['() (error "Invalid state")])))
(: step-node (-> State Node State))
(define (step-node st n)
(match n
[(? integer?) (error "A number cannot be stepped any further!")]
[(list a _) (update-stack (λ (x) (cons a x)) st)]
[(list 'define (list name args ...) body)
(step-sc st name args body)]))
(: step-sc (-> State Name (Listof Name) CoreExpr State))
(define (step-sc state sc args body)
(error "to be implemented"))