[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 20/99: Implement keyword argument parsing
From: |
Christopher Allan Webber |
Subject: |
[Guile-commits] 20/99: Implement keyword argument parsing |
Date: |
Sun, 10 Oct 2021 21:50:46 -0400 (EDT) |
cwebber pushed a commit to branch compile-to-js-merge
in repository guile.
commit e84f8394633339284953d7e54fe3cd5018d2e160
Author: Ian Price <ianprice90@googlemail.com>
AuthorDate: Sat Jun 13 22:41:37 2015 +0100
Implement keyword argument parsing
---
module/language/cps/compile-js.scm | 14 ++++-----
module/language/js-il.scm | 6 ++--
module/language/js-il/compile-javascript.scm | 45 ++++++++++++++++++++++++----
module/language/js-il/runtime.js | 20 +++++++++++++
4 files changed, 69 insertions(+), 16 deletions(-)
diff --git a/module/language/cps/compile-js.scm
b/module/language/cps/compile-js.scm
index 1e36aec..8bffa97 100644
--- a/module/language/cps/compile-js.scm
+++ b/module/language/cps/compile-js.scm
@@ -47,21 +47,21 @@
(define (extract-clauses self clause)
(let loop ((clause clause) (specs '()) (clauses '()))
(match clause
- (($ $cont k ($ $kclause ($ $arity req opts rest _ _) _ #f))
- (values (reverse (cons (cons (make-params self req opts rest) k) specs))
+ (($ $cont k ($ $kclause ($ $arity req opts rest kw allow-other-keys?) _
#f))
+ (values (reverse (cons (cons (make-params self req opts rest kw
allow-other-keys?) k) specs))
(reverse (cons clause clauses))))
- (($ $cont k ($ $kclause ($ $arity req opts rest _ _) _ alternate))
+ (($ $cont k ($ $kclause ($ $arity req opts rest kw allow-other-keys?) _
alternate))
(loop alternate
- (cons (cons (make-params self req opts rest) k) specs)
+ (cons (cons (make-params self req opts rest kw allow-other-keys?)
k) specs)
(cons clause clauses))))))
(define (compile-clause clause self tail)
(match clause
- (($ $cont k ($ $kclause ($ $arity req opt rest _) body _))
+ (($ $cont k ($ $kclause ($ $arity req opt rest ((_ _ kw-syms) ...) _) body
_))
(make-var
k
(make-continuation
- (append (list self) req opt (if rest (list rest) '()))
+ (append (list self) req opt kw-syms (if rest (list rest) '()))
(match body
(($ $cont k ($ $kargs () () exp))
(compile-term exp))
@@ -69,7 +69,7 @@
(make-local (list (compile-cont body))
(make-continue
k
- (map make-id (append req opt (if rest (list rest)
'()))))))))))))
+ (map make-id (append req opt kw-syms (if rest (list
rest) '()))))))))))))
(define (not-supported msg clause)
(error 'not-supported msg clause))
diff --git a/module/language/js-il.scm b/module/language/js-il.scm
index acaeb5a..3415cd9 100644
--- a/module/language/js-il.scm
+++ b/module/language/js-il.scm
@@ -52,7 +52,7 @@
(define-js-type program entry body)
(define-js-type function params body)
(define-js-type jump-table spec)
-(define-js-type params self req opt rest)
+(define-js-type params self req opt rest kw allow-other-keys?)
(define-js-type continuation params body)
(define-js-type local bindings body) ; local scope
(define-js-type var id exp)
@@ -77,8 +77,8 @@
`(jump-table ,@(map (lambda (p)
`(,(unparse-js (car p)) . ,(cdr p)))
body)))
- (($ params self req opt rest)
- `(params ,self ,req ,opt ,rest))
+ (($ params self req opt rest kw allow-other-keys?)
+ `(params ,self ,req ,opt ,rest ,kw ,allow-other-keys?))
(($ local bindings body)
`(local ,(map unparse-js bindings) ,(unparse-js body)))
(($ var id exp)
diff --git a/module/language/js-il/compile-javascript.scm
b/module/language/js-il/compile-javascript.scm
index ca7cca5..27f91ad 100644
--- a/module/language/js-il/compile-javascript.scm
+++ b/module/language/js-il/compile-javascript.scm
@@ -21,6 +21,7 @@
(values exp env env))
(define *scheme* (make-id "scheme"))
+(define *utils* (make-refine *scheme* (make-const "utils")))
(define (name->id name)
(make-id (rename name)))
@@ -85,6 +86,18 @@
opts
(iota (length opts))))
+(define (bind-kw-args kws ids num-drop)
+ (define lookup (make-refine *utils* (make-const "keyword_ref")))
+ (map (lambda (kw id)
+ (make-var (rename id)
+ (make-call lookup
+ (list (compile-const kw)
+ (make-id "arguments")
+ (compile-const num-drop)
+ (make-refine *scheme* (make-const
"UNDEFINED"))))))
+ kws
+ ids))
+
(define (compile-exp exp)
;; TODO: handle ids for js
@@ -149,17 +162,17 @@
(define offset 2) ; closure & continuation
(define (compile-test params)
(match params
- (($ il:params self req '() #f)
+ (($ il:params self req '() #f '() #f)
(make-binop '=
(make-refine (make-id "arguments")
(make-const "length"))
(make-const (+ offset (length req)))))
- (($ il:params self req '() rest)
+ (($ il:params self req '() rest '() #f)
(make-binop '>=
(make-refine (make-id "arguments")
(make-const "length"))
(make-const (+ offset (length req)))))
- (($ il:params self req opts #f)
+ (($ il:params self req opts #f '() #f)
(make-binop 'and
(make-binop '<=
(make-const (+ offset (length req)))
@@ -169,10 +182,16 @@
(make-refine (make-id "arguments")
(make-const "length"))
(make-const (+ offset (length req) (length
opts))))))
+ ;; FIXME: need to handle allow-other-keys? and testing for actual
keywords
+ (($ il:params self req opts #f kwargs _)
+ (make-binop '<=
+ (make-const (+ offset (length req)))
+ (make-refine (make-id "arguments")
+ (make-const "length"))))
))
(define (compile-jump params k)
(match params
- (($ il:params self req '() #f)
+ (($ il:params self req '() #f '() #f)
(list
(make-return
(make-call (name->id k)
@@ -181,7 +200,7 @@
(make-refine (make-id "arguments")
(make-const (+ offset idx))))
(iota (length req))))))))
- (($ il:params self req '() rest)
+ (($ il:params self req '() rest '() #f)
(list
(bind-rest-args rest (+ offset (length req)))
(make-return
@@ -192,7 +211,7 @@
(make-const (+ offset idx))))
(iota (length req)))
(list (name->id rest)))))))
- (($ il:params self req opts #f)
+ (($ il:params self req opts #f '() #f)
(append
(bind-opt-args opts (+ offset (length req)))
(list
@@ -204,6 +223,20 @@
(make-const (+ offset idx))))
(iota (length req)))
(map name->id opts)))))))
+ (($ il:params self req opts #f ((kws names ids) ...) _)
+ (append
+ (bind-opt-args opts (+ offset (length req)))
+ (bind-kw-args kws names (+ offset (length req)))
+ (list
+ (make-return
+ (make-call (name->id k)
+ (append (list (name->id self))
+ (map (lambda (idx)
+ (make-refine (make-id "arguments")
+ (make-const (+ offset idx))))
+ (iota (length req)))
+ (map name->id opts)
+ (map name->id names)))))))
))
(fold-right (lambda (a d)
(make-branch (compile-test (car a))
diff --git a/module/language/js-il/runtime.js b/module/language/js-il/runtime.js
index 6569cbe..688974e 100644
--- a/module/language/js-il/runtime.js
+++ b/module/language/js-il/runtime.js
@@ -1,6 +1,7 @@
var scheme = {
obarray : {},
primitives : {},
+ utils : {},
env : {},
cache: [],
builtins: [],
@@ -117,6 +118,25 @@ scheme.Keyword = function(s) {
return this;
};
+scheme.utils.keyword_ref = function(kw, args, start, dflt) {
+ var l = args.length;
+
+ if ((l - start) % 2 == 1) {
+ // FIXME: should error
+ return undefined;
+ }
+ // Need to loop in reverse because last matching keyword wins
+ for (var i = l - 2; i >= start; i -= 2) {
+ if (!(args[i] instanceof scheme.Keyword)) {
+ return undefined;
+ }
+ if (args[i].name === kw.name) {
+ return args[i + 1];
+ }
+ }
+ return dflt;
+};
+
// Vectors
scheme.Vector = function () {
this.array = Array.prototype.slice.call(arguments);
- [Guile-commits] 09/99: get rid of unused match case, (continued)
- [Guile-commits] 09/99: get rid of unused match case, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 03/99: Remove jscall type, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 04/99: fix makefile, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 05/99: separate js-il functions into actual functions and those for continuations, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 06/99: Get rid of comments and dead branches, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 07/99: Simple inlining of immediate calls, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 08/99: conditional->branch, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 10/99: fix makefile, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 11/99: Compile rest args, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 16/99: Remove superfluous space, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 20/99: Implement keyword argument parsing,
Christopher Allan Webber <=
- [Guile-commits] 12/99: Compile string constants, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 13/99: Mangle js identifiers, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 15/99: Handle case-lambda via a jump table, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 19/99: Simplify output Javascript, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 21/99: Primitives should return Scheme Booleans, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 23/99: Compile cps $prompt form to javascript, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 26/99: abort-to-prompt takes multiple arguments, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 34/99: Change function type representation, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 33/99: Change program type representation, Christopher Allan Webber, 2021/10/10
- [Guile-commits] 31/99: Different types for Continuation and Variable identifiers, Christopher Allan Webber, 2021/10/10