mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-08 05:27:33 +02:00
Merge branch 'foreign-dev'
This commit is contained in:
commit
8a115df516
7 changed files with 494 additions and 59 deletions
2
Makefile
2
Makefile
|
@ -78,6 +78,7 @@ install : libs install-libs install-includes install-bin
|
||||||
$(INSTALL) -m0644 scheme/cyclone/*.scm $(DESTDIR)$(DATADIR)/scheme/cyclone
|
$(INSTALL) -m0644 scheme/cyclone/*.scm $(DESTDIR)$(DATADIR)/scheme/cyclone
|
||||||
$(INSTALL) -m0644 libs/cyclone/test.meta $(DESTDIR)$(DATADIR)/cyclone
|
$(INSTALL) -m0644 libs/cyclone/test.meta $(DESTDIR)$(DATADIR)/cyclone
|
||||||
$(INSTALL) -m0644 libs/cyclone/match.meta $(DESTDIR)$(DATADIR)/cyclone
|
$(INSTALL) -m0644 libs/cyclone/match.meta $(DESTDIR)$(DATADIR)/cyclone
|
||||||
|
$(INSTALL) -m0644 libs/cyclone/foreign.meta $(DESTDIR)$(DATADIR)/cyclone
|
||||||
$(INSTALL) -m0644 scheme/cyclone/*.o $(DESTDIR)$(DATADIR)/scheme/cyclone
|
$(INSTALL) -m0644 scheme/cyclone/*.o $(DESTDIR)$(DATADIR)/scheme/cyclone
|
||||||
$(INSTALL) -m0755 scheme/cyclone/*.so $(DESTDIR)$(DATADIR)/scheme/cyclone
|
$(INSTALL) -m0755 scheme/cyclone/*.so $(DESTDIR)$(DATADIR)/scheme/cyclone
|
||||||
$(INSTALL) -m0644 libs/cyclone/*.sld $(DESTDIR)$(DATADIR)/cyclone
|
$(INSTALL) -m0644 libs/cyclone/*.sld $(DESTDIR)$(DATADIR)/cyclone
|
||||||
|
@ -271,6 +272,7 @@ bootstrap : icyc libs
|
||||||
cp scheme/cyclone/macros.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
cp scheme/cyclone/macros.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
||||||
cp libs/cyclone/match.c $(BOOTSTRAP_DIR)/cyclone
|
cp libs/cyclone/match.c $(BOOTSTRAP_DIR)/cyclone
|
||||||
cp libs/cyclone/match.meta $(BOOTSTRAP_DIR)/cyclone
|
cp libs/cyclone/match.meta $(BOOTSTRAP_DIR)/cyclone
|
||||||
|
cp libs/cyclone/foreign.meta $(BOOTSTRAP_DIR)/cyclone
|
||||||
cp scheme/cyclone/pretty-print.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
cp scheme/cyclone/pretty-print.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
||||||
cp scheme/cyclone/primitives.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
cp scheme/cyclone/primitives.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
||||||
cp scheme/cyclone/transforms.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
cp scheme/cyclone/transforms.c $(BOOTSTRAP_DIR)/scheme/cyclone
|
||||||
|
|
|
@ -57,6 +57,7 @@ Cyclone supports the following [Scheme Requests for Implementation (SRFI)](http:
|
||||||
These libraries are provided as Cyclone-specific extensions:
|
These libraries are provided as Cyclone-specific extensions:
|
||||||
|
|
||||||
- [`cyclone concurrent`](api/cyclone/concurrent.md) - A helper library for writing concurrent code.
|
- [`cyclone concurrent`](api/cyclone/concurrent.md) - A helper library for writing concurrent code.
|
||||||
|
- [`cyclone foreign`](api/cyclone/foreign.md) - Provides a convenient interface for integrating with C code.
|
||||||
- [`cyclone match`](api/cyclone/match.md) - A hygienic pattern matcher based on Alex Shinn's portable `match.scm`.
|
- [`cyclone match`](api/cyclone/match.md) - A hygienic pattern matcher based on Alex Shinn's portable `match.scm`.
|
||||||
- [`cyclone test`](api/cyclone/test.md) - A unit testing framework ported from `(chibi test)`.
|
- [`cyclone test`](api/cyclone/test.md) - A unit testing framework ported from `(chibi test)`.
|
||||||
- [`scheme cyclone array-list`](api/scheme/cyclone/array-list.md)
|
- [`scheme cyclone array-list`](api/scheme/cyclone/array-list.md)
|
||||||
|
|
72
docs/api/cyclone/foreign.md
Normal file
72
docs/api/cyclone/foreign.md
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
# Foreign Library
|
||||||
|
|
||||||
|
The `(cyclone foreign)` provides a convenient interface for integrating with C code. It is based in concept on the `(chicken foreign)` module from CHICKEN Scheme. Similarly to that module, this library manipulates the C code directly before it is compiled to a native binary. It is not possible to call these forms at runtime.
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
- [`c-code`](#c-code)
|
||||||
|
- [`c-value`](#c-value)
|
||||||
|
- [`c-define`](#c-define)
|
||||||
|
- [`c-define-type`](#c-define-type)
|
||||||
|
|
||||||
|
## c-code
|
||||||
|
|
||||||
|
*Syntax*
|
||||||
|
|
||||||
|
(c-code CODE ...)
|
||||||
|
|
||||||
|
Insert C code directly into the compiled program. Each `CODE` parameter must be a string containing C code.
|
||||||
|
|
||||||
|
## c-value
|
||||||
|
|
||||||
|
*Syntax*
|
||||||
|
|
||||||
|
(c-value CODE TYPE)
|
||||||
|
|
||||||
|
Generate code that takes the C code specified by the string `CODE` and converts it to a Scheme object of type `TYPE`.
|
||||||
|
|
||||||
|
## c-define
|
||||||
|
|
||||||
|
*Syntax*
|
||||||
|
|
||||||
|
(c-define SCM-FUNC RETURN-TYPE C-FUNC TYPE ...)
|
||||||
|
|
||||||
|
Define a Scheme function `SCM-FUNC` returning an object of type `RETURN-TYPE`. The function will call C function specified by the string `C-FUNC` passed parameters of type specified by any `TYPE` arguments.
|
||||||
|
|
||||||
|
For example, to define a function that calls `strlen`:
|
||||||
|
|
||||||
|
(c-define scm-strlen int "strlen" string)
|
||||||
|
|
||||||
|
Note that these definitions are introduced at the top-level.
|
||||||
|
|
||||||
|
## c-define-type
|
||||||
|
|
||||||
|
*Syntax*
|
||||||
|
|
||||||
|
(c-define-type NAME TYPE (ARG-CONVERT (RET-CONVERT)))
|
||||||
|
|
||||||
|
Define a custom type with symbol `NAME` that is an alias of type `TYPE`. It is also possible to specify conversion functions `ARG-CONVERT` and `RET-CONVERT` to convert to/from this custom type.
|
||||||
|
|
||||||
|
EG, to define a type that consists of integers in Scheme and strings in C:
|
||||||
|
|
||||||
|
(c-define-type string-as-integer string number->string string->number)
|
||||||
|
|
||||||
|
|
||||||
|
# Type Specifiers
|
||||||
|
|
||||||
|
The following built-in specifiers may be used as a `TYPE` for forms in this module.
|
||||||
|
|
||||||
|
Scheme | C
|
||||||
|
------ | -
|
||||||
|
`int` | `int`
|
||||||
|
`integer` | `int`
|
||||||
|
`bool` | `int`
|
||||||
|
`char` | `int`
|
||||||
|
`string` | `char *`
|
||||||
|
`symbol` | `const char *`
|
||||||
|
`bytevector` | `char *`
|
||||||
|
`float` | `double`
|
||||||
|
`double` | `double`
|
||||||
|
`bignum` | `mp_int`
|
||||||
|
`opaque` | `void *`
|
||||||
|
|
282
libs/cyclone/foreign.sld
Normal file
282
libs/cyclone/foreign.sld
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
;;;; Cyclone Scheme
|
||||||
|
;;;; https://github.com/justinethier/cyclone
|
||||||
|
;;;;
|
||||||
|
;;;; Copyright (c) 2014-2019, Justin Ethier
|
||||||
|
;;;; All rights reserved.
|
||||||
|
;;;;
|
||||||
|
;;;; This module makes it easier to interface directly with C code using the FFI.
|
||||||
|
;;;;
|
||||||
|
(define-library (cyclone foreign)
|
||||||
|
(import
|
||||||
|
(scheme base)
|
||||||
|
(scheme eval)
|
||||||
|
(scheme cyclone util)
|
||||||
|
;(scheme write) ;; TODO: debugging only!
|
||||||
|
)
|
||||||
|
(export
|
||||||
|
c-code
|
||||||
|
c-value
|
||||||
|
c-define
|
||||||
|
c->scm
|
||||||
|
scm->c
|
||||||
|
c-define-type
|
||||||
|
)
|
||||||
|
(begin
|
||||||
|
;;
|
||||||
|
;;(eval `(define *foreign-types* (list)))
|
||||||
|
|
||||||
|
;; (c-define-type name type (pack (unpack)))
|
||||||
|
(define-syntax c-define-type
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(let ((name (cadr expr))
|
||||||
|
(type (cddr expr)))
|
||||||
|
;;
|
||||||
|
;; Custom foreign types are all stored within the global environment
|
||||||
|
;; used by `eval` at compile time. We play a few tricks using exception
|
||||||
|
;; handlers to check if variables are defined in that environment.
|
||||||
|
;;
|
||||||
|
(unless (eval '(with-handler (lambda X #f) *foreign-types*))
|
||||||
|
;(write "no foreign type table" (current-error-port))
|
||||||
|
;(newline (current-error-port))
|
||||||
|
(eval `(define *foreign-types* (make-hash-table))))
|
||||||
|
(eval `(hash-table-set! *foreign-types* (quote ,name) (quote ,type)))
|
||||||
|
#f))))
|
||||||
|
|
||||||
|
(define-syntax c-value
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(let* ((code-arg (cadr expr))
|
||||||
|
(type-arg (caddr expr))
|
||||||
|
(c-type (eval `(with-handler
|
||||||
|
(lambda X #f)
|
||||||
|
(hash-table-ref *foreign-types* (quote ,type-arg))
|
||||||
|
)))
|
||||||
|
(c-ret-convert #f)
|
||||||
|
)
|
||||||
|
(when c-type
|
||||||
|
;(write `(defined c type ,c-type) (current-error-port))
|
||||||
|
;(newline (current-error-port))
|
||||||
|
(set! type-arg (car c-type))
|
||||||
|
(if (= 3 (length c-type))
|
||||||
|
(set! c-ret-convert (caddr c-type))))
|
||||||
|
|
||||||
|
;(for-each
|
||||||
|
; (lambda (arg)
|
||||||
|
; (if (not (string? arg))
|
||||||
|
; (error "c-value" "Invalid argument: string expected, received " arg)))
|
||||||
|
; (cdr expr))
|
||||||
|
|
||||||
|
(if c-ret-convert
|
||||||
|
`((lambda () (,c-ret-convert (Cyc-foreign-value ,code-arg ,(symbol->string type-arg)))))
|
||||||
|
`((lambda () (Cyc-foreign-value ,code-arg ,(symbol->string type-arg))))
|
||||||
|
)
|
||||||
|
))))
|
||||||
|
|
||||||
|
(define-syntax c-code
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(for-each
|
||||||
|
(lambda (arg)
|
||||||
|
(if (not (string? arg))
|
||||||
|
(error "c-code" "Invalid argument: string expected, received " arg)))
|
||||||
|
(cdr expr))
|
||||||
|
`(Cyc-foreign-code ,@(cdr expr)))))
|
||||||
|
|
||||||
|
;; Unbox scheme object
|
||||||
|
;;
|
||||||
|
;; scm->c :: string -> symbol -> string
|
||||||
|
;;
|
||||||
|
;; Inputs:
|
||||||
|
;; - code - C variable used to reference the Scheme object
|
||||||
|
;; - type - Data type of the Scheme object
|
||||||
|
;; Returns:
|
||||||
|
;; - C code used to unbox the data
|
||||||
|
;(define (scm->c code type)
|
||||||
|
(define-syntax scm->c
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(let ((code (cadr expr))
|
||||||
|
(type (caddr expr)))
|
||||||
|
`(case ,type
|
||||||
|
((int integer)
|
||||||
|
(string-append "obj_obj2int(" ,code ")"))
|
||||||
|
((double float)
|
||||||
|
(string-append "double_value(" ,code ")"))
|
||||||
|
((bignum bigint)
|
||||||
|
(string-append "bignum_value(" ,code ")"))
|
||||||
|
((bool)
|
||||||
|
(string-append "(" ,code " == boolean_f)"))
|
||||||
|
((char)
|
||||||
|
(string-append "obj_obj2char(" ,code ")"))
|
||||||
|
((string)
|
||||||
|
(string-append "string_str(" ,code ")"))
|
||||||
|
((symbol)
|
||||||
|
(string-append "symbol_desc(" ,code ")"))
|
||||||
|
((bytevector)
|
||||||
|
(string-append "(((bytevector_type *)" ,code ")->data)"))
|
||||||
|
((opaque)
|
||||||
|
(string-append "opaque_ptr(" ,code ")"))
|
||||||
|
(else
|
||||||
|
(error "scm->c unable to convert scheme object of type " ,type)))))))
|
||||||
|
|
||||||
|
;; Box C object, basically the meat of (c-value)
|
||||||
|
;;
|
||||||
|
;; c->scm :: string -> symbol -> string
|
||||||
|
;;
|
||||||
|
;; Inputs:
|
||||||
|
;; - C expression
|
||||||
|
;; - Data type used to box the data
|
||||||
|
;; Returns:
|
||||||
|
;; - Allocation code?
|
||||||
|
;; - C code
|
||||||
|
(define-syntax c->scm
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(let ((code (cadr expr))
|
||||||
|
(type (caddr expr)))
|
||||||
|
`(case (if (string? ,type)
|
||||||
|
(string->symbol ,type)
|
||||||
|
,type)
|
||||||
|
((int integer)
|
||||||
|
(cons
|
||||||
|
""
|
||||||
|
(string-append "obj_int2obj(" ,code ")")))
|
||||||
|
((float double)
|
||||||
|
(let ((var (mangle (gensym 'var))))
|
||||||
|
(cons
|
||||||
|
(string-append
|
||||||
|
"make_double(" var ", " ,code ");")
|
||||||
|
(string-append "&" var)
|
||||||
|
)))
|
||||||
|
((bool)
|
||||||
|
(cons
|
||||||
|
""
|
||||||
|
(string-append "(" ,code " == 0 ? boolean_f : boolean_t)")))
|
||||||
|
((char)
|
||||||
|
(cons
|
||||||
|
""
|
||||||
|
(string-append "obj_char2obj(" ,code ")")))
|
||||||
|
((string)
|
||||||
|
(let ((var (mangle (gensym 'var))))
|
||||||
|
(cons
|
||||||
|
(string-append
|
||||||
|
"make_utf8_string(data," var ", " ,code ");")
|
||||||
|
(string-append "&" var)
|
||||||
|
)))
|
||||||
|
((bytevector)
|
||||||
|
(let ((var (mangle (gensym 'var))))
|
||||||
|
(cons
|
||||||
|
(string-append
|
||||||
|
"make_empty_bytevector(data," var ");"
|
||||||
|
var "->data = " ,code ";")
|
||||||
|
(string-append "&" var)
|
||||||
|
)))
|
||||||
|
((opaque)
|
||||||
|
(let ((var (mangle (gensym 'var))))
|
||||||
|
(cons
|
||||||
|
(string-append
|
||||||
|
"make_c_opaque(data," var ", " ,code ");")
|
||||||
|
(string-append "&" var)
|
||||||
|
)))
|
||||||
|
(else
|
||||||
|
(error "c->scm unable to convert C object of type " ,type)))))))
|
||||||
|
|
||||||
|
(define-syntax c-define
|
||||||
|
(er-macro-transformer
|
||||||
|
(lambda (expr rename compare)
|
||||||
|
(let* ((scm-fnc (cadr expr))
|
||||||
|
(scm-fnc-wrapper (gensym 'scm-fnc))
|
||||||
|
(c-fnc (cadddr expr))
|
||||||
|
(rv-type (caddr expr))
|
||||||
|
;; boolean - Are we returning a custom (user-defined) type?
|
||||||
|
(rv-cust-type (eval `(with-handler
|
||||||
|
(lambda X #f)
|
||||||
|
(hash-table-ref *foreign-types* (quote ,rv-type))
|
||||||
|
)))
|
||||||
|
;; boolean - Does the custom return type have a conversion function?
|
||||||
|
(rv-cust-convert
|
||||||
|
(if (and rv-cust-type (= 3 (length rv-cust-type)))
|
||||||
|
(caddr rv-cust-type)
|
||||||
|
#f))
|
||||||
|
(arg-types (cddddr expr))
|
||||||
|
(arg-cust-convert #f)
|
||||||
|
(arg-syms/unbox
|
||||||
|
(map
|
||||||
|
(lambda (type)
|
||||||
|
(let ((var (mangle (gensym 'arg)))
|
||||||
|
(arg-cust-type (eval `(with-handler
|
||||||
|
(lambda X #f)
|
||||||
|
(hash-table-ref *foreign-types* (quote ,type))
|
||||||
|
)))
|
||||||
|
)
|
||||||
|
(cons
|
||||||
|
var
|
||||||
|
(scm->c
|
||||||
|
var
|
||||||
|
(cond
|
||||||
|
(arg-cust-type
|
||||||
|
(if (> (length arg-cust-type) 1)
|
||||||
|
(set! arg-cust-convert #t))
|
||||||
|
(car arg-cust-type))
|
||||||
|
(else
|
||||||
|
type)))
|
||||||
|
;(string-append "string_str(" var ")")
|
||||||
|
)))
|
||||||
|
arg-types))
|
||||||
|
(returns
|
||||||
|
(c->scm
|
||||||
|
(string-append
|
||||||
|
c-fnc "(" (string-join (map cdr arg-syms/unbox) ",") ")")
|
||||||
|
(if rv-cust-type
|
||||||
|
(car rv-cust-type)
|
||||||
|
rv-type)))
|
||||||
|
(return-alloc (car returns))
|
||||||
|
(return-expr (cdr returns))
|
||||||
|
(args (string-append
|
||||||
|
"(void *data, int argc, closure _, object k "
|
||||||
|
(apply string-append
|
||||||
|
(map
|
||||||
|
(lambda (sym/unbox)
|
||||||
|
(string-append ", object " (car sym/unbox)))
|
||||||
|
arg-syms/unbox))
|
||||||
|
")"))
|
||||||
|
(body
|
||||||
|
(string-append
|
||||||
|
return-alloc
|
||||||
|
"return_closcall1(data, k, " return-expr ");"))
|
||||||
|
)
|
||||||
|
(cond
|
||||||
|
;; If there are any custom type conversion functions we need to create
|
||||||
|
;; a wrapper function in Scheme to perform those conversions
|
||||||
|
((or rv-cust-convert arg-cust-convert)
|
||||||
|
(if (not rv-cust-convert)
|
||||||
|
(set! rv-cust-convert 'begin))
|
||||||
|
(let ((arg-syms
|
||||||
|
(map
|
||||||
|
(lambda (type)
|
||||||
|
(let* ((sym (gensym 'arg))
|
||||||
|
(arg-cust-type (eval `(with-handler
|
||||||
|
(lambda X #f)
|
||||||
|
(hash-table-ref *foreign-types* (quote ,type)))))
|
||||||
|
(pass-arg
|
||||||
|
(if (and arg-cust-type
|
||||||
|
(> (length arg-cust-type) 1))
|
||||||
|
`(,(cadr arg-cust-type) ,sym)
|
||||||
|
sym)) )
|
||||||
|
(cons
|
||||||
|
sym ;; Arg
|
||||||
|
pass-arg)));; Passing arg to internal func
|
||||||
|
arg-types)))
|
||||||
|
`(begin
|
||||||
|
(define-c ,scm-fnc-wrapper ,args ,body)
|
||||||
|
(define (,scm-fnc ,@(map car arg-syms))
|
||||||
|
(,rv-cust-convert
|
||||||
|
(,scm-fnc-wrapper ,@(map cdr arg-syms)))))))
|
||||||
|
;; Simpler case, just define the function directly
|
||||||
|
(else
|
||||||
|
`(define-c ,scm-fnc ,args ,body)))
|
||||||
|
))))
|
||||||
|
|
||||||
|
)
|
||||||
|
)
|
57
libs/test-foreign.scm
Normal file
57
libs/test-foreign.scm
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
;; Unit tests for the (cyclone foreign) module.
|
||||||
|
;;
|
||||||
|
(import
|
||||||
|
(scheme base)
|
||||||
|
(scheme write)
|
||||||
|
(cyclone test)
|
||||||
|
(cyclone foreign)
|
||||||
|
(scheme cyclone util)
|
||||||
|
(scheme cyclone pretty-print)
|
||||||
|
)
|
||||||
|
|
||||||
|
(define *my-global* #f)
|
||||||
|
|
||||||
|
(c-define-type my-string string)
|
||||||
|
(c-define-type my-integer integer)
|
||||||
|
(c-define-type my-integer-as-string integer string->number number->string)
|
||||||
|
(c-define-type string-as-integer string number->string string->number)
|
||||||
|
|
||||||
|
(test-group "foreign value"
|
||||||
|
(test 3 (c-value "1 + 2" integer))
|
||||||
|
(test 4 (c-value "2 + 2" my-integer))
|
||||||
|
(test "4" (c-value "2 + 2" my-integer-as-string))
|
||||||
|
(test "test" (c-value "\"test\"" string))
|
||||||
|
)
|
||||||
|
|
||||||
|
(test-group "foreign code"
|
||||||
|
(test #f *my-global*)
|
||||||
|
(c-code
|
||||||
|
"printf(\"test %d %d \\n\", 1, 2);"
|
||||||
|
"printf(\"test %d %d %d\\n\", 1, 2, 3);"
|
||||||
|
"__glo__85my_91global_85 = boolean_t;")
|
||||||
|
(test #t *my-global*)
|
||||||
|
(set! *my-global* 1)
|
||||||
|
(test 1 *my-global*)
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Must be top-level
|
||||||
|
|
||||||
|
;TODO: support custom types (arg and ret) for c-define.
|
||||||
|
; Also need to be able to support arg/ret convert optional type arguments
|
||||||
|
; Would need to generate scheme wrappers to handle these conversions
|
||||||
|
|
||||||
|
(c-define scm-strlen my-integer "strlen" string)
|
||||||
|
(c-define scm-strlen-str my-integer-as-string "strlen" string)
|
||||||
|
;(c-define scm-strlen "int" "strlen" string)
|
||||||
|
(c-define scm-strlend double "strlen" string)
|
||||||
|
(c-define scm-strlen2 integer "strlen" my-string)
|
||||||
|
(c-define scm-strlen3 integer "strlen" string-as-integer)
|
||||||
|
|
||||||
|
(test-group "foreign lambda"
|
||||||
|
(test 15 (scm-strlen "testing 1, 2, 3"))
|
||||||
|
(test 15 (scm-strlen2 "testing 1, 2, 3"))
|
||||||
|
(test 15.0 (scm-strlend "testing 1, 2, 3"))
|
||||||
|
(test "15" (scm-strlen-str "testing 1, 2, 3"))
|
||||||
|
(test 3 (scm-strlen3 255))
|
||||||
|
)
|
||||||
|
(test-exit)
|
|
@ -13,6 +13,7 @@
|
||||||
(scheme eval)
|
(scheme eval)
|
||||||
(scheme inexact)
|
(scheme inexact)
|
||||||
(scheme write)
|
(scheme write)
|
||||||
|
(cyclone foreign)
|
||||||
(scheme cyclone primitives)
|
(scheme cyclone primitives)
|
||||||
(scheme cyclone transforms)
|
(scheme cyclone transforms)
|
||||||
(scheme cyclone ast)
|
(scheme cyclone ast)
|
||||||
|
@ -283,12 +284,12 @@
|
||||||
;;; Compilation routines.
|
;;; Compilation routines.
|
||||||
|
|
||||||
;; Return generated code that also requests allocation of C variables on stack
|
;; Return generated code that also requests allocation of C variables on stack
|
||||||
(define (c-code/vars str cvars)
|
(define (c:code/vars str cvars)
|
||||||
(list str
|
(list str
|
||||||
cvars))
|
cvars))
|
||||||
|
|
||||||
;; Return generated code with no C variables allocated on the stack
|
;; Return generated code with no C variables allocated on the stack
|
||||||
(define (c-code str) (c-code/vars str (list)))
|
(define (c:code str) (c:code/vars str (list)))
|
||||||
|
|
||||||
;; Append arg count to a C code pair
|
;; Append arg count to a C code pair
|
||||||
(define (c:tuple/args cp num-args)
|
(define (c:tuple/args cp num-args)
|
||||||
|
@ -327,12 +328,12 @@
|
||||||
c-allocs))
|
c-allocs))
|
||||||
|
|
||||||
(define (c:append cp1 cp2)
|
(define (c:append cp1 cp2)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append (c:body cp1) (c:body cp2))
|
(string-append (c:body cp1) (c:body cp2))
|
||||||
(append (c:allocs cp1) (c:allocs cp2))))
|
(append (c:allocs cp1) (c:allocs cp2))))
|
||||||
|
|
||||||
(define (c:append/prefix prefix cp1 cp2)
|
(define (c:append/prefix prefix cp1 cp2)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append prefix (c:body cp1) (c:body cp2))
|
(string-append prefix (c:body cp1) (c:body cp2))
|
||||||
(append (c:allocs cp1) (c:allocs cp2))))
|
(append (c:allocs cp1) (c:allocs cp2))))
|
||||||
|
|
||||||
|
@ -390,7 +391,7 @@
|
||||||
((const? exp) (c-compile-const exp (alloca? ast-id trace) #f)) ;; TODO: OK to hardcode immutable to false here??
|
((const? exp) (c-compile-const exp (alloca? ast-id trace) #f)) ;; TODO: OK to hardcode immutable to false here??
|
||||||
((prim? exp)
|
((prim? exp)
|
||||||
;; TODO: this needs to be more refined, probably w/a lookup table
|
;; TODO: this needs to be more refined, probably w/a lookup table
|
||||||
(c-code (string-append "primitive_" (mangle exp))))
|
(c:code (string-append "primitive_" (mangle exp))))
|
||||||
((ref? exp) (c-compile-ref exp))
|
((ref? exp) (c-compile-ref exp))
|
||||||
((quote? exp) (c-compile-quote exp (alloca? ast-id trace)))
|
((quote? exp) (c-compile-quote exp (alloca? ast-id trace)))
|
||||||
((if? exp) (c-compile-if exp append-preamble cont ast-id trace cps?))
|
((if? exp) (c-compile-if exp append-preamble cont ast-id trace cps?))
|
||||||
|
@ -436,7 +437,7 @@
|
||||||
(num-args 0)
|
(num-args 0)
|
||||||
(create-cons
|
(create-cons
|
||||||
(lambda (cvar a b)
|
(lambda (cvar a b)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append
|
(string-append
|
||||||
c-make-macro "(" cvar "," (c:body a) "," (c:body b) ");"
|
c-make-macro "(" cvar "," (c:body a) "," (c:body b) ");"
|
||||||
(c-set-immutable-field cvar use-alloca immutable))
|
(c-set-immutable-field cvar use-alloca immutable))
|
||||||
|
@ -445,7 +446,7 @@
|
||||||
(lambda (args)
|
(lambda (args)
|
||||||
(cond
|
(cond
|
||||||
((null? args)
|
((null? args)
|
||||||
(c-code "NULL"))
|
(c:code "NULL"))
|
||||||
((not (pair? args))
|
((not (pair? args))
|
||||||
(c-compile-const args use-alloca immutable))
|
(c-compile-const args use-alloca immutable))
|
||||||
(else
|
(else
|
||||||
|
@ -455,7 +456,7 @@
|
||||||
(c-compile-const (car args) use-alloca immutable)
|
(c-compile-const (car args) use-alloca immutable)
|
||||||
(_c-compile-scalars (cdr args)))))
|
(_c-compile-scalars (cdr args)))))
|
||||||
(set! num-args (+ 1 num-args))
|
(set! num-args (+ 1 num-args))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name)
|
(string-append addr-op cvar-name)
|
||||||
(append
|
(append
|
||||||
(c:allocs cell)
|
(c:allocs cell)
|
||||||
|
@ -484,7 +485,7 @@
|
||||||
(let ((idx-code (c-compile-const (vector-ref exp i) use-alloca immutable)))
|
(let ((idx-code (c-compile-const (vector-ref exp i) use-alloca immutable)))
|
||||||
(loop
|
(loop
|
||||||
(+ i 1)
|
(+ i 1)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
;; The vector's C variable
|
;; The vector's C variable
|
||||||
(c:body code)
|
(c:body code)
|
||||||
;; Allocations
|
;; Allocations
|
||||||
|
@ -498,7 +499,7 @@
|
||||||
";"))))))))))
|
";"))))))))))
|
||||||
(cond
|
(cond
|
||||||
((zero? len)
|
((zero? len)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code is just the variable name
|
(string-append addr-op cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate empty vector
|
(list ; Allocate empty vector
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -506,7 +507,7 @@
|
||||||
(c-set-immutable-field cvar-name use-alloca immutable)))))
|
(c-set-immutable-field cvar-name use-alloca immutable)))))
|
||||||
(else
|
(else
|
||||||
(let ((code
|
(let ((code
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code body is just var name
|
(string-append addr-op cvar-name) ; Code body is just var name
|
||||||
(list ; Allocate the vector
|
(list ; Allocate the vector
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -532,7 +533,7 @@
|
||||||
(let ((byte-val (number->string (bytevector-u8-ref exp i))))
|
(let ((byte-val (number->string (bytevector-u8-ref exp i))))
|
||||||
(loop
|
(loop
|
||||||
(+ i 1)
|
(+ i 1)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
;; The bytevector's C variable
|
;; The bytevector's C variable
|
||||||
(c:body code)
|
(c:body code)
|
||||||
;; Allocations
|
;; Allocations
|
||||||
|
@ -545,7 +546,7 @@
|
||||||
";"))))))))))
|
";"))))))))))
|
||||||
(cond
|
(cond
|
||||||
((zero? len)
|
((zero? len)
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code is just the variable name
|
(string-append addr-op cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate empty vector
|
(list ; Allocate empty vector
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -554,7 +555,7 @@
|
||||||
))))
|
))))
|
||||||
(else
|
(else
|
||||||
(let ((code
|
(let ((code
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code body is just var name
|
(string-append addr-op cvar-name) ; Code body is just var name
|
||||||
(list ; Allocate the vector
|
(list ; Allocate the vector
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -572,7 +573,7 @@
|
||||||
(use-alloca
|
(use-alloca
|
||||||
(let ((tmp-name (mangle (gensym 'tmp)))
|
(let ((tmp-name (mangle (gensym 'tmp)))
|
||||||
(blen (number->string (string-byte-length exp))))
|
(blen (number->string (string-byte-length exp))))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append "" cvar-name) ; Code is just the variable name
|
(string-append "" cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate integer on the C stack
|
(list ; Allocate integer on the C stack
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -595,7 +596,7 @@
|
||||||
use-alloca immutable)
|
use-alloca immutable)
|
||||||
)))))
|
)))))
|
||||||
(else
|
(else
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append "&" cvar-name) ; Code is just the variable name
|
(string-append "&" cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate integer on the C stack
|
(list ; Allocate integer on the C stack
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -623,7 +624,7 @@
|
||||||
(define (c-compile-const exp use-alloca immutable)
|
(define (c-compile-const exp use-alloca immutable)
|
||||||
(cond
|
(cond
|
||||||
((null? exp)
|
((null? exp)
|
||||||
(c-code "NULL"))
|
(c:code "NULL"))
|
||||||
((pair? exp)
|
((pair? exp)
|
||||||
(c-compile-scalars exp use-alloca immutable))
|
(c-compile-scalars exp use-alloca immutable))
|
||||||
((vector? exp)
|
((vector? exp)
|
||||||
|
@ -635,7 +636,7 @@
|
||||||
(num2str (cond
|
(num2str (cond
|
||||||
(else
|
(else
|
||||||
(number->string exp)))))
|
(number->string exp)))))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append "" cvar-name) ; Code is just the variable name
|
(string-append "" cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate pointer on the C stack
|
(list ; Allocate pointer on the C stack
|
||||||
(string-append
|
(string-append
|
||||||
|
@ -656,14 +657,14 @@
|
||||||
(inum (num2str (imag-part exp)))
|
(inum (num2str (imag-part exp)))
|
||||||
(addr-op (if use-alloca "" "&"))
|
(addr-op (if use-alloca "" "&"))
|
||||||
(c-make-macro (if use-alloca "alloca_complex_num" "make_complex_num")))
|
(c-make-macro (if use-alloca "alloca_complex_num" "make_complex_num")))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code is just the variable name
|
(string-append addr-op cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate on the C stack
|
(list ; Allocate on the C stack
|
||||||
(string-append
|
(string-append
|
||||||
c-make-macro "(" cvar-name ", " rnum ", " inum ");")))))
|
c-make-macro "(" cvar-name ", " rnum ", " inum ");")))))
|
||||||
((and (integer? exp)
|
((and (integer? exp)
|
||||||
(exact? exp))
|
(exact? exp))
|
||||||
(c-code (string-append "obj_int2obj("
|
(c:code (string-append "obj_int2obj("
|
||||||
(number->string exp) ")")))
|
(number->string exp) ")")))
|
||||||
((real? exp)
|
((real? exp)
|
||||||
(let ((cvar-name (mangle (gensym 'c)))
|
(let ((cvar-name (mangle (gensym 'c)))
|
||||||
|
@ -676,22 +677,22 @@
|
||||||
(number->string exp))))
|
(number->string exp))))
|
||||||
(addr-op (if use-alloca "" "&"))
|
(addr-op (if use-alloca "" "&"))
|
||||||
(c-make-macro (if use-alloca "alloca_double" "make_double")))
|
(c-make-macro (if use-alloca "alloca_double" "make_double")))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append addr-op cvar-name) ; Code is just the variable name
|
(string-append addr-op cvar-name) ; Code is just the variable name
|
||||||
(list ; Allocate on the C stack
|
(list ; Allocate on the C stack
|
||||||
(string-append
|
(string-append
|
||||||
c-make-macro "(" cvar-name ", " num2str ");")))))
|
c-make-macro "(" cvar-name ", " num2str ");")))))
|
||||||
((boolean? exp)
|
((boolean? exp)
|
||||||
(c-code (string-append
|
(c:code (string-append
|
||||||
(if exp "boolean_t" "boolean_f"))))
|
(if exp "boolean_t" "boolean_f"))))
|
||||||
((char? exp)
|
((char? exp)
|
||||||
(c-code (string-append "obj_char2obj("
|
(c:code (string-append "obj_char2obj("
|
||||||
(number->string (char->integer exp)) ")")))
|
(number->string (char->integer exp)) ")")))
|
||||||
((string? exp)
|
((string? exp)
|
||||||
(c-compile-string exp use-alloca immutable))
|
(c-compile-string exp use-alloca immutable))
|
||||||
((symbol? exp)
|
((symbol? exp)
|
||||||
(allocate-symbol exp)
|
(allocate-symbol exp)
|
||||||
(c-code (string-append "quote_" (mangle exp))))
|
(c:code (string-append "quote_" (mangle exp))))
|
||||||
(else
|
(else
|
||||||
(error "unknown constant: " exp))))
|
(error "unknown constant: " exp))))
|
||||||
|
|
||||||
|
@ -783,7 +784,7 @@
|
||||||
(c-var-assign
|
(c-var-assign
|
||||||
(lambda (type)
|
(lambda (type)
|
||||||
(let ((cv-name (mangle (gensym 'c))))
|
(let ((cv-name (mangle (gensym 'c))))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append
|
(string-append
|
||||||
(if (or (prim:cont? p)
|
(if (or (prim:cont? p)
|
||||||
(equal? (prim/c-var-assign p) "object")
|
(equal? (prim/c-var-assign p) "object")
|
||||||
|
@ -830,7 +831,7 @@
|
||||||
;; the logic
|
;; the logic
|
||||||
;;
|
;;
|
||||||
(let ((cv-name (mangle (gensym 'c))))
|
(let ((cv-name (mangle (gensym 'c))))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(if (or (prim:allocates-object? p use-alloca?)
|
(if (or (prim:allocates-object? p use-alloca?)
|
||||||
(prim->c-func-uses-alloca? p use-alloca?))
|
(prim->c-func-uses-alloca? p use-alloca?))
|
||||||
cv-name ; Already a pointer
|
cv-name ; Already a pointer
|
||||||
|
@ -838,7 +839,7 @@
|
||||||
(list
|
(list
|
||||||
(string-append c-func "(" cv-name tdata-comma tdata)))))
|
(string-append c-func "(" cv-name tdata-comma tdata)))))
|
||||||
(else
|
(else
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append c-func "(" tdata tptr-comma tptr)
|
(string-append c-func "(" tdata tptr-comma tptr)
|
||||||
(list tptr-decl))))))
|
(list tptr-decl))))))
|
||||||
|
|
||||||
|
@ -869,7 +870,7 @@
|
||||||
|
|
||||||
;; c-compile-ref : ref-exp -> string
|
;; c-compile-ref : ref-exp -> string
|
||||||
(define (c-compile-ref exp)
|
(define (c-compile-ref exp)
|
||||||
(c-code
|
(c:code
|
||||||
(if (member exp *global-syms*)
|
(if (member exp *global-syms*)
|
||||||
(cgen:mangle-global exp)
|
(cgen:mangle-global exp)
|
||||||
(mangle exp))))
|
(mangle exp))))
|
||||||
|
@ -882,7 +883,7 @@
|
||||||
(lambda (args append-preamble prefix cont)
|
(lambda (args append-preamble prefix cont)
|
||||||
(cond
|
(cond
|
||||||
((not (pair? args))
|
((not (pair? args))
|
||||||
(c-code ""))
|
(c:code ""))
|
||||||
(else
|
(else
|
||||||
;; (trace:debug `(c-compile-args ,(car args)))
|
;; (trace:debug `(c-compile-args ,(car args)))
|
||||||
(let ((cp (c-compile-exp (car args)
|
(let ((cp (c-compile-exp (car args)
|
||||||
|
@ -929,7 +930,7 @@
|
||||||
cps?))
|
cps?))
|
||||||
(num-cargs (c:num-args cgen)))
|
(num-cargs (c:num-args cgen)))
|
||||||
(set-c-call-arity! num-cargs)
|
(set-c-call-arity! num-cargs)
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cgen))
|
(c:allocs->str (c:allocs cgen))
|
||||||
"return_direct" (number->string num-cargs)
|
"return_direct" (number->string num-cargs)
|
||||||
|
@ -978,7 +979,7 @@
|
||||||
parent-args
|
parent-args
|
||||||
cgen-lis))))
|
cgen-lis))))
|
||||||
;;(trace:info `(loop ,args ,(cadr args) ,cgen-lis ,parent-args))
|
;;(trace:info `(loop ,args ,(cadr args) ,cgen-lis ,parent-args))
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
cgen-allocs ; (c:allocs->str (c:allocs cgen))
|
cgen-allocs ; (c:allocs->str (c:allocs cgen))
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -986,6 +987,18 @@
|
||||||
"\n"
|
"\n"
|
||||||
"continue;"))))
|
"continue;"))))
|
||||||
|
|
||||||
|
((eq? 'Cyc-foreign-code fun)
|
||||||
|
(c:code/vars
|
||||||
|
(string-append
|
||||||
|
"")
|
||||||
|
args))
|
||||||
|
|
||||||
|
((eq? 'Cyc-foreign-value fun)
|
||||||
|
(let ((kons (c->scm (car args) (cadr args))))
|
||||||
|
(c:code/vars
|
||||||
|
(cdr kons)
|
||||||
|
(list (car kons)))))
|
||||||
|
|
||||||
((prim? fun)
|
((prim? fun)
|
||||||
(let* ((c-fun
|
(let* ((c-fun
|
||||||
(c-compile-prim fun cont ast-id))
|
(c-compile-prim fun cont ast-id))
|
||||||
|
@ -997,7 +1010,7 @@
|
||||||
(number->string num-args)
|
(number->string num-args)
|
||||||
(if (> num-args 0) "," "")))
|
(if (> num-args 0) "," "")))
|
||||||
(c-args* (if (prim:arg-count? fun)
|
(c-args* (if (prim:arg-count? fun)
|
||||||
(c:append (c-code num-args-str) c-args)
|
(c:append (c:code num-args-str) c-args)
|
||||||
c-args)))
|
c-args)))
|
||||||
;; Emit symbol when mutating global variables, so we can look
|
;; Emit symbol when mutating global variables, so we can look
|
||||||
;; up the cvar
|
;; up the cvar
|
||||||
|
@ -1016,7 +1029,7 @@
|
||||||
|
|
||||||
(if (prim/cvar? fun)
|
(if (prim/cvar? fun)
|
||||||
;; Args need to go with alloc function
|
;; Args need to go with alloc function
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(c:body c-fun)
|
(c:body c-fun)
|
||||||
(append
|
(append
|
||||||
(c:allocs c-args*) ; fun alloc depends upon arg allocs
|
(c:allocs c-args*) ; fun alloc depends upon arg allocs
|
||||||
|
@ -1042,12 +1055,12 @@
|
||||||
(and (prim:udf? fun)
|
(and (prim:udf? fun)
|
||||||
(zero? num-args)))
|
(zero? num-args)))
|
||||||
c-fun
|
c-fun
|
||||||
(c:append c-fun (c-code ", "))))
|
(c:append c-fun (c:code ", "))))
|
||||||
c-args*)
|
c-args*)
|
||||||
(c-code ")")))))
|
(c:code ")")))))
|
||||||
|
|
||||||
((equal? '%closure-ref fun)
|
((equal? '%closure-ref fun)
|
||||||
(c-code (apply string-append (list
|
(c:code (apply string-append (list
|
||||||
(c-compile-closure-element-ref
|
(c-compile-closure-element-ref
|
||||||
ast-id
|
ast-id
|
||||||
(car args)
|
(car args)
|
||||||
|
@ -1069,7 +1082,7 @@
|
||||||
(num-cargs (c:num-args cargs)))
|
(num-cargs (c:num-args cargs)))
|
||||||
(cond
|
(cond
|
||||||
((not cps?)
|
((not cps?)
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1125,7 +1138,7 @@
|
||||||
(string-append " " p " = " tmp "; "))
|
(string-append " " p " = " tmp "; "))
|
||||||
params tmp-params))))
|
params tmp-params))))
|
||||||
;; (trace:error `(JAE ,fun ,ast-id ,params ,args (c:num-args cargs)))
|
;; (trace:error `(JAE ,fun ,ast-id ,params ,args (c:num-args cargs)))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1150,7 +1163,7 @@
|
||||||
(let* ((lid (ast:lambda-id wkf))
|
(let* ((lid (ast:lambda-id wkf))
|
||||||
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid)))
|
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid)))
|
||||||
(c-lambda-fnc-gc-ret-str (string-append "__lambda_gc_ret_" (number->string lid))))
|
(c-lambda-fnc-gc-ret-str (string-append "__lambda_gc_ret_" (number->string lid))))
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1171,7 +1184,7 @@
|
||||||
((and wkf fnc)
|
((and wkf fnc)
|
||||||
(let* ((lid (ast:lambda-id wkf))
|
(let* ((lid (ast:lambda-id wkf))
|
||||||
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid))))
|
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid))))
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1184,7 +1197,7 @@
|
||||||
(c:body cargs)
|
(c:body cargs)
|
||||||
");"))))
|
");"))))
|
||||||
(else
|
(else
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1204,7 +1217,7 @@
|
||||||
(num-cargs (c:num-args cargs)))
|
(num-cargs (c:num-args cargs)))
|
||||||
(cond
|
(cond
|
||||||
((not cps?)
|
((not cps?)
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1224,7 +1237,7 @@
|
||||||
(let* ((lid (ast:lambda-id (closure->lam fun)))
|
(let* ((lid (ast:lambda-id (closure->lam fun)))
|
||||||
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid)))
|
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid)))
|
||||||
(c-lambda-fnc-gc-ret-str (string-append "__lambda_gc_ret_" (number->string lid))))
|
(c-lambda-fnc-gc-ret-str (string-append "__lambda_gc_ret_" (number->string lid))))
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1241,7 +1254,7 @@
|
||||||
((adbf:well-known fnc)
|
((adbf:well-known fnc)
|
||||||
(let* ((lid (ast:lambda-id (closure->lam fun)))
|
(let* ((lid (ast:lambda-id (closure->lam fun)))
|
||||||
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid))))
|
(c-lambda-fnc-str (string-append "__lambda_" (number->string lid))))
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1254,7 +1267,7 @@
|
||||||
(c:body cargs)
|
(c:body cargs)
|
||||||
");"))))
|
");"))))
|
||||||
(else
|
(else
|
||||||
(c-code
|
(c:code
|
||||||
(string-append
|
(string-append
|
||||||
(c:allocs->str (c:allocs cfun) "\n")
|
(c:allocs->str (c:allocs cfun) "\n")
|
||||||
(c:allocs->str (c:allocs cargs) "\n")
|
(c:allocs->str (c:allocs cargs) "\n")
|
||||||
|
@ -1271,25 +1284,25 @@
|
||||||
;; Join expressions; based on c:append
|
;; Join expressions; based on c:append
|
||||||
(let ((cp1 (if (ref? expr)
|
(let ((cp1 (if (ref? expr)
|
||||||
;; Ignore lone ref to avoid C warning
|
;; Ignore lone ref to avoid C warning
|
||||||
(c-code/vars "" '())
|
(c:code/vars "" '())
|
||||||
(c-compile-exp expr append-preamble cont ast-id trace cps?)))
|
(c-compile-exp expr append-preamble cont ast-id trace cps?)))
|
||||||
(cp2 acc))
|
(cp2 acc))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(let ((cp1-body (c:body cp1)))
|
(let ((cp1-body (c:body cp1)))
|
||||||
(if (zero? (string-length cp1-body))
|
(if (zero? (string-length cp1-body))
|
||||||
(c:body cp2) ; Ignore cp1 if necessary
|
(c:body cp2) ; Ignore cp1 if necessary
|
||||||
(string-append cp1-body ";" (c:body cp2))))
|
(string-append cp1-body ";" (c:body cp2))))
|
||||||
(append (c:allocs cp1) (c:allocs cp2)))))
|
(append (c:allocs cp1) (c:allocs cp2)))))
|
||||||
(c-code "")
|
(c:code "")
|
||||||
args)))
|
args)))
|
||||||
exps))
|
exps))
|
||||||
((equal? 'Cyc-local-set! fun)
|
((equal? 'Cyc-local-set! fun)
|
||||||
;:(trace:error `(JAE DEBUG Cyc-local-set ,exp))
|
;:(trace:error `(JAE DEBUG Cyc-local-set ,exp))
|
||||||
(let ((val-exp (c-compile-exp (caddr exp) append-preamble cont ast-id trace cps?)))
|
(let ((val-exp (c-compile-exp (caddr exp) append-preamble cont ast-id trace cps?)))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append (mangle (cadr exp)) " = " (c:body val-exp) ";")
|
(string-append (mangle (cadr exp)) " = " (c:body val-exp) ";")
|
||||||
(c:allocs val-exp)))
|
(c:allocs val-exp)))
|
||||||
;; (c-code (string-append (mangle (cadr exp)) " = " (mangle (caddr exp)) ";"))
|
;; (c:code (string-append (mangle (cadr exp)) " = " (mangle (caddr exp)) ";"))
|
||||||
)
|
)
|
||||||
((equal? 'let fun)
|
((equal? 'let fun)
|
||||||
(let* ((vars/vals (cadr exp))
|
(let* ((vars/vals (cadr exp))
|
||||||
|
@ -1301,14 +1314,14 @@
|
||||||
(let ((cp1 (c-compile-exp (cadr var/val) append-preamble cont ast-id trace cps?))
|
(let ((cp1 (c-compile-exp (cadr var/val) append-preamble cont ast-id trace cps?))
|
||||||
(cp2 acc))
|
(cp2 acc))
|
||||||
(set-use-alloca! #f) ; Revert flag
|
(set-use-alloca! #f) ; Revert flag
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(let ((cp1-body (c:body cp1)))
|
(let ((cp1-body (c:body cp1)))
|
||||||
(string-append cp1-body ";" (c:body cp2)))
|
(string-append cp1-body ";" (c:body cp2)))
|
||||||
(append
|
(append
|
||||||
(list (string-append "object " (mangle (car var/val)) ";"))
|
(list (string-append "object " (mangle (car var/val)) ";"))
|
||||||
(c:allocs cp1)
|
(c:allocs cp1)
|
||||||
(c:allocs cp2)))))
|
(c:allocs cp2)))))
|
||||||
(c-code "")
|
(c:code "")
|
||||||
vars/vals))
|
vars/vals))
|
||||||
(body-exp (c-compile-exp
|
(body-exp (c-compile-exp
|
||||||
body append-preamble cont ast-id trace cps?)))
|
body append-preamble cont ast-id trace cps?)))
|
||||||
|
@ -1324,7 +1337,7 @@
|
||||||
(test (compile (if->condition exp)))
|
(test (compile (if->condition exp)))
|
||||||
(then (compile (if->then exp)))
|
(then (compile (if->then exp)))
|
||||||
(els (compile (if->else exp))))
|
(els (compile (if->else exp))))
|
||||||
(c-code (string-append
|
(c:code (string-append
|
||||||
(c:allocs->str (c:allocs test) " ")
|
(c:allocs->str (c:allocs test) " ")
|
||||||
"if( (boolean_f != "
|
"if( (boolean_f != "
|
||||||
(c:body test)
|
(c:body test)
|
||||||
|
@ -1392,7 +1405,7 @@
|
||||||
#f ; inline, so disable CPS on this pass
|
#f ; inline, so disable CPS on this pass
|
||||||
)))
|
)))
|
||||||
|
|
||||||
(c-code/vars "" (list ""))))
|
(c:code/vars "" (list ""))))
|
||||||
|
|
||||||
(define (c-compile-raw-global-lambda exp append-preamble cont trace . cps?)
|
(define (c-compile-raw-global-lambda exp append-preamble cont trace . cps?)
|
||||||
(let* ((precompiled-sym
|
(let* ((precompiled-sym
|
||||||
|
@ -1434,14 +1447,14 @@
|
||||||
(define->var exp)
|
(define->var exp)
|
||||||
#t ; (lambda? body)
|
#t ; (lambda? body)
|
||||||
(let ((cv-name (mangle (gensym 'c))))
|
(let ((cv-name (mangle (gensym 'c))))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(string-append "&" cv-name)
|
(string-append "&" cv-name)
|
||||||
(list
|
(list
|
||||||
(string-append "mclosure0(" cv-name ", (function_type)__lambda_"
|
(string-append "mclosure0(" cv-name ", (function_type)__lambda_"
|
||||||
(number->string lid) ");" cv-name ".num_args = "
|
(number->string lid) ");" cv-name ".num_args = "
|
||||||
(number->string num-args)
|
(number->string num-args)
|
||||||
";")))))
|
";")))))
|
||||||
(c-code/vars "" (list ""))))
|
(c:code/vars "" (list ""))))
|
||||||
|
|
||||||
;; Symbol compilation
|
;; Symbol compilation
|
||||||
|
|
||||||
|
@ -1642,7 +1655,7 @@
|
||||||
(create-object (lambda ()
|
(create-object (lambda ()
|
||||||
;; JAE - this is fine, now need to handle other side (actually reading the value without a closure obj
|
;; JAE - this is fine, now need to handle other side (actually reading the value without a closure obj
|
||||||
;; (trace:error `(create-object free-vars ,free-vars ,(car free-vars)))
|
;; (trace:error `(create-object free-vars ,free-vars ,(car free-vars)))
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(car free-vars)
|
(car free-vars)
|
||||||
(list))))
|
(list))))
|
||||||
(create-nclosure (lambda ()
|
(create-nclosure (lambda ()
|
||||||
|
@ -1700,7 +1713,7 @@
|
||||||
(use-obj-instead-of-closure?
|
(use-obj-instead-of-closure?
|
||||||
(create-object))
|
(create-object))
|
||||||
(else
|
(else
|
||||||
(c-code/vars
|
(c:code/vars
|
||||||
(if (and use-alloca?
|
(if (and use-alloca?
|
||||||
(> (length free-vars) 0))
|
(> (length free-vars) 0))
|
||||||
cv-name
|
cv-name
|
||||||
|
@ -1806,7 +1819,7 @@
|
||||||
"") ; No varargs, skip
|
"") ; No varargs, skip
|
||||||
(c:serialize
|
(c:serialize
|
||||||
(c:append
|
(c:append
|
||||||
(c-code
|
(c:code
|
||||||
;; Only trace when entering initial defined function
|
;; Only trace when entering initial defined function
|
||||||
(cond
|
(cond
|
||||||
(has-closure?
|
(has-closure?
|
||||||
|
|
|
@ -89,6 +89,8 @@
|
||||||
Cyc-stderr
|
Cyc-stderr
|
||||||
Cyc-list
|
Cyc-list
|
||||||
Cyc-if
|
Cyc-if
|
||||||
|
Cyc-foreign-code
|
||||||
|
Cyc-foreign-value
|
||||||
Cyc-fast-plus
|
Cyc-fast-plus
|
||||||
Cyc-fast-sub
|
Cyc-fast-sub
|
||||||
Cyc-fast-mul
|
Cyc-fast-mul
|
||||||
|
@ -238,6 +240,8 @@
|
||||||
(Cyc-stdin 0 0)
|
(Cyc-stdin 0 0)
|
||||||
(Cyc-stderr 0 0)
|
(Cyc-stderr 0 0)
|
||||||
(Cyc-if 3 3)
|
(Cyc-if 3 3)
|
||||||
|
(Cyc-foreign-code 1 #f)
|
||||||
|
(Cyc-foreign-value 2 2)
|
||||||
(Cyc-fast-plus 2 2)
|
(Cyc-fast-plus 2 2)
|
||||||
(Cyc-fast-sub 2 2)
|
(Cyc-fast-sub 2 2)
|
||||||
(Cyc-fast-mul 2 2)
|
(Cyc-fast-mul 2 2)
|
||||||
|
@ -529,6 +533,8 @@
|
||||||
((eq? p 'Cyc-stderr) "Cyc_stderr")
|
((eq? p 'Cyc-stderr) "Cyc_stderr")
|
||||||
((eq? p 'Cyc-list) "Cyc_list")
|
((eq? p 'Cyc-list) "Cyc_list")
|
||||||
((eq? p 'Cyc-if) "Cyc_if")
|
((eq? p 'Cyc-if) "Cyc_if")
|
||||||
|
((eq? p 'Cyc-foreign-code) "UNDEF")
|
||||||
|
((eq? p 'Cyc-foreign-value) "UNDEF")
|
||||||
((eq? p 'Cyc-fast-plus) "Cyc_fast_sum")
|
((eq? p 'Cyc-fast-plus) "Cyc_fast_sum")
|
||||||
((eq? p 'Cyc-fast-sub) "Cyc_fast_sub")
|
((eq? p 'Cyc-fast-sub) "Cyc_fast_sub")
|
||||||
((eq? p 'Cyc-fast-mul) "Cyc_fast_mul")
|
((eq? p 'Cyc-fast-mul) "Cyc_fast_mul")
|
||||||
|
@ -701,6 +707,8 @@
|
||||||
(or
|
(or
|
||||||
(memq p '(
|
(memq p '(
|
||||||
Cyc-list
|
Cyc-list
|
||||||
|
Cyc-foreign-code
|
||||||
|
Cyc-foreign-value
|
||||||
Cyc-fast-plus
|
Cyc-fast-plus
|
||||||
Cyc-fast-sub
|
Cyc-fast-sub
|
||||||
Cyc-fast-mul
|
Cyc-fast-mul
|
||||||
|
|
Loading…
Add table
Reference in a new issue