241 lines
7.9 KiB
Racket
241 lines
7.9 KiB
Racket
#lang typed/racket/base
|
|
|
|
(provide (all-defined-out))
|
|
|
|
(require "arity-structs.rkt"
|
|
"../type-helpers.rkt")
|
|
(define-type OperandDomain (U 'number
|
|
'string
|
|
'box
|
|
'list
|
|
'pair
|
|
'caarpair
|
|
'any))
|
|
|
|
|
|
;; The following are primitives that the compiler knows about:
|
|
(define-type KernelPrimitiveName (U '+
|
|
'-
|
|
'*
|
|
'/
|
|
'add1
|
|
'sub1
|
|
'abs
|
|
'<
|
|
'<=
|
|
'=
|
|
'>
|
|
'>=
|
|
'cons
|
|
'car
|
|
'caar
|
|
'cdr
|
|
'cadr
|
|
'caddr
|
|
'list
|
|
'list?
|
|
'list*
|
|
'list->vector
|
|
'vector->list
|
|
'vector
|
|
'vector-length
|
|
'vector-ref
|
|
'vector-set!
|
|
'make-vector
|
|
'equal?
|
|
'member
|
|
'append
|
|
'reverse
|
|
'length
|
|
'pair?
|
|
'null?
|
|
'not
|
|
'eq?
|
|
'eqv?
|
|
'remainder
|
|
'display
|
|
'newline
|
|
'call/cc
|
|
'box
|
|
'unbox
|
|
'set-box!
|
|
'string-append
|
|
'current-continuation-marks
|
|
'continuation-mark-set->list
|
|
'values
|
|
'call-with-values
|
|
'apply
|
|
|
|
|
|
'for-each
|
|
'current-print
|
|
|
|
'make-struct-type
|
|
'current-inspector
|
|
'make-struct-field-accessor
|
|
'make-struct-field-mutator
|
|
|
|
'gensym
|
|
'srcloc
|
|
'make-srcloc
|
|
'srcloc-source
|
|
'srcloc-line
|
|
'srcloc-column
|
|
'srcloc-position
|
|
'srcloc-span
|
|
|
|
'error
|
|
'raise-type-error
|
|
'struct:exn:fail
|
|
'prop:exn:srclocs
|
|
|
|
'hash?
|
|
'hash-eq?
|
|
'hash-eqv?
|
|
'hash
|
|
'hasheqv
|
|
'hasheq
|
|
'make-hash
|
|
'make-hasheqv
|
|
'make-hasheq
|
|
'make-immutable-hash
|
|
'make-immutable-hasheqv
|
|
'make-immutable-hasheq
|
|
'hash-ref
|
|
'hash-has-key?
|
|
'hash-set!
|
|
'hash-set
|
|
'hash-remove!
|
|
'hash-remove
|
|
'equal-hash-code
|
|
))
|
|
(define-predicate KernelPrimitiveName? KernelPrimitiveName)
|
|
|
|
|
|
;; These are the primitives that we know how to inline.
|
|
(define-type KernelPrimitiveName/Inline (U '+
|
|
'-
|
|
'*
|
|
'/
|
|
'add1
|
|
'sub1
|
|
'<
|
|
'<=
|
|
'=
|
|
'>
|
|
'>=
|
|
'cons
|
|
'car
|
|
'caar
|
|
'cdr
|
|
'list
|
|
'list?
|
|
'pair?
|
|
'null?
|
|
'not
|
|
'eq?
|
|
))
|
|
|
|
(ensure-type-subsetof KernelPrimitiveName/Inline KernelPrimitiveName)
|
|
|
|
|
|
(define-predicate KernelPrimitiveName/Inline? KernelPrimitiveName/Inline)
|
|
|
|
(define-struct: IncorrectArity ([expected : Arity]))
|
|
|
|
|
|
(: kernel-primitive-expected-operand-types (KernelPrimitiveName/Inline Natural -> (U (Listof OperandDomain)
|
|
IncorrectArity)))
|
|
;; Given a primitive and the number of arguments, produces the list of expected domains.
|
|
;; TODO: do something more polymorphic.
|
|
(define (kernel-primitive-expected-operand-types prim arity)
|
|
(cond
|
|
[(eq? prim '+)
|
|
(build-list arity (lambda (i) 'number))]
|
|
|
|
[(eq? prim '-)
|
|
(cond [(> arity 0)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 1))])]
|
|
|
|
[(eq? prim '*)
|
|
(build-list arity (lambda (i) 'number))]
|
|
|
|
[(eq? prim '/)
|
|
(cond [(> arity 0)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 1))])]
|
|
|
|
[(eq? prim 'add1)
|
|
(cond [(= arity 1)
|
|
(list 'number)]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 1))])]
|
|
|
|
[(eq? prim 'sub1)
|
|
(cond [(= arity 1)
|
|
(list 'number)]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 1))])]
|
|
|
|
[(eq? prim '<)
|
|
(cond [(>= arity 2)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 2))])]
|
|
|
|
[(eq? prim '<=)
|
|
(cond [(>= arity 2)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 2))])]
|
|
|
|
[(eq? prim '=)
|
|
(cond [(>= arity 2)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 2))])]
|
|
|
|
[(eq? prim '>)
|
|
(cond [(>= arity 2)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 2))])]
|
|
|
|
[(eq? prim '>=)
|
|
(cond [(>= arity 2)
|
|
(build-list arity (lambda (i) 'number))]
|
|
[else
|
|
(make-IncorrectArity (make-ArityAtLeast 2))])]
|
|
|
|
[(eq? prim 'cons)
|
|
(list 'any 'any)]
|
|
|
|
[(eq? prim 'car)
|
|
(list 'pair)]
|
|
|
|
[(eq? prim 'caar)
|
|
(list 'caarpair)]
|
|
|
|
[(eq? prim 'cdr)
|
|
(list 'pair)]
|
|
|
|
[(eq? prim 'list)
|
|
(build-list arity (lambda (i) 'any))]
|
|
|
|
[(eq? prim 'list?)
|
|
(list 'any)]
|
|
|
|
[(eq? prim 'pair?)
|
|
(list 'any)]
|
|
|
|
[(eq? prim 'null?)
|
|
(list 'any)]
|
|
|
|
[(eq? prim 'not)
|
|
(list 'any)]
|
|
|
|
[(eq? prim 'eq?)
|
|
(list 'any 'any)])) |