Skip to content

Commit d0f170f

Browse files
authored
Merge pull request #392 from yamacir-kit/r5rs
Compliant with R5RS
2 parents bef08e6 + 36c0389 commit d0f170f

File tree

8 files changed

+152
-33
lines changed

8 files changed

+152
-33
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ sudo rm -rf /usr/local/share/meevax
103103

104104
| Target Name | Description
105105
|:-------------------|:--
106-
| `all` (default) | Build shared-library `libmeevax.0.3.1022.so` and executable `meevax`.
106+
| `all` (default) | Build shared-library `libmeevax.0.4.0.so` and executable `meevax`.
107107
| `test` | Test executable `meevax`.
108-
| `package` | Generate debian package `meevax_0.3.1022_amd64.deb`.
108+
| `package` | Generate debian package `meevax_0.4.0_amd64.deb`.
109109
| `install` | Copy files into `/usr/local` __(1)__.
110110
| `install.deb` | `all` + `package` + `sudo apt install <meevax>.deb`
111111
| `safe-install.deb` | `all` + `test` + `package` + `sudo apt install <meevax>.deb`
@@ -120,7 +120,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's
120120
## Usage
121121

122122
```
123-
Meevax Lisp System, version 0.3.1022
123+
Meevax Lisp System, version 0.4.0
124124
125125
Usage: meevax [OPTION...] [FILE...]
126126

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.1022
1+
0.4.0

include/meevax/kernel/machine.hpp

+46-15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ inline namespace kernel
3939
machine()
4040
{}
4141

42+
IMPORT(environment, fork, const);
43+
4244
protected:
4345
let s, // stack (holding intermediate results and return address)
4446
e, // environment (giving values to symbols)
@@ -113,12 +115,31 @@ inline namespace kernel
113115
let const& expression)
114116
: syntactic_environment { syntactic_environment }
115117
, expression { expression }
116-
, identity { identify() }
118+
, identity { syntactic_environment.as<environment>().identify(expression, syntactic_environment.as<environment>().scope()) }
117119
{}
118120

119-
auto identify()
121+
auto identify_with_offset(const_reference use_env_scope)
120122
{
121-
return syntactic_environment.as<environment>().identify(expression, syntactic_environment.as<environment>().scope());
123+
if (identity.is<relative>())
124+
{
125+
let const& mac_env_scope = syntactic_environment.as<environment>().scope();
126+
auto offset = make<exact_integer>(length(use_env_scope) - length(mac_env_scope));
127+
return make<relative>(car(identity),
128+
cadr(identity).template as<exact_integer>() + offset,
129+
cddr(identity));
130+
}
131+
else if (identity.is<variadic>())
132+
{
133+
let const& mac_env_scope = syntactic_environment.as<environment>().scope();
134+
auto offset = make<exact_integer>(length(use_env_scope) - length(mac_env_scope));
135+
return make<variadic>(car(identity),
136+
cadr(identity).template as<exact_integer>() + offset,
137+
cddr(identity));
138+
}
139+
else
140+
{
141+
return identity;
142+
}
122143
}
123144

124145
friend auto operator ==(syntactic_closure const& x, syntactic_closure const& y) -> bool
@@ -197,12 +218,21 @@ inline namespace kernel
197218
return cons(id.as<identity>().make_load_instruction(), id,
198219
current_continuation);
199220
}
200-
else
221+
else // The syntactic-closure encloses procedure call.
201222
{
223+
let mac_env_scope = current_expression.as<syntactic_closure>().syntactic_environment.template as<environment>().scope();
224+
225+
auto offset = length(current_scope) - length(mac_env_scope);
226+
227+
for (auto i = 0; i < offset; ++i)
228+
{
229+
mac_env_scope = cons(unit, mac_env_scope);
230+
}
231+
202232
return compile(current_context,
203233
current_expression.as<syntactic_closure>().syntactic_environment.template as<environment>(),
204234
current_expression.as<syntactic_closure>().expression,
205-
current_expression.as<syntactic_closure>().syntactic_environment.template as<environment>().scope(),
235+
mac_env_scope,
206236
current_continuation);
207237
}
208238
}
@@ -421,7 +451,7 @@ inline namespace kernel
421451
*
422452
* ------------------------------------------------------------------- */
423453
assert(car(s).template is<closure>());
424-
cadr(c).template as<absolute>().load() = make<transformer>(car(s), static_cast<environment const&>(*this).fork());
454+
cadr(c).template as<absolute>().load() = make<transformer>(car(s), fork());
425455
c = cddr(c);
426456
goto decode;
427457

@@ -438,10 +468,12 @@ inline namespace kernel
438468

439469
let const& f = environment(static_cast<environment const&>(*this)).execute(binding);
440470

441-
binding = make<transformer>(f, static_cast<environment const&>(*this).fork(cadr(c).template as<syntactic_continuation>().scope()));
471+
binding = make<transformer>(f, fork(cdr(cadr(c).template as<syntactic_continuation>().scope())));
442472
}
443473
}();
444474

475+
e = cons(unit, e); // dummy environment
476+
445477
std::swap(c.as<pair>(),
446478
body(context::none,
447479
static_cast<environment &>(*this),
@@ -459,22 +491,21 @@ inline namespace kernel
459491
* ------------------------------------------------------------------- */
460492
[&]() // DIRTY HACK!!!
461493
{
462-
let const syntactic_environment
463-
= static_cast<environment const&>(*this).fork(cadr(c).template as<syntactic_continuation>().scope());
494+
let const expander = fork(cadr(c).template as<syntactic_continuation>().scope());
464495

465496
auto const [transformer_specs, body] = unpair(cadr(c).template as<syntactic_continuation>().expression());
466497

467498
for (let const& transformer_spec : transformer_specs)
468499
{
469-
syntactic_environment.as<environment>().execute(compile(context::outermost,
470-
syntactic_environment.as<environment>(),
471-
cons(make<syntax>("define-syntax", define_syntax), transformer_spec),
472-
cadr(c).template as<syntactic_continuation>().scope()));
500+
expander.as<environment>().execute(compile(context::outermost,
501+
expander.as<environment>(),
502+
cons(make<syntax>("define-syntax", define_syntax), transformer_spec),
503+
cadr(c).template as<syntactic_continuation>().scope()));
473504
}
474505

475506
std::swap(c.as<pair>(),
476507
machine::body(context::outermost,
477-
syntactic_environment.as<environment>(),
508+
expander.as<environment>(),
478509
body,
479510
cadr(c).template as<syntactic_continuation>().scope(),
480511
cddr(c)
@@ -686,7 +717,7 @@ inline namespace kernel
686717
}
687718
}
688719

689-
return variable.is<syntactic_closure>() ? variable.as<syntactic_closure>().identify() : f;
720+
return variable.is<syntactic_closure>() ? variable.as<syntactic_closure>().identify_with_offset(scope) : f;
690721
}
691722

692723
inline auto reset() -> void

script/version.sh

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ root="$(git rev-parse --show-toplevel)"
44

55
current_version()
66
{
7-
count="$(git rev-list --count HEAD)"
8-
echo "0.3.$((count - 2135))"
7+
# count="$(git rev-list --count HEAD)"
8+
# echo "0.3.$((count - 2135))"
9+
10+
count="$(git rev-list --no-merges --count HEAD)"
11+
echo "0.4.$((count - 2854))"
912
}
1013

1114
update_version()
@@ -16,7 +19,7 @@ update_version()
1619
list_version()
1720
{
1821
git fetch origin --tags
19-
git tag --list | sed -e 's/^/ /'
22+
git tag --list --sort=version:refname | sed -e 's/^/ /'
2023
echo "\e[32m* v$(current_version)\e[0m"
2124
}
2225

src/main.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ auto main(int const argc, char const* const* const argv) -> int
3232
if (main.is_interactive_mode())
3333
{
3434
main.display_version();
35-
main.print(features());
35+
main.declare_import("(scheme r5rs)");
3636
}
3737

3838
while (main.is_interactive_mode() and main.char_ready())

test/let-syntax.ss

+19-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@
5151
(let ((x 'inner))
5252
(m)))) => outer)
5353

54+
(check (let ((x 'outer))
55+
(let-syntax ((m (er-macro-transformer
56+
(lambda (form rename compare)
57+
(rename 'x)))))
58+
(let ((x 'x1))
59+
(let ((x 'x2))
60+
(let ((x 'x3))
61+
(m)))))) => outer)
62+
63+
(let ((x 'outer))
64+
(let-syntax ((m (er-macro-transformer
65+
(lambda (form rename compare)
66+
(rename 'x)))))
67+
(let ((x 'x1))
68+
(let ((x 'x2))
69+
(let ((x 'x3))
70+
(check (m) => outer))))))
71+
5472
(define result
5573
(let ((x 'outer))
5674
(let-syntax ((m (er-macro-transformer
@@ -63,4 +81,4 @@
6381

6482
(check-report)
6583

66-
(exit (check-passed? 5))
84+
(exit (check-passed? 7))

test/letrec-syntax.ss

+38-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
(import (scheme base)
22
(scheme process-context)
33
(srfi 78)
4-
(srfi 211 explicit-renaming))
4+
(srfi 211 explicit-renaming)
5+
(srfi 211 syntactic-closures))
56

67
(letrec-syntax ((my-and (er-macro-transformer
78
(lambda (form rename compare)
@@ -30,13 +31,42 @@
3031
(if even?))
3132
(check (my-or x (let temp) (if y) y) => 7)))
3233

33-
; (check (let ((x 'outer))
34-
; (letrec-syntax ((m (er-macro-transformer
35-
; (lambda (form rename compare)
36-
; (rename 'x)))))
37-
; (let ((x 'inner))
38-
; (m)))) => outer)
34+
(check (let ((x 'outer))
35+
(letrec-syntax ((m (er-macro-transformer
36+
(lambda (form rename compare)
37+
(rename 'x)))))
38+
(m))) => outer)
39+
40+
(check (let ((x 'outer))
41+
(letrec-syntax ((m (er-macro-transformer
42+
(lambda (form rename compare)
43+
(rename 'x)))))
44+
(let ((x 'inner))
45+
(m)))) => outer)
46+
47+
(check (let ((x 'outer))
48+
(letrec-syntax ((m (er-macro-transformer
49+
(lambda (form rename compare)
50+
(rename 'x)))))
51+
(let ((x 'x1))
52+
(let ((x 'x2))
53+
(let ((x 'x3))
54+
(m)))))) => outer)
55+
56+
(check (let ((x 'outer))
57+
(letrec-syntax ((m (sc-macro-transformer
58+
(lambda (form use-env)
59+
'x))))
60+
(let ((x 'inner))
61+
(m)))) => outer)
62+
63+
(check (let ((x 'outer))
64+
(letrec-syntax ((m (rsc-macro-transformer
65+
(lambda (form mac-env)
66+
(make-syntactic-closure mac-env '() 'x)))))
67+
(let ((x 'inner))
68+
(m)))) => outer)
3969

4070
(check-report)
4171

42-
(exit (check-passed? 2))
72+
(exit (check-passed? 7))

test/transformer.ss

+38-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,43 @@
6262

6363
(check (cons x y) => (2 . 1))
6464

65+
(let-syntax ((swap!
66+
(sc-macro-transformer
67+
(lambda (form use-env)
68+
(let ((a (make-syntactic-closure use-env '() (cadr form)))
69+
(b (make-syntactic-closure use-env '() (caddr form))))
70+
`(let ((value ,a))
71+
(set! ,a ,b)
72+
(set! ,b value)))))))
73+
(let ((a 'non-hygienic!)
74+
(b 'non-hygienic!)
75+
(let 'non-hygienic!)
76+
(set! 'non-hygienic!)
77+
(value 'non-hygienic!))
78+
(swap! x y)))
79+
80+
(check (cons x y) => (1 . 2))
81+
82+
(let ((return-value 42))
83+
(let-syntax ((swap!
84+
(sc-macro-transformer
85+
(lambda (form use-env)
86+
(let ((a (make-syntactic-closure use-env '() (cadr form)))
87+
(b (make-syntactic-closure use-env '() (caddr form))))
88+
`(let ((value ,a))
89+
(set! ,a ,b)
90+
(set! ,b value)
91+
return-value))))))
92+
(let ((a 'non-hygienic!)
93+
(b 'non-hygienic!)
94+
(let 'non-hygienic!)
95+
(set! 'non-hygienic!)
96+
(value 'non-hygienic!)
97+
(return-value 3.14))
98+
(check (swap! x y) => 42))))
99+
100+
(check (cons x y) => (2 . 1))
101+
65102
; ------------------------------------------------------------------------------
66103

67104
(define-syntax swap!
@@ -132,4 +169,4 @@
132169

133170
(check-report)
134171

135-
(exit (check-passed? 12))
172+
(exit (check-passed? 15))

0 commit comments

Comments
 (0)