mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-05 09:10:18 +02:00
Add some documentation. Function calls now properly handle multiple
values resulting from a function call as the last argument. doc/ref/api-languages.texi: Add a small blurb about Lua. module/language/lua/compile-tree-il.scm: Function calls now properly handle multiple values resulting from a function call as the last argument.
This commit is contained in:
parent
faa16f9989
commit
f4c44a3ba7
9 changed files with 130 additions and 46 deletions
|
@ -20,6 +20,7 @@
|
|||
|
||||
(define-module (language lua compile-tree-il)
|
||||
#:use-module (language tree-il)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-39)
|
||||
#:use-module ((system base syntax) #:select (record-case))
|
||||
#:use-module (rnrs control)
|
||||
|
@ -35,20 +36,45 @@
|
|||
|
||||
|
||||
(define (ref-runtime src name)
|
||||
"Shorthand for referring to a variable in the (language lua runtime) module"
|
||||
(make-module-ref src *runtime-name* name #t))
|
||||
|
||||
(define (make-runtime-application src name arguments)
|
||||
"Apply a function in the (language lua runtime) module"
|
||||
"Shorthand for creating an application of a function in the (language lua runtime) module"
|
||||
(make-application src (ref-runtime src name) arguments))
|
||||
|
||||
(define (make-table-ref src table index)
|
||||
"Shorthand for calling the index function in (language lua runtime)"
|
||||
(make-runtime-application src 'index
|
||||
(list table (if (symbol? index) (make-const src (symbol->string index)) index))))
|
||||
|
||||
(define (make-table-set! src table index exp)
|
||||
"Shorthand for calling the new-index! function in (language lua runtime)"
|
||||
(make-runtime-application src 'new-index!
|
||||
(list table (if (symbol? index) (make-const src (symbol->string index)) index) exp)))
|
||||
|
||||
;; Calling conventions
|
||||
(define* (make-plain-lambda-case src args gensyms body #:optional alternate)
|
||||
(make-lambda-case src args #f #f #f '() (or gensyms args) body alternate))
|
||||
|
||||
(define* (make-plain-lambda src args gensyms body #:optional alternate)
|
||||
(make-lambda src '()
|
||||
(make-plain-lambda-case src args gensyms body alternate)))
|
||||
|
||||
(define (make-arg-ignoring-lambda src body)
|
||||
(make-lambda src '()
|
||||
(make-lambda-case src '() #f '_ #f '() (list (gensym "_"))
|
||||
body #f)))
|
||||
|
||||
(define (make-catch-all-lambda src body rest-gensym)
|
||||
(make-lambda src '()
|
||||
(make-lambda-case src '() #f 'rest #f '() (list rest-gensym)
|
||||
body #f)))
|
||||
|
||||
(define (make-argless-lambda src body)
|
||||
(make-plain-lambda src '() #f body))
|
||||
|
||||
|
||||
;; FIXME: use prompt and abort rather than catch and throw
|
||||
(define (apply-named-lua-function src name get-body)
|
||||
(let* ((name (gensym (string-append " " name)))
|
||||
|
@ -81,24 +107,15 @@
|
|||
(make-application src (make-lexical-ref src loop loop) '())))
|
||||
(make-void src)))))
|
||||
|
||||
;; calling conventions
|
||||
(define* (make-plain-lambda-case src args gensyms body #:optional alternate)
|
||||
(make-lambda-case src args #f #f #f '() (or gensyms args) body alternate))
|
||||
(define (could-result-in-multiple-values? x)
|
||||
(if (not (null? x))
|
||||
(let ((last-expr (last x)))
|
||||
(or (ast-function-call? last-expr) (ast-variable-arguments? last-expr)))
|
||||
#f))
|
||||
|
||||
(define* (make-plain-lambda src args gensyms body #:optional alternate)
|
||||
(make-lambda src '()
|
||||
(make-plain-lambda-case src args gensyms body alternate)))
|
||||
|
||||
(define (make-arg-ignoring-lambda src body)
|
||||
(make-lambda src '()
|
||||
(make-lambda-case src '() #f '_ #f '() (list (gensym "_"))
|
||||
body #f)))
|
||||
|
||||
(define (make-argless-lambda src body)
|
||||
(make-plain-lambda src '() #f body))
|
||||
|
||||
(define (adjust-to-single-value src exp)
|
||||
"adjust an expression so that it only returns one result; the rest are
|
||||
;; TODO REMOVE
|
||||
#;(define (adjust-to-single-value src exp)
|
||||
"Adjust an expression so that it only returns one result; the rest are
|
||||
dropped silently"
|
||||
;; Rely on the truncating behavior of returning multiple values to a
|
||||
;; singly-valued continuation.
|
||||
|
@ -153,12 +170,40 @@ dropped silently"
|
|||
#f))))
|
||||
|
||||
((ast-function-call src operator operands)
|
||||
#| (let* ((proc (compile operator))
|
||||
(args (make-application src (make-primitive-ref src 'list) (map-compile operands)))
|
||||
(app-args (make-application src (make-primitive-ref src 'list) (list proc args)))
|
||||
(app (make-application src (make-primitive-ref src 'apply) (list (make-primitive-ref src 'apply) app-args)))) |#
|
||||
(let* ((proc (compile operator))
|
||||
(app (make-application src proc (map-compile operands))))
|
||||
;; will be #t if the the last expression in the list is a
|
||||
;; function call or variable arguments, which means we need
|
||||
;; to account for #<values>
|
||||
(need-to-apply-multiple-values? (could-result-in-multiple-values? operands))
|
||||
(args (map-compile operands)))
|
||||
(define app
|
||||
(if need-to-apply-multiple-values?
|
||||
;; Get the last function's (the one that could result in
|
||||
;; multiple values) return values using call-with-values
|
||||
;; and a function that takes variable arguments. Then
|
||||
;; append those variable arguments to the rest of the
|
||||
;; expression, and apply the first function to it)
|
||||
(make-application src
|
||||
(make-primitive-ref src 'call-with-values)
|
||||
(list
|
||||
(make-argless-lambda src (make-sequence src (last-pair args)))
|
||||
(let ((rest-gensym (gensym "rest")))
|
||||
(make-catch-all-lambda src
|
||||
(make-application src (make-primitive-ref src 'apply)
|
||||
(list
|
||||
proc
|
||||
(make-application src
|
||||
(make-module-ref src '(srfi srfi-1) 'append! #t)
|
||||
(list
|
||||
(make-application src (make-primitive-ref src 'list) (drop-right args 1))
|
||||
(make-lexical-ref src 'rest rest-gensym)))))
|
||||
rest-gensym))))
|
||||
|
||||
(make-application src proc args)))
|
||||
|
||||
;; If this is function is a global variable, prepend a call to
|
||||
;; check-global-function to make sure it's defined before
|
||||
;; applying it
|
||||
(if (ast-global-ref? operator)
|
||||
(make-sequence
|
||||
src (list
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue