1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-02 07:40:30 +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:
Phil 2011-05-07 16:15:11 -05:00 committed by Ian Price
parent faa16f9989
commit f4c44a3ba7
9 changed files with 130 additions and 46 deletions

View file

@ -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

View file

@ -5,17 +5,32 @@ This is an org-mode todo list of stuff that needs to be done for Guile Lua.
CLOSED: [2011-04-19 Tue 19:36]
** DONE Standard library functions: math.modf, math.fmod
CLOSED: [2011-04-21 Thu 15:43]
** TODO Variable arguments and multiple returns
** TODO Assignment cannot be naive left-to-right
a,b = b,a should work correctly
** STARTED Multiple values
What's the deal? In Lua, the rightmost expression in a
comma-delimited list (such as in a function application, or the
right-hand side of an assignment) may result in multiple values.
** TODO Variable arguments
** TODO Function environments (getfenv and setfenv)
** TODO Use prompt and abort instead of throw and catch
** TODO Standard library function: module
** TODO Standard library function: table.sort
** TODO Get the official Lua 5.1 test suite running
** TODO Lua working at the REPL
** TODO Document some stuff
* Eh
** TODO Standard library function: math.frexp
Pending some additions to Guile's numeric tower.
** TODO Use module binders
** TODO Better testing of standard library modules io, os
** TODO Function environments (getfenv and setfenv)
** TODO compile-tree-il.scm should be rewritten
Right now it's a jungle of tree-il constructors. There's a lot of
boilerplate code that could be made much nicer using macros and
parse-tree-il.
* Differences
Here are some difference in Guile Lua's behavior that should not cause

View file

@ -351,7 +351,7 @@
(enforce-next! #\))
;; finished
save))
(else (syntax-error (get-source-info) "unexpected symbol ~a" token))))
(else (syntax-error (get-source-info) "unexpected token ~a" token))))
;; index -> '[' expression ']'
(define (index)
@ -598,7 +598,6 @@
;; FIXME: does a left-to-right assignment, so x, y = y, x probably
;; doesn't work. Also does not appear to handle the x, y = foo() case.
;;
(define (parse-assignment src left right)
;; and then parses it, branching to handle overflows on either side if necessary
(make-ast-sequence

View file

@ -332,10 +332,7 @@
(runtime-error "~a" (if (null? opts) "assertion failed" (car opts)))))
;; NOTE: collectgarbage cannot be fully implemented because it expects
;; an incremental garbage collector that matches lua's interface; libgc
;; can be incremental but i don't think we can turn that on from guile
;; currently, and even if we could i'm not sure that libgc exposes what
;; lua wants
;; an incremental garbage collector that matches lua's interface
(define-global collectgarbage
(lambda* (opt #:optional (arg #nil))
(define (ignore) (runtime-warning "collectgarbage cannot respect command ~a" opt))