Skip to content

Commit f1ed60c

Browse files
committed
wip
1 parent 27faf73 commit f1ed60c

File tree

4 files changed

+418
-2
lines changed

4 files changed

+418
-2
lines changed

blc.php

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
// ;;;; Krivine's Machine in Scheme ;;;;
4+
// ;;; 2012 Minori Yamashita <[email protected]> ;;add your name here
5+
// ;;;
6+
// ;;; reference:
7+
// ;;; http://pauillac.inria.fr/~xleroy/talks/zam-kazam05.pdf
8+
// ;;; http://pop-art.inrialpes.fr/~fradet/PDFs/HOSC07.pdf
9+
//
10+
// ;;; Notes ;;;
11+
// ;; CLOSURE creates thunks that packs the continuation and environment together.
12+
// ;; To create closures(function objects), CLOSURE the GRAB and expression followed by CONTINUE.
13+
// ;;
14+
15+
// based on:
16+
// https://github.com/ympbyc/Carrot/blob/master/old/Krivine.scm
17+
18+
// ;;get the value associated with the key symbol
19+
// (define (assoc-ref env key)
20+
// (let ((binding (assq key env)))
21+
// (if binding (cdr binding) 'lookup-fail)))
22+
23+
// ;;; Krivine's Machine ;;;
24+
function krivine($code, $env, $stack)
25+
{
26+
// ;(print (format "code : ~S" code))
27+
// ;(print (format "env : ~S" env))
28+
// ;(print (format "stack: ~S" stack))
29+
// ;(print (format "g-env: ~S"))
30+
// ;(newline)
31+
32+
$inst = first(first($code));
33+
$inst_arg = rest(first($code));
34+
$code_rest = rest($code);
35+
36+
return $inst($inst_arg, $inst_arg, $code_rest, $env, $stack);
37+
}
38+
39+
// ;; refer a value associated with the character from either local-env or global-env
40+
function ACCESS($args, $code, $env, $stack)
41+
{
42+
$val = assoc_ref($env, first($args));
43+
array_unshift($stack, $val);
44+
45+
return krivine($code, $env, $stack);
46+
}
47+
48+
// ;; retrieves a thunk from the stack and replace the state with its.
49+
// ;; thunks carry all the continuation therefore no need to worry about the "frame" or "return"
50+
function _CONTINUE($args, $code, $env, $stack)
51+
{
52+
$closure = first($stack);
53+
$c_code = assoc_ref($closure, 'code');
54+
$c_env = assoc_ref($closure, 'env');
55+
56+
return krivine($c_code, $c_env, rest($stack));
57+
}
58+
59+
// ;; associate a stack-top value with the character and cons the pair onto the local-env
60+
function GRAB($args, $code, $env, $stack)
61+
{
62+
// (cons `(,(car args) . ,(car stack)) env)
63+
array_unshift($env, [first($args), first($stack)]);
64+
65+
return krivine($code, $env, rest($stack));
66+
}
67+
68+
// ;; creates a thunk that is a data carrying continuation + environment
69+
function CLOSURE($args, $code, $env, $stack)
70+
{
71+
// (cons `((code . ,(car args)) (env . ,env)) stack))
72+
array_unshift($stack, [[$code, first($args)], [$env, $env]]);
73+
74+
return krivine($code, $env, $stack);
75+
}
76+
77+
__halt_compiler();
78+
79+
(define (PRIMITIVE args code env stack)
80+
(define (get-constant code) ;dirty part
81+
(receive (result _)
82+
(guard (exc
83+
(else (values 'closure '())))
84+
(Krivine- code env '())) result))
85+
(let ([subr (car args)]
86+
[p-args (cdr args)]
87+
[true `((,ACCESS true) (,CONTINUE))]
88+
[false `((,ACCESS false) (,CONTINUE))])
89+
(cond
90+
[(eq? subr 'equal)
91+
(Krivine-
92+
(append (if (equal? (get-constant (car p-args)) (get-constant (cadr p-args))) true false) code)
93+
env stack)]
94+
[(eq? subr '<)
95+
(Krivine-
96+
(append (if (< (get-constant (car p-args)) (get-constant (cadr p-args))) true false) code)
97+
env stack)]
98+
[(eq? subr '<=)
99+
(Krivine-
100+
(append (if (<= (get-constant (car p-args)) (get-constant (cadr p-args))) true false) code)
101+
env stack)]
102+
[(eq? subr '+)
103+
(Krivine-
104+
code env
105+
(cons (+ (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
106+
[(eq? subr '-)
107+
(Krivine-
108+
code env
109+
(cons (- (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
110+
[(eq? subr '*)
111+
(Krivine-
112+
code env
113+
(cons (* (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
114+
[(eq? subr '/)
115+
(Krivine-
116+
code env
117+
(cons (/ (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
118+
[(eq? subr '%)
119+
(Krivine-
120+
code env
121+
(cons (mod (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
122+
[(eq? subr '++)
123+
(Krivine-
124+
code env
125+
(cons (string-append (get-constant (car p-args)) (get-constant (cadr p-args))) stack))]
126+
[(eq? subr 'num->str)
127+
(Krivine-
128+
code env
129+
(cons (number->string (get-constant (car p-args))) stack))]
130+
[(eq? subr 'string?)
131+
(Krivine-
132+
(append (if (string? (get-constant (car p-args))) true false) code) env stack)]
133+
[(eq? subr 'number?)
134+
(Krivine-
135+
(append (if (number? (get-constant (car p-args))) true false) code)
136+
env stack)]
137+
[(eq? subr 'print)
138+
(print (get-constant (car p-args)))
139+
(Krivine-
140+
code env stack)]
141+
[(eq? subr 'time)
142+
(time (get-constant (car p-args)))
143+
(Krivine-
144+
code env stack)])))

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
"email": "[email protected]"
1010
}
1111
],
12+
"require": {
13+
"nikic/iter": "dev-master"
14+
},
1215
"require-dev": {
1316
"jakubledl/dissect": "dev-develop"
1417
},

composer.lock

Lines changed: 40 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)