whalesong/typed-structs.rkt

166 lines
5.9 KiB
Racket

#lang typed/racket/base
(provide (all-defined-out))
;; Expressions
(define-type ExpressionCore (U Constant Quote Var Branch Def Lam Seq App))
(define-type Expression (U ExpressionCore Assign))
(define-struct: Constant ([v : Any]) #:transparent)
(define-struct: Quote ([text : Any]) #:transparent)
(define-struct: Var ([id : Symbol]) #:transparent)
(define-struct: Assign ([variable : Symbol]
[value : Expression]) #:transparent)
(define-struct: Branch ([predicate : Expression]
[consequent : Expression]
[alternative : Expression]) #:transparent)
(define-struct: Def ([variable : Symbol]
[value : Expression]) #:transparent)
(define-struct: Lam ([parameters : (Listof Symbol)]
[body : (Listof Expression)]) #:transparent)
(define-struct: Seq ([actions : (Listof Expression)]) #:transparent)
(define-struct: App ([operator : Expression]
[operands : (Listof Expression)]) #:transparent)
(: last-exp? ((Listof Expression) -> Boolean))
(define (last-exp? seq)
(null? (cdr seq)))
(: first-exp ((Listof Expression) -> Expression))
(define (first-exp seq) (car seq))
(: rest-exps ((Listof Expression) -> (Listof Expression)))
(define (rest-exps seq) (cdr seq))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; instruction sequences
(define-type UnlabeledStatement (U
AssignImmediateStatement
AssignPrimOpStatement
PerformStatement
TestStatement
BranchLabelStatement
GotoStatement
SaveStatement
RestoreStatement))
(define-type Statement (U UnlabeledStatement
Symbol ;; label
))
(define-struct: AssignImmediateStatement ([target : Symbol]
[value : (U Const Reg Label)])
#:transparent)
(define-struct: AssignPrimOpStatement ([target : Symbol]
[op : PrimitiveOperator]
[rands : (Listof (U Label Reg Const))])
#:transparent)
(define-struct: PerformStatement ([op : PerformOperator]
[rands : (Listof (U Label Reg Const))]) #:transparent)
(define-struct: TestStatement ([op : TestOperator]
[register-rand : Symbol]) #:transparent)
(define-struct: BranchLabelStatement ([label : Symbol]) #:transparent)
(define-struct: GotoStatement ([target : (U Label Reg)]) #:transparent)
(define-struct: SaveStatement ([reg : Symbol]) #:transparent)
(define-struct: RestoreStatement ([reg : Symbol]) #:transparent)
(define-struct: Label ([name : Symbol])
#:transparent)
(define-struct: Reg ([name : Symbol])
#:transparent)
(define-struct: Const ([const : Any])
#:transparent)
(define-type OpArg (U Const Label Reg))
(define-type PrimitiveOperator (U 'compiled-procedure-entry
'compiled-procedure-env
'make-compiled-procedure
'false?
'cons
'list
'apply-primitive-procedure
'lexical-address-lookup
'toplevel-lookup
'extend-environment
'extend-environment/prefix))
(define-type TestOperator (U 'false? 'primitive-procedure?))
(define-type PerformOperator (U 'toplevel-set!
'lexical-address-set!
'check-bound!))
(define-type InstructionSequence (U Symbol instruction-sequence))
(define-struct: instruction-sequence ([needs : (Listof Symbol)]
[modifies : (Listof Symbol)]
[statements : (Listof Statement)]) #:transparent)
(define empty-instruction-sequence (make-instruction-sequence '() '() '()))
(: make-label (Symbol -> Symbol))
(define make-label
(let ([n 0])
(lambda (l)
(set! n (add1 n))
(string->symbol (format "~a~a" l n)))))
(: registers-needed (InstructionSequence -> (Listof Symbol)))
(define (registers-needed s)
(if (symbol? s) '() (instruction-sequence-needs s)))
(: registers-modified (InstructionSequence -> (Listof Symbol)))
(define (registers-modified s)
(if (symbol? s) '() (instruction-sequence-modifies s)))
(: statements (InstructionSequence -> (Listof Statement)))
(define (statements s)
(if (symbol? s) (list s) (instruction-sequence-statements s)))
;; Targets
(define-type Target Symbol)
;; Linkage
(define-type Linkage (U 'return 'next Symbol))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Assembly
(define-struct: BasicBlock ([name : Symbol]
[stmts : (Listof UnlabeledStatement)]) #:transparent)
;;;;;;;;;;;;;;
;; Lexical environments
;; A toplevel prefix contains a list of toplevel variables.
(define-struct: Prefix ([names : (Listof Symbol)])
#:transparent)
;; A compile-time environment is a (listof (listof symbol)).
;; A lexical address is either a 2-tuple (depth pos), or 'not-found.
(define-type CompileTimeEnvironment (Listof (U (Listof Symbol)
Prefix)))
(define-type LexicalAddress (U LocalAddress PrefixAddress))
(define-struct: LocalAddress ([depth : Natural]
[pos : Natural])
#:transparent)
(define-struct: PrefixAddress ([depth : Natural]
[pos : Natural]
[name : Symbol])
#:transparent)