203 lines
7.9 KiB
Plaintext
203 lines
7.9 KiB
Plaintext
top:
|
|
00xxxxxx out in in: expression
|
|
01xxxxxx in in in: statement
|
|
1xxxxxxx out in in: conditional
|
|
expression: up to 64, 1 out, 2 in
|
|
00000000 out sub in: unary-expr
|
|
00xxxxxx out in in: binary-expr, x > 1
|
|
unary-expr: up to 255, 1 out, 1 in
|
|
00 invalid / permanently reserved
|
|
01 (set! out in)
|
|
02 (set! out (car in))
|
|
03 (set! out (cdr in))
|
|
04 (set! out (unbox in))
|
|
05 (set! out (not in)) ; if in == #f then #t else #f
|
|
06 (set! out (nil? in)) ; value => bool
|
|
07 (set! out (pair? in)) ; value => bool
|
|
08 (set! out (box? in)) ; value => bool
|
|
09 (set! out (vector? in)) ; value => bool
|
|
0a (set! out (byte-string? in)) ; value => bool
|
|
0b (set! out (struct? in)) ; value => bool
|
|
0c (set! out (fixnum? in)) ; value => bool
|
|
0d (set! out (float? in)) ; value => bool
|
|
0e (set! out (make-box in)) ; value => box
|
|
0f (set! out (make-struct in)) ; metastruct => struct
|
|
10 (set! out (make-float in)) ; fixnum => float
|
|
11 (set! out (lambda in)) ; template-or-lambda => lambda
|
|
12 (set! out (bit-not in)) ; one's complement / bitwise negation
|
|
13 (set! out (fix- in)) ; two's complement / arithmetic negation
|
|
14 (set! out (float- in)) ; floating-point negation
|
|
|
|
; ISO C floating-point
|
|
20 (set! out (acos in))
|
|
21 (set! out (asin in))
|
|
22 (set! out (atan in))
|
|
23 (set! out (cos in))
|
|
24 (set! out (sin in))
|
|
25 (set! out (tan in))
|
|
26 (set! out (cosh in))
|
|
27 (set! out (sinh in))
|
|
28 (set! out (tanh in))
|
|
29 (set! out (exp in))
|
|
2a (set! out (frexp in)) ; float => (float . fixnum)
|
|
2b (set! out (log in)) ; base e
|
|
2c (set! out (log10 in))
|
|
2d (set! out (modf in)) ; float => (float . float)
|
|
2e (set! out (sqrt in))
|
|
2f (set! out (ceil in))
|
|
30 (set! out (fabs in))
|
|
31 (set! out (floor in))
|
|
|
|
; SVID & X/Open
|
|
40 (set! out (erf in))
|
|
41 (set! out (erfc in))
|
|
; (set! out (gamma in)) ; obsolete
|
|
42 (set! out (j0 in))
|
|
43 (set! out (j1 in))
|
|
44 (set! out (lgamma in)) ; float => (float . fixnum), actually lgamma_r
|
|
45 (set! out (y0 in))
|
|
46 (set! out (y1 in))
|
|
|
|
; SVID & XPG 4.2/5
|
|
47 (set! out (asinh in))
|
|
48 (set! out (acosh in))
|
|
49 (set! out (atanh in))
|
|
4a (set! out (cbrt in))
|
|
4b (set! out (logb in))
|
|
|
|
; XPG 4.2/5
|
|
4c (set! out (expm1 in))
|
|
4d (set! out (ilogb in))
|
|
4e (set! out (log1p in))
|
|
; (set! out (rint in)) ; implies changing rounding mode; use floor or ceil
|
|
binary-expr: up to 63 (01..3f), 1 out, 2 in
|
|
00 unary-expr
|
|
01 (set! out (cons in1 in2)) ; car cdr
|
|
02 (set! out (make-vector in1 in2)) ; nelem iv, nelem >= 0
|
|
03 (set! out (make-byte-string in1 in2)) ; nbytes iv, nbytes >= 0
|
|
04 (set! out (vector-ref in1 in2)) ; vector n, 0 <= n < nelem
|
|
05 (set! out (byte-string-ref in1 in2)) ; string n, 0 <= n < nbytes
|
|
06 (set! out (struct-ref in1 in2)) ; struct n, 0 <= n < nslots
|
|
07 (set! out (eq? in1 in2)) ; any values; superset of (fix= in2 in1)
|
|
08 (set! out (fix+ in1 in2))
|
|
09 (set! out (fix- in1 in2))
|
|
0a (set! out (fix* in1 in2))
|
|
0b (set! out (fix/ in1 in2))
|
|
0c (set! out (fix% in1 in2))
|
|
0d (set! out (fix< in1 in2)) ; == (fix> in2 in1)
|
|
0e (set! out (fix>= in1 in2)) ; == (fix<= in2 in1)
|
|
0f (set! out (bit-and in1 in2))
|
|
10 (set! out (bit-or in1 in2))
|
|
11 (set! out (bit-xor in1 in2))
|
|
12 (set! out (fix<< in1 in2)) ; arithmetic left-shift (2*x) w/ overflow into sign
|
|
13 (set! out (fix>> in1 in2)) ; arithmetic right-shift (x/2)
|
|
14 (set! out (fix>>> in1 in2)) ; logical right-shift; sign becomes zero (+)
|
|
15 (set! out (float+ in1 in2))
|
|
16 (set! out (float- in1 in2))
|
|
17 (set! out (float* in1 in2))
|
|
18 (set! out (float/ in1 in2))
|
|
19 (set! out (float< in1 in2)) ; == (float> in2 in1)
|
|
1a (set! out (float>= in1 in2)) ; == (float<= in2 in1)
|
|
1b (set! out (atan2 in1 in2)) ; float float
|
|
1c (set! out (pow in1 in2)) ; float float
|
|
1d (set! out (ldexp in1 in2)) ; float fixnum
|
|
1e (set! out (fmod in1 in2)) ; float float
|
|
1f (set! out (hypot in1 in2)) ; float float
|
|
20 (set! out (jn in1 in2)) ; fixnum float
|
|
21 (set! out (yn in1 in2)) ; fixnum float
|
|
22 (set! out (nextafter in1 in2)) ; float float
|
|
23 (set! out (remainder in1 in2)) ; float float
|
|
24 (set! out (scalb in1 in2)) ; float float
|
|
conditional: 1AAAAAAA; 1 out, 2 in + fA
|
|
AA (set! out (if fA in1 in2)) ; in2 if fA == #f, in1 otherwise
|
|
statement: up to 64 (40..7f), 3 in
|
|
40 (set-box! in in) ; box value
|
|
41 (set-car! in in) ; pair value
|
|
42 (set-cdr! in in) ; pair value
|
|
|
|
60 (vector-set! in in in) ; vector n value, 0 <= n < nelem
|
|
61 (byte-string-set! in in in) ; string n value, 0 <= n < nbytes
|
|
62 (struct-set! in in in) ; struct n value, 0 <= n < nslots
|
|
|
|
in:
|
|
nil (00000000) [g0, always NIL]
|
|
gN (00NNNNNN) [global, N < 64]
|
|
iN (01NNNNNN) [instance, N < 64]
|
|
fN (1NNNNNNN) [frame, N < 120]
|
|
-- (11111NNN) [reserved, N < 5]
|
|
argv (11111101) [argument list]
|
|
k (11111110) [continuation]
|
|
ctx (11111111) [dynamic context]
|
|
|
|
out:
|
|
fN (1NNNNNNN) [0 <= N < 120]
|
|
|
|
lambda:[
|
|
global: vector of immutable values (g1..gN); shared between instances (lambdas)
|
|
instance: vector of immutable values (i0..iN); shared between frames (calls)
|
|
frame: number of frame variables; initially NIL
|
|
code: byte-string containing sequence of 4-byte instruction words
|
|
tail-call: in-ref of lambda to tail-call
|
|
arguments: in-ref of argument list to pass to tail-call
|
|
continuation: in-ref of continuation to pass to tail-call
|
|
context: in-ref of dynamic context to pass to tail-call
|
|
]
|
|
|
|
template:[
|
|
global: linked
|
|
instance: byte-string of in-refs. to parent instance/frame slots
|
|
frame: copied verbatim
|
|
code: linked
|
|
tail-call: copied verbatim
|
|
arguments: copied verbatim
|
|
continuation: copied verbatim
|
|
context: copied verbatim
|
|
]
|
|
|
|
Protocol:
|
|
|
|
Normal function calls (return to caller, or caller's continuation if tail-call):
|
|
Call: Tail-call function with valid 'k' and original 'ctx'.
|
|
Return: Tail-call 'k' with 'nil' continuation and context (ignored).
|
|
|
|
Coroutines (cooperating, interleaved tail-call chains in CPS):
|
|
Call: Tail-call function with valid 'k' and original 'ctx'.
|
|
Return: Tail-call 'k' with valid 'k' and original 'ctx'.
|
|
|
|
call-with-current-continuation:
|
|
Look up abort handler by prompt tag in incoming 'ctx'.
|
|
call provided lambda with lambda parameter as follows:
|
|
Tail-call abort handler with same parameters and 'k' & 'ctx' from call/cc.
|
|
|
|
call-with-composable-continuation:
|
|
(define (call-with-composable-continuation proc [prompt-tag (current-prompt-tag)])
|
|
(let [(meta-continuation (prompt-tag-meta-continuation prompt-tag))]
|
|
(call-with-current-continuation
|
|
(lambda (k)
|
|
(let [(result (let [(var (lambda values
|
|
(call-with-continuation-prompt
|
|
(lambda () (apply k values))
|
|
prompt-tag)))]
|
|
(proc var)))]
|
|
((meta-continuation) result))))]))
|
|
|
|
call-with-continuation-prompt:
|
|
(define (call-with-continuation-prompt body-thunk
|
|
[prompt-tag (current-prompt-tag)]
|
|
[abort-proc (lambda (fn . args)
|
|
(apply fn args))])
|
|
(let [(meta-continuation (prompt-tag-meta-continuation prompt-tag))
|
|
(abort-handler (prompt-tag-abort-handler prompt-tag))]
|
|
(call-with-current-continuation
|
|
(lambda (k)
|
|
(parameterize [(meta-continuation k)
|
|
(abort-handler abort-proc)]
|
|
(let [(result (body-thunk))]
|
|
((meta-continuation) result))))))]))
|
|
|
|
parameterize:
|
|
Call thunk with 'k' and updated context.
|
|
New context includes (parameter => value) association.
|
|
|
|
# vim:set sw=2 expandtab tw=0:
|