Skip to content

Commit

Permalink
vectors in syntax-rules patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
jcubic committed Jan 30, 2024
1 parent 4d58def commit ac35349
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 219 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![npm](https://img.shields.io/badge/npm-1.0.0%E2%80%93beta.18.1-blue.svg)](https://www.npmjs.com/package/@jcubic/lips)
![1.0.0 Complete](https://img.shields.io/github/milestones/progress-percent/jcubic/lips/1?label=1.0.0%20Complete)
[![Build and test](https://github.com/jcubic/lips/actions/workflows/build.yaml/badge.svg?branch=devel&event=push)](https://github.com/jcubic/lips/actions/workflows/build.yaml)
[![Coverage Status](https://coveralls.io/repos/github/jcubic/lips/badge.svg?branch=devel&11ba88363e619f57a11527ee298bf93a)](https://coveralls.io/github/jcubic/lips?branch=devel)
[![Coverage Status](https://coveralls.io/repos/github/jcubic/lips/badge.svg?branch=devel&f132026a42f8e324556b86fd84287233)](https://coveralls.io/github/jcubic/lips?branch=devel)
[![Join Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jcubic/lips)
![NPM Download Count](https://img.shields.io/npm/dm/@jcubic/lips)
![JSDelivr Download count](https://img.shields.io/jsdelivr/npm/hm/@jcubic/lips)
Expand Down
197 changes: 129 additions & 68 deletions dist/lips.cjs

Large diffs are not rendered by default.

197 changes: 129 additions & 68 deletions dist/lips.esm.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions dist/lips.esm.min.js

Large diffs are not rendered by default.

197 changes: 129 additions & 68 deletions dist/lips.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions dist/lips.min.js

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions dist/std.scm

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 54 additions & 4 deletions src/lips.js
Original file line number Diff line number Diff line change
Expand Up @@ -3575,6 +3575,47 @@ function extract_patterns(pattern, code, symbols, ellipsis_symbol, scope = {}) {
const ref = expansion.ref(pattern);
return !ref || ref === define || ref === global_env;
}
if (Array.isArray(pattern) && Array.isArray(code)) {
log('<<< a 1');
if (pattern.length === 0 && code.length === 0) {
return true;
}
if (LSymbol.is(pattern[1], ellipsis_symbol)) {
if (pattern[0] instanceof LSymbol) {
const name = pattern[0].valueOf();
log('<<< a 2 ' + ellipsis);
if (ellipsis) {
const as_list = Pair.fromArray(code, false);
if (!bindings['...'].symbols[name]) {
bindings['...'].symbols[name] = new Pair(as_list, nil);
} else {
bindings['...'].symbols[name].append(new Pair(as_list, nil));
}
} else {
bindings['...'].symbols[name] = code;
}
} else if (Array.isArray(pattern[0])) {
log('<<< a 3');
const names = [...pattern_names];
let node = code;
if (!code.every(node => traverse(pattern[0], node, names, true))) {
return false;
}
}
if (pattern.length > 2) {
log('THERE IS MORE');
log(pattern);
const pat = pattern.slice(2);
return traverse(pat, code.slice(-pat.length), pattern_names, ellipsis);
}
return true;
}
const first = traverse(pattern[0], code[0], pattern_names, ellipsis);
log({first, pattern: pattern[0], code: code[0]});
const rest = traverse(pattern.slice(1), code.slice(1), pattern_names, ellipsis);
log({first, rest});
return first && rest;
}
// pattern (a b (x ...)) and (x ...) match nil
if (pattern instanceof Pair &&
pattern.car instanceof Pair &&
Expand All @@ -3586,7 +3627,7 @@ function extract_patterns(pattern, code, symbols, ellipsis_symbol, scope = {}) {
if (pattern.car.car instanceof LSymbol) {
if (pattern.car.cdr instanceof Pair &&
LSymbol.is(pattern.car.cdr.car, ellipsis_symbol)) {
let name = pattern.car.car.valueOf();
const name = pattern.car.car.valueOf();
const last = pattern.last_pair();
if (LSymbol.is(last.car, ellipsis_symbol)) {
bindings['...'].symbols[name] = null;
Expand Down Expand Up @@ -3738,6 +3779,16 @@ function extract_patterns(pattern, code, symbols, ellipsis_symbol, scope = {}) {
node = node.cdr;
}
return true;
} if (Array.isArray(pattern.car) ) {
var names = [...pattern_names];
let node = code;
while (node instanceof Pair) {
if (!traverse(pattern.car, node.car, names, true)) {
return false;
}
node = node.cdr;
}
return true;
}
return false;
}
Expand All @@ -3751,12 +3802,11 @@ function extract_patterns(pattern, code, symbols, ellipsis_symbol, scope = {}) {
return true;
}
if (ellipsis) {
bindings['...'].symbols[name] = bindings['...'].symbols[name] || [];
log(bindings['...'].symbols[name]);
bindings['...'].symbols[name] ??= [];
bindings['...'].symbols[name].push(code);
}
bindings.symbols[name] = code;
if (!bindings.symbols[name]) {
}
return true;
}
if (pattern instanceof Pair && code instanceof Pair) {
Expand Down
57 changes: 57 additions & 0 deletions tests/syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1362,3 +1362,60 @@
(t.is (to.throw (let ((else #f) (x 10))
(if+ (even? x) then (/ x 2) else (/ (+ x 1) 2))))
#t)))

(test "syntax: vectors as symbols"
(lambda (t)
(define-syntax foo
(syntax-rules ()
((_ sym ...)
(list sym ...))))

(t.is (foo #(1 2) #(3 4)) '(#(1 2) #(3 4)))))

(test "syntax: make-vector"
(lambda (t)
(define-syntax foo
(syntax-rules ()
((_ #(x ...) ...)
(vector x ... ...))))

(t.is (foo #(1 2) #(3 4))
#(1 2 3 4))))

(test "syntax: vector and symbol + rest"
(lambda (t)
(define-syntax foo
(syntax-rules ()
((_ #(a b ...) ...)
(vector (list a b ...) ...))))

(t.is (foo #(1 2 3) #(4 5 6))
#((1 2 3) (4 5 6)))))

(test "syntax: vector 3 ellipsis"
(lambda (t)
(define-syntax foo
(syntax-rules ()
((_ #(#(a b ...) ...) ...)
(vector '(a b ...) ... ...))))

(t.is (foo #(#(1 2 3) #(4 5 6)) #(#(1 2)))
#((1 2 3) (4 5 6) (1 2)))))

(test "syntax: vector ellipsis + symbols after"
(lambda (t)
(define-syntax quux
(syntax-rules ()
((_ #(a b ... z) ...)
(vector 'z ...))))

(t.is (quux #(1 2 3) #(4 5 6) #(7 8 9))
#(3 6 9))

(define-syntax quux
(syntax-rules ()
((_ #(x ... a b) ...)
(vector '(a b) ...))))

(t.is (quux #(1 2 3 4) #(5 6 7 8) #(9 10 11 12))
#((3 4) (7 8) (11 12)))))

0 comments on commit ac35349

Please sign in to comment.