rebirth: Use cdr in libprebirth replacement proc definitions

This removes the need to use the ES `arguments' reference.  Not only is this
what we want to do, but it's _necessary_---the next commit will introduce
environments, and wrapping procedures in lambdas breaks the `arguments'
reference in each of these cases.

Note that fold and map can now be written in Rebirth Lisp, but I'm just
leaving them alone for now.

* build-aux/bootstrap/rebirth.scm
  (append, string-append, +, -, map): Use define cdr in place of ES
    `arguments'.
master
Mike Gerwitz 2018-01-05 00:01:22 -05:00
parent 49142b6630
commit 01990614cc
Signed by: mikegerwitz
GPG Key ID: 8C917B7F5DC51BA2
1 changed files with 18 additions and 27 deletions

View File

@ -240,8 +240,7 @@
(define (es:arg->arr args) (define (es:arg->arr args)
(string->es "Array.prototype.slice.call($$args)")) (string->es "Array.prototype.slice.call($$args)"))
(define (list) (define (list . xs) xs)
(es:arg->arr (string->es "arguments")))
;; warning: only compares two values ;; warning: only compares two values
(define (= x y) (define (= x y)
@ -284,12 +283,12 @@
(es:-assert-pair pair) (es:-assert-pair pair)
(string->es "$$pair.slice(1)")) (string->es "$$pair.slice(1)"))
(define (append) (define (append . args)
(fold (lambda (x xs) (fold (lambda (x xs)
(es:-assert-list x) (es:-assert-list x)
(string->es "$$xs.concat($$x)")) (string->es "$$xs.concat($$x)"))
(list) (list)
(es:arg->arr (string->es "arguments")))) args))
;; warning: these two are wholly inadequate ;; warning: these two are wholly inadequate
(define (list? xs) (define (list? xs)
@ -307,26 +306,23 @@
(string->es "typeof $$s1 === 'string' && $$s1 === $$s2")) (string->es "typeof $$s1 === 'string' && $$s1 === $$s2"))
(define (string-ref s i) (define (string-ref s i)
(string->es "$$s[$$i] || $$error(`value out of range: ${$$i}`)")) (string->es "$$s[$$i] || $$error(`value out of range: ${$$i}`)"))
(define (string-append) (define (string-append . xs)
(let ((args (es:arg->arr (string->es "arguments")))) (string->es "$$xs.join('')"))
(string->es "$$args.join('')")))
(define (eq? x y) (define (eq? x y)
(string->es "$$x === $$y")) (string->es "$$x === $$y"))
;; R7RS math ;; R7RS math
(define (+) (define (+ . xs)
(let ((args (es:arg->arr (string->es "arguments")))) (fold (lambda (y x)
(fold (lambda (y x) (string->es "$$x + $$y"))
(string->es "$$x + $$y")) 0
0 xs))
args))) (define (- . xs)
(define (-) (fold (lambda (y x)
(let ((args (es:arg->arr (string->es "arguments")))) (string->es "$$x - $$y"))
(fold (lambda (y x) (car xs)
(string->es "$$x - $$y")) (cdr xs)))
(car args)
(cdr args))))
(define (zero? x) (define (zero? x)
(eq? x 0)) (eq? x 0))
@ -336,14 +332,9 @@
(string->es "$$xs.reduce((prev, x) => $$f(x, prev), $$init)")) (string->es "$$xs.reduce((prev, x) => $$f(x, prev), $$init)"))
;; warning: map here uses the length of the first list, not the shortest ;; warning: map here uses the length of the first list, not the shortest
;; (we implement this in ES for now so that we don't have to augment (define (map f . xs)
;; Prebirth Lisp to support the "rest" procedure definition syntax) (string->es
(define (map f) "$$xs[0].map((_, i) => $$f.apply(null, $$xs.map(x => x[i])))"))
(string->es "__a = arguments") ; because let introduces a function
(let* ((args (es:arg->arr (string->es "__a")))
(xs (cdr args)))
(string->es
"$$xs[0].map((_, i) => $$f.apply(null, $$xs.map(x => x[i])))")))
(define (es:regexp s opts) (define (es:regexp s opts)
(string->es "new RegExp($$s, $$opts)")) (string->es "new RegExp($$s, $$opts)"))