adding kernel primitive as opargs.
This commit is contained in:
parent
4be57c1e37
commit
39935eaee3
|
@ -51,7 +51,9 @@
|
||||||
[(CompiledProcedureEntry? v)
|
[(CompiledProcedureEntry? v)
|
||||||
(assemble-compiled-procedure-entry v)]
|
(assemble-compiled-procedure-entry v)]
|
||||||
[(CompiledProcedureClosureReference? v)
|
[(CompiledProcedureClosureReference? v)
|
||||||
(assemble-compiled-procedure-closure-reference v)]))
|
(assemble-compiled-procedure-closure-reference v)]
|
||||||
|
[(PrimitiveKernelValue? v)
|
||||||
|
(assemble-primitive-kernel-value v)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,3 +262,6 @@
|
||||||
(assemble-label a-location)]))
|
(assemble-label a-location)]))
|
||||||
|
|
||||||
|
|
||||||
|
(: assemble-primitive-kernel-value (PrimitiveKernelValue -> String))
|
||||||
|
(define (assemble-primitive-kernel-value a-prim)
|
||||||
|
(format "MACHINE.primitives[~s]" (symbol->string (PrimitiveKernelValue-id a-prim))))
|
|
@ -1,5 +1,6 @@
|
||||||
#lang typed/racket/base
|
#lang typed/racket/base
|
||||||
(require "il-structs.rkt"
|
(require "expression-structs.rkt"
|
||||||
|
"il-structs.rkt"
|
||||||
"lexical-structs.rkt"
|
"lexical-structs.rkt"
|
||||||
"helpers.rkt"
|
"helpers.rkt"
|
||||||
racket/list)
|
racket/list)
|
||||||
|
@ -88,7 +89,9 @@
|
||||||
[(CompiledProcedureEntry? an-input)
|
[(CompiledProcedureEntry? an-input)
|
||||||
(collect-input (CompiledProcedureEntry-proc an-input))]
|
(collect-input (CompiledProcedureEntry-proc an-input))]
|
||||||
[(CompiledProcedureClosureReference? an-input)
|
[(CompiledProcedureClosureReference? an-input)
|
||||||
(collect-input (CompiledProcedureClosureReference-proc an-input))]))
|
(collect-input (CompiledProcedureClosureReference-proc an-input))]
|
||||||
|
[(PrimitiveKernelValue? an-input)
|
||||||
|
empty]))
|
||||||
|
|
||||||
|
|
||||||
(: collect-location ((U Reg Label) -> (Listof Symbol)))
|
(: collect-location ((U Reg Label) -> (Listof Symbol)))
|
||||||
|
|
31
compiler.rkt
31
compiler.rkt
|
@ -137,7 +137,9 @@
|
||||||
(append (loop (ApplyValues-proc exp) cenv)
|
(append (loop (ApplyValues-proc exp) cenv)
|
||||||
(loop (ApplyValues-args-expr exp) cenv))]
|
(loop (ApplyValues-args-expr exp) cenv))]
|
||||||
[(DefValues? exp)
|
[(DefValues? exp)
|
||||||
(append (loop (DefValues-rhs exp) cenv))])))
|
(append (loop (DefValues-rhs exp) cenv))]
|
||||||
|
[(PrimitiveKernelValue? exp)
|
||||||
|
'()])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +207,9 @@
|
||||||
[(ApplyValues? exp)
|
[(ApplyValues? exp)
|
||||||
(compile-apply-values exp cenv target linkage)]
|
(compile-apply-values exp cenv target linkage)]
|
||||||
[(DefValues? exp)
|
[(DefValues? exp)
|
||||||
(compile-def-values exp cenv target linkage)]))
|
(compile-def-values exp cenv target linkage)]
|
||||||
|
[(PrimitiveKernelValue? exp)
|
||||||
|
(compile-primitive-kernel-value exp cenv target linkage)]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1764,6 +1768,24 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(: compile-primitive-kernel-value (PrimitiveKernelValue CompileTimeEnvironment Target Linkage -> InstructionSequence))
|
||||||
|
(define (compile-primitive-kernel-value exp cenv target linkage)
|
||||||
|
(let ([id (PrimitiveKernelValue-id exp)])
|
||||||
|
(cond
|
||||||
|
[(KernelPrimitiveName? id)
|
||||||
|
|
||||||
|
(let ([singular-context-check (emit-singular-context linkage)])
|
||||||
|
;; Compiles constant values.
|
||||||
|
(end-with-linkage linkage
|
||||||
|
cenv
|
||||||
|
(append-instruction-sequences
|
||||||
|
(make-instruction-sequence
|
||||||
|
`(,(make-AssignImmediateStatement target exp)
|
||||||
|
singular-context-check)))))]
|
||||||
|
[else
|
||||||
|
(error 'unimplemented-kernel-primitive
|
||||||
|
"Primitive Kernel Value ~s has not been implemented"
|
||||||
|
id)])))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1974,4 +1996,7 @@
|
||||||
(ensure-toplevelref
|
(ensure-toplevelref
|
||||||
(adjust-expression-depth id n skip)))
|
(adjust-expression-depth id n skip)))
|
||||||
(DefValues-ids exp))
|
(DefValues-ids exp))
|
||||||
(adjust-expression-depth (DefValues-rhs exp) n skip))]))
|
(adjust-expression-depth (DefValues-rhs exp) n skip))]
|
||||||
|
|
||||||
|
[(PrimitiveKernelValue? exp)
|
||||||
|
exp]))
|
|
@ -25,7 +25,8 @@
|
||||||
BoxEnv
|
BoxEnv
|
||||||
WithContMark
|
WithContMark
|
||||||
ApplyValues
|
ApplyValues
|
||||||
DefValues))
|
DefValues
|
||||||
|
PrimitiveKernelValue))
|
||||||
|
|
||||||
;; A ModuleName is an identifier for a Module.
|
;; A ModuleName is an identifier for a Module.
|
||||||
(define-struct: ModuleName ([name : Symbol])
|
(define-struct: ModuleName ([name : Symbol])
|
||||||
|
@ -135,6 +136,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(define-struct: PrimitiveKernelValue ([id : Symbol]) #:transparent)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: last-exp? ((Listof Expression) -> Boolean))
|
(: last-exp? ((Listof Expression) -> Boolean))
|
||||||
(define (last-exp? seq)
|
(define (last-exp? seq)
|
||||||
(null? (cdr seq)))
|
(null? (cdr seq)))
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
ControlStackLabel/MultipleValueReturn
|
ControlStackLabel/MultipleValueReturn
|
||||||
ControlFrameTemporary
|
ControlFrameTemporary
|
||||||
CompiledProcedureEntry
|
CompiledProcedureEntry
|
||||||
CompiledProcedureClosureReference))
|
CompiledProcedureClosureReference
|
||||||
|
PrimitiveKernelValue))
|
||||||
|
|
||||||
|
|
||||||
;; Targets: these are the allowable lhs's for a targetted assignment.
|
;; Targets: these are the allowable lhs's for a targetted assignment.
|
||||||
|
|
|
@ -34,6 +34,28 @@
|
||||||
(define-predicate KernelPrimitiveName? KernelPrimitiveName)
|
(define-predicate KernelPrimitiveName? KernelPrimitiveName)
|
||||||
|
|
||||||
|
|
||||||
|
;; These are the primitives that we know how to inline.
|
||||||
|
(define-type KernelPrimitiveName/Inline (U '+
|
||||||
|
'-
|
||||||
|
'*
|
||||||
|
'/
|
||||||
|
'add1
|
||||||
|
'sub1
|
||||||
|
'<
|
||||||
|
'<=
|
||||||
|
'=
|
||||||
|
'>
|
||||||
|
'>=
|
||||||
|
'cons
|
||||||
|
'car
|
||||||
|
'cdr
|
||||||
|
'list
|
||||||
|
'null?
|
||||||
|
'not
|
||||||
|
'eq?))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(: kernel-primitive-expected-operand-types (KernelPrimitiveName Natural -> (Listof OperandDomain)))
|
(: kernel-primitive-expected-operand-types (KernelPrimitiveName Natural -> (Listof OperandDomain)))
|
||||||
;; Given a primitive and the number of arguments, produces the list of expected domains.
|
;; Given a primitive and the number of arguments, produces the list of expected domains.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#lang typed/racket/base
|
#lang typed/racket/base
|
||||||
(require "il-structs.rkt"
|
(require "expression-structs.rkt"
|
||||||
|
"il-structs.rkt"
|
||||||
"lexical-structs.rkt"
|
"lexical-structs.rkt"
|
||||||
racket/list)
|
racket/list)
|
||||||
|
|
||||||
|
@ -132,7 +133,9 @@
|
||||||
[(CompiledProcedureClosureReference? oparg)
|
[(CompiledProcedureClosureReference? oparg)
|
||||||
(make-CompiledProcedureClosureReference
|
(make-CompiledProcedureClosureReference
|
||||||
(adjust-oparg-depth (CompiledProcedureClosureReference-proc oparg) n)
|
(adjust-oparg-depth (CompiledProcedureClosureReference-proc oparg) n)
|
||||||
(CompiledProcedureClosureReference-n oparg))]))
|
(CompiledProcedureClosureReference-n oparg))]
|
||||||
|
[(PrimitiveKernelValue? oparg)
|
||||||
|
oparg]))
|
||||||
|
|
||||||
|
|
||||||
(define-predicate natural? Natural)
|
(define-predicate natural? Natural)
|
||||||
|
|
|
@ -38,6 +38,43 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; Code is copied-and-pasted from compiler/decompile. Maps the primval ids to their respective
|
||||||
|
;; symbolic names.
|
||||||
|
(define primitive-table
|
||||||
|
;; Figure out number-to-id mapping for kernel functions in `primitive'
|
||||||
|
(let ([bindings
|
||||||
|
(let ([ns (make-base-empty-namespace)])
|
||||||
|
(parameterize ([current-namespace ns])
|
||||||
|
(namespace-require ''#%kernel)
|
||||||
|
(namespace-require ''#%unsafe)
|
||||||
|
(namespace-require ''#%flfxnum)
|
||||||
|
(for/list ([l (namespace-mapped-symbols)])
|
||||||
|
(cons l (with-handlers ([exn:fail? (lambda (x)
|
||||||
|
#f)])
|
||||||
|
(compile l))))))]
|
||||||
|
[table (make-hash)])
|
||||||
|
(for ([b (in-list bindings)])
|
||||||
|
(let ([v (and (cdr b)
|
||||||
|
(zo-parse (let ([out (open-output-bytes)])
|
||||||
|
(write (cdr b) out)
|
||||||
|
(close-output-port out)
|
||||||
|
(open-input-bytes (get-output-bytes out)))))])
|
||||||
|
(let ([n (match v
|
||||||
|
[(struct compilation-top (_ prefix (struct primval (n)))) n]
|
||||||
|
[else #f])])
|
||||||
|
(hash-set! table n (car b)))))
|
||||||
|
table))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; parse-bytecode: Input-Port -> Expression
|
;; parse-bytecode: Input-Port -> Expression
|
||||||
(define (parse-bytecode in)
|
(define (parse-bytecode in)
|
||||||
(parameterize ([seen-closures (make-hasheq)])
|
(parameterize ([seen-closures (make-hasheq)])
|
||||||
|
@ -430,5 +467,9 @@
|
||||||
(define (parse-apply-values expr)
|
(define (parse-apply-values expr)
|
||||||
(error 'fixme))
|
(error 'fixme))
|
||||||
|
|
||||||
|
|
||||||
(define (parse-primval expr)
|
(define (parse-primval expr)
|
||||||
(error 'fixme))
|
(match expr
|
||||||
|
[(struct primval (id))
|
||||||
|
(let ([name (hash-ref primitive-table id)])
|
||||||
|
(make-PrimitiveKernelValue name))]))
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
;; For example, I'll need to be able to count the number of statements executed by an evaluation.
|
;; For example, I'll need to be able to count the number of statements executed by an evaluation.
|
||||||
;; I also need to do things like count pushes and pops. Basically, low-level benchmarking.
|
;; I also need to do things like count pushes and pops. Basically, low-level benchmarking.
|
||||||
|
|
||||||
(require "il-structs.rkt"
|
(require "expression-structs.rkt"
|
||||||
|
"il-structs.rkt"
|
||||||
"lexical-structs.rkt"
|
"lexical-structs.rkt"
|
||||||
"simulator-structs.rkt"
|
"simulator-structs.rkt"
|
||||||
"bootstrapped-primitives.rkt"
|
"bootstrapped-primitives.rkt"
|
||||||
|
@ -766,7 +767,10 @@
|
||||||
|
|
||||||
[(CompiledProcedureClosureReference? an-oparg)
|
[(CompiledProcedureClosureReference? an-oparg)
|
||||||
(let ([proc (ensure-closure (evaluate-oparg m (CompiledProcedureClosureReference-proc an-oparg)))])
|
(let ([proc (ensure-closure (evaluate-oparg m (CompiledProcedureClosureReference-proc an-oparg)))])
|
||||||
(list-ref (closure-vals proc) (CompiledProcedureClosureReference-n an-oparg)))]))
|
(list-ref (closure-vals proc) (CompiledProcedureClosureReference-n an-oparg)))]
|
||||||
|
|
||||||
|
[(PrimitiveKernelValue? an-oparg)
|
||||||
|
(lookup-primitive (PrimitiveKernelValue-id an-oparg))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
(parse-bytecode (open-input-bytes (get-output-bytes op))))))
|
(parse-bytecode (open-input-bytes (get-output-bytes op))))))
|
||||||
|
|
||||||
|
|
||||||
|
(check-equal? (run-my-parse #''hello)
|
||||||
|
(make-Top (make-Prefix '())
|
||||||
|
(make-Constant 'hello)))
|
||||||
|
|
||||||
(check-equal? (run-my-parse #'"hello world")
|
(check-equal? (run-my-parse #'"hello world")
|
||||||
(make-Top (make-Prefix (list))
|
(make-Top (make-Prefix (list))
|
||||||
|
@ -85,6 +88,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; let1's
|
||||||
(check-equal? (run-my-parse #'(let ([y (f)])
|
(check-equal? (run-my-parse #'(let ([y (f)])
|
||||||
'ok))
|
'ok))
|
||||||
(make-Top (make-Prefix (list (make-GlobalBucket 'f)))
|
(make-Top (make-Prefix (list (make-GlobalBucket 'f)))
|
||||||
|
@ -123,6 +127,9 @@
|
||||||
(make-LocalRef 0 #f)))))
|
(make-LocalRef 0 #f)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; branches
|
||||||
(check-equal? (run-my-parse #'(if (f) (g) (h)))
|
(check-equal? (run-my-parse #'(if (f) (g) (h)))
|
||||||
(make-Top (make-Prefix (list (make-GlobalBucket 'f)
|
(make-Top (make-Prefix (list (make-GlobalBucket 'f)
|
||||||
(make-GlobalBucket 'g)
|
(make-GlobalBucket 'g)
|
||||||
|
@ -140,6 +147,31 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(check-equal? (run-my-parse #'(if x (if y z 1) #t))
|
||||||
|
(make-Top (make-Prefix (list (make-GlobalBucket 'x)
|
||||||
|
(make-GlobalBucket 'y)
|
||||||
|
(make-GlobalBucket 'z)))
|
||||||
|
(make-Branch (make-ToplevelRef 0 0)
|
||||||
|
(make-Branch (make-ToplevelRef 0 1)
|
||||||
|
(make-ToplevelRef 0 2)
|
||||||
|
(make-Constant 1))
|
||||||
|
(make-Constant #t))))
|
||||||
|
|
||||||
|
|
||||||
|
(check-equal? (run-my-parse #'(cond [x y]))
|
||||||
|
(make-Top (make-Prefix (list (make-GlobalBucket 'x)
|
||||||
|
(make-GlobalBucket 'y)))
|
||||||
|
(make-Branch (make-ToplevelRef 0 0)
|
||||||
|
(make-ToplevelRef 0 1)
|
||||||
|
(make-Constant (void)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(check-equal? (run-my-parse #'+)
|
||||||
|
(make-Top (make-Prefix (list))
|
||||||
|
(make-PrimitiveKernelValue '+)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; make sure we don't see an infinite loop
|
;; make sure we don't see an infinite loop
|
||||||
|
@ -147,13 +179,12 @@
|
||||||
(g)))
|
(g)))
|
||||||
(void (run-my-parse #'(letrec ([g (lambda () (g))])
|
(void (run-my-parse #'(letrec ([g (lambda () (g))])
|
||||||
(g))))
|
(g))))
|
||||||
;; todo: add tests to make sure we're parsing this as expected.
|
;; todo: add tests to make sure we're parsing this as expected. We expect to see an EmptyClosureReference here.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#;(run-zo-parse #'(letrec ([g (lambda () (h))]
|
#;(run-zo-parse #'(letrec ([g (lambda () (h))]
|
||||||
[h (lambda () (g))])
|
[h (lambda () (g))])
|
||||||
(g)))
|
(g)))
|
||||||
;; FIXME: we need to handle closure cycles here.
|
;; FIXME: we need to handle closure cycles here.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user