mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
Moved compiler code into sld's
This commit is contained in:
parent
e2d75b8dcd
commit
3825604205
11 changed files with 3356 additions and 3409 deletions
1
Makefile
1
Makefile
|
@ -145,7 +145,6 @@ uninstall:
|
||||||
$(RMDIR) $(DESTDIR)$(DATADIR)
|
$(RMDIR) $(DESTDIR)$(DATADIR)
|
||||||
|
|
||||||
trans:
|
trans:
|
||||||
sudo cp scheme/cyclone/transforms.scm /usr/local/share/cyclone/scheme/cyclone/
|
|
||||||
cyclone scheme/cyclone/transforms.sld
|
cyclone scheme/cyclone/transforms.sld
|
||||||
sudo cp scheme/cyclone/transforms.* /usr/local/share/cyclone/scheme/cyclone/
|
sudo cp scheme/cyclone/transforms.* /usr/local/share/cyclone/scheme/cyclone/
|
||||||
cyclone cyclone.scm
|
cyclone cyclone.scm
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,31 +1 @@
|
||||||
(define *version* "0.0.2 (Pre-release)")
|
#f
|
||||||
|
|
||||||
(define *version-banner*
|
|
||||||
(string-append "
|
|
||||||
:@
|
|
||||||
@@@
|
|
||||||
@@@@:
|
|
||||||
`@@@@@+
|
|
||||||
.@@@+@@@ Cyclone
|
|
||||||
@@ @@ Scheme-to-C compiler
|
|
||||||
,@ https://github.com/justinethier/cyclone
|
|
||||||
'@
|
|
||||||
.@
|
|
||||||
@@ #@ (c) 2014 Justin Ethier
|
|
||||||
`@@@#@@@. Version " *version* "
|
|
||||||
#@@@@@
|
|
||||||
+@@@+
|
|
||||||
@@#
|
|
||||||
`@.
|
|
||||||
|
|
||||||
"))
|
|
||||||
|
|
||||||
(define *c-file-header-comment*
|
|
||||||
(string-append "/**
|
|
||||||
** This file was automatically generated by the Cyclone scheme compiler
|
|
||||||
**
|
|
||||||
** (c) 2014 Justin Ethier
|
|
||||||
** Version " *version* "
|
|
||||||
**
|
|
||||||
**/
|
|
||||||
"))
|
|
||||||
|
|
|
@ -6,4 +6,38 @@
|
||||||
*c-file-header-comment*)
|
*c-file-header-comment*)
|
||||||
(include "common.scm")
|
(include "common.scm")
|
||||||
(begin
|
(begin
|
||||||
(define *Cyc-version-banner* *version-banner*)))
|
(define *Cyc-version-banner* *version-banner*)
|
||||||
|
|
||||||
|
(define *version* "0.0.2 (Pre-release)")
|
||||||
|
|
||||||
|
(define *version-banner*
|
||||||
|
(string-append "
|
||||||
|
:@
|
||||||
|
@@@
|
||||||
|
@@@@:
|
||||||
|
`@@@@@+
|
||||||
|
.@@@+@@@ Cyclone
|
||||||
|
@@ @@ Scheme-to-C compiler
|
||||||
|
,@ https://github.com/justinethier/cyclone
|
||||||
|
'@
|
||||||
|
.@
|
||||||
|
@@ #@ (c) 2014 Justin Ethier
|
||||||
|
`@@@#@@@. Version " *version* "
|
||||||
|
#@@@@@
|
||||||
|
+@@@+
|
||||||
|
@@#
|
||||||
|
`@.
|
||||||
|
|
||||||
|
"))
|
||||||
|
|
||||||
|
(define *c-file-header-comment*
|
||||||
|
(string-append "/**
|
||||||
|
** This file was automatically generated by the Cyclone scheme compiler
|
||||||
|
**
|
||||||
|
** (c) 2014 Justin Ethier
|
||||||
|
** Version " *version* "
|
||||||
|
**
|
||||||
|
**/
|
||||||
|
"))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
|
@ -1,220 +1 @@
|
||||||
;;
|
#f
|
||||||
;; Cyclone Scheme
|
|
||||||
;; Copyright (c) 2014, Justin Ethier
|
|
||||||
;; All rights reserved.
|
|
||||||
;;
|
|
||||||
;; This module implements r7rs libraries. In our compiler, these are used to
|
|
||||||
;; encapsulate C modules.
|
|
||||||
;;
|
|
||||||
;; Initially, this a quicky-and-dirty (for now) implementation of r7rs libraries.
|
|
||||||
;;
|
|
||||||
;; TODO: go through functions and ensure consistent naming conventions.
|
|
||||||
;; probably should also clean up some of the function names, this is
|
|
||||||
;; not a very clean or nice API at the moment.
|
|
||||||
;;
|
|
||||||
|
|
||||||
(define (library? ast)
|
|
||||||
(tagged-list? 'define-library ast))
|
|
||||||
|
|
||||||
(define (lib:name ast) (cadr ast))
|
|
||||||
|
|
||||||
;; Convert name (as list of symbols) to a mangled string
|
|
||||||
(define (lib:name->string name)
|
|
||||||
(apply string-append (map mangle name)))
|
|
||||||
|
|
||||||
;; Convert library name to a unique symbol
|
|
||||||
(define (lib:name->symbol name)
|
|
||||||
(string->symbol
|
|
||||||
(string-append
|
|
||||||
"lib-init:" ;; Maybe make this an optional param? Trying to ensure uniqueness
|
|
||||||
(lib:name->string name))))
|
|
||||||
|
|
||||||
;; Helper function that returns an empty list as a default value
|
|
||||||
(define (lib:result result)
|
|
||||||
(if result result '()))
|
|
||||||
|
|
||||||
;; TODO: most of these below assume 0 or 1 instances of the directive.
|
|
||||||
;; may need to replace some of these later with filter operations to
|
|
||||||
;; support more than 1 instance.
|
|
||||||
(define (lib:exports ast)
|
|
||||||
(lib:result
|
|
||||||
(let ((code (assoc 'export (cddr ast))))
|
|
||||||
(if code (cdr code) #f))))
|
|
||||||
(define (lib:imports ast)
|
|
||||||
(lib:result
|
|
||||||
(let ((code (assoc 'import (cddr ast))))
|
|
||||||
(if code (cdr code) #f))))
|
|
||||||
(define (lib:body ast)
|
|
||||||
(lib:result
|
|
||||||
(let ((code (assoc 'begin (cddr ast))))
|
|
||||||
(if code (cdr code) #f))))
|
|
||||||
(define (lib:includes ast)
|
|
||||||
(map
|
|
||||||
(lambda (inc-lst)
|
|
||||||
(cadr inc-lst))
|
|
||||||
(filter
|
|
||||||
(lambda (code)
|
|
||||||
(tagged-list? 'include code))
|
|
||||||
(cddr ast))))
|
|
||||||
|
|
||||||
;; TODO: include-ci, cond-expand
|
|
||||||
|
|
||||||
;; Resolve library filename given an import.
|
|
||||||
;; Assumes ".sld" file extension if one is not specified.
|
|
||||||
(define (lib:import->filename import . ext)
|
|
||||||
(let* ((file-ext
|
|
||||||
(if (null? ext)
|
|
||||||
".sld"
|
|
||||||
(car ext)))
|
|
||||||
(filename*
|
|
||||||
(string-append
|
|
||||||
(apply
|
|
||||||
string-append
|
|
||||||
(map
|
|
||||||
(lambda (i)
|
|
||||||
(string-append "/" (symbol->string i)))
|
|
||||||
import))
|
|
||||||
file-ext))
|
|
||||||
(filename
|
|
||||||
(substring filename* 1 (string-length filename*))))
|
|
||||||
(if (tagged-list? 'scheme import)
|
|
||||||
(string-append (Cyc-installation-dir 'sld) "/" filename) ;; Built-in library
|
|
||||||
filename)))
|
|
||||||
|
|
||||||
;; Get path to directory that contains the library
|
|
||||||
(define (lib:import->path import)
|
|
||||||
(let* ((import-path (reverse (cdr (reverse import))))
|
|
||||||
(path
|
|
||||||
(apply
|
|
||||||
string-append
|
|
||||||
(map
|
|
||||||
(lambda (i)
|
|
||||||
(string-append (symbol->string i) "/"))
|
|
||||||
import-path))))
|
|
||||||
(if (tagged-list? 'scheme import)
|
|
||||||
(string-append (Cyc-installation-dir 'sld) "/" path) ;; Built-in library
|
|
||||||
path)))
|
|
||||||
|
|
||||||
;; Given a program's import set, resolve each import to its .o file, then
|
|
||||||
;; process each import recursively to get the .o files that each one of those
|
|
||||||
;; libs requires. will probably need to prune duplicates from completed list.
|
|
||||||
;; Longer-term, do we want to look at file timestamps to see if files need to
|
|
||||||
;; be recompiled?
|
|
||||||
;(define (lib:imports->objs imports)
|
|
||||||
; (apply
|
|
||||||
; append
|
|
||||||
; (map
|
|
||||||
; (lambda (i)
|
|
||||||
; (cons
|
|
||||||
; (lib:import->filename i ".o")
|
|
||||||
; (lib:imports->objs (lib:read-imports i))
|
|
||||||
; ))
|
|
||||||
; imports)))
|
|
||||||
|
|
||||||
;; Given a single import from an import-set, open the corresponding
|
|
||||||
;; library file and retrieve the library's import-set.
|
|
||||||
(define (lib:read-imports import)
|
|
||||||
(let* ((dir (lib:import->filename import))
|
|
||||||
(fp (open-input-file dir))
|
|
||||||
(lib (read-all fp))
|
|
||||||
(imports (lib:imports (car lib))))
|
|
||||||
(close-input-port fp)
|
|
||||||
imports))
|
|
||||||
|
|
||||||
;; Read export list for a given import
|
|
||||||
(define (lib:import->export-list import)
|
|
||||||
(let* ((dir (string-append (lib:import->filename import)))
|
|
||||||
(fp (open-input-file dir))
|
|
||||||
(lib (read-all fp))
|
|
||||||
(exports (lib:exports (car lib))))
|
|
||||||
(close-input-port fp)
|
|
||||||
exports))
|
|
||||||
|
|
||||||
;; Take a list of imports and resolve it to the imported vars
|
|
||||||
(define (lib:resolve-imports imports)
|
|
||||||
(apply
|
|
||||||
append
|
|
||||||
(map
|
|
||||||
(lambda (import)
|
|
||||||
(lib:import->export-list import))
|
|
||||||
imports)))
|
|
||||||
|
|
||||||
;; Given an import set, get all dependant import names that are required
|
|
||||||
;; The list of deps is intended to be returned in order, such that the
|
|
||||||
;; libraries can be initialized properly in sequence.
|
|
||||||
(define (lib:get-all-import-deps imports)
|
|
||||||
(letrec ((libraries/deps '())
|
|
||||||
(find-deps!
|
|
||||||
(lambda (import-set)
|
|
||||||
(for-each
|
|
||||||
(lambda (i)
|
|
||||||
(cond
|
|
||||||
;; Prevent cycles by only processing new libraries
|
|
||||||
((not (assoc i libraries/deps))
|
|
||||||
;; Find all dependencies of i (IE, libraries it imports)
|
|
||||||
(let ((deps (lib:read-imports i)))
|
|
||||||
(set! libraries/deps (cons (cons i deps) libraries/deps))
|
|
||||||
(find-deps! deps)
|
|
||||||
))))
|
|
||||||
import-set))))
|
|
||||||
(find-deps! imports)
|
|
||||||
;`((deps ,libraries/deps) ; DEBUG
|
|
||||||
; (result ,(lib:get-dep-list libraries/deps)))
|
|
||||||
(lib:get-dep-list libraries/deps)
|
|
||||||
))
|
|
||||||
|
|
||||||
;; Given a list of alists (library-name . imports), return an ordered
|
|
||||||
;; list of library names such that each lib is encounted after the
|
|
||||||
;; libraries it imports (it's dependencies).
|
|
||||||
(define (lib:get-dep-list libs/deps)
|
|
||||||
; Overall strategy is:
|
|
||||||
; for each library
|
|
||||||
; compute index of result that is after any libs that lib imports
|
|
||||||
; compute index of result that is before any libs that import lib
|
|
||||||
; if there is a 'hole' then insert lib into result in that space
|
|
||||||
; otherwise, throw an error (unfortunate but will identify problems)
|
|
||||||
;
|
|
||||||
; To test, run this from hello directory:
|
|
||||||
; (pp (lib:get-all-import-deps '((scheme base) (scheme eval) (scheme base)
|
|
||||||
; (scheme read) (scheme eval) (libs lib1) (libs lib2))))
|
|
||||||
;
|
|
||||||
(let ((result '()))
|
|
||||||
(for-each
|
|
||||||
(lambda (lib/dep)
|
|
||||||
(cond
|
|
||||||
((null? result)
|
|
||||||
(set! result (cons lib/dep '())))
|
|
||||||
(else
|
|
||||||
(let ((idx-my-imports 0) ; lib must be placed after this
|
|
||||||
(idx-imports-me (length result))) ; lib must be before any libs that import it
|
|
||||||
(define (loop i)
|
|
||||||
(cond
|
|
||||||
((= i (length result))
|
|
||||||
'done)
|
|
||||||
(else
|
|
||||||
;; Does lib import this one?
|
|
||||||
(if (and
|
|
||||||
(> i idx-my-imports)
|
|
||||||
(member (car (list-ref result i)) (cdr lib/dep)))
|
|
||||||
(set! idx-my-imports i))
|
|
||||||
|
|
||||||
;; Does this one import lib?
|
|
||||||
(if (and
|
|
||||||
(< i idx-imports-me)
|
|
||||||
(member (car lib/dep) (cdr (list-ref result i))))
|
|
||||||
(set! idx-imports-me i))
|
|
||||||
|
|
||||||
(loop (+ i 1)))))
|
|
||||||
(loop 0)
|
|
||||||
;(pp `(JAE DEBUG ,result ,lib/dep ,idx-imports-me ,idx-my-imports))
|
|
||||||
(if (<= idx-my-imports idx-imports-me)
|
|
||||||
(list-insert-at! result lib/dep
|
|
||||||
(if (= idx-my-imports idx-imports-me)
|
|
||||||
idx-my-imports
|
|
||||||
(+ 1 idx-my-imports)))
|
|
||||||
(error "Internal error: unable to import library"))))
|
|
||||||
))
|
|
||||||
libs/deps)
|
|
||||||
(map car result)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
;;
|
||||||
|
;; Cyclone Scheme
|
||||||
|
;; Copyright (c) 2014, Justin Ethier
|
||||||
|
;; All rights reserved.
|
||||||
|
;;
|
||||||
|
;; This module implements r7rs libraries. In our compiler, these are used to
|
||||||
|
;; encapsulate C modules.
|
||||||
|
;;
|
||||||
|
;; Initially, this a quicky-and-dirty (for now) implementation of r7rs libraries.
|
||||||
|
;;
|
||||||
|
;; TODO: go through functions and ensure consistent naming conventions.
|
||||||
|
;; probably should also clean up some of the function names, this is
|
||||||
|
;; not a very clean or nice API at the moment.
|
||||||
|
;;
|
||||||
(define-library (scheme cyclone libraries)
|
(define-library (scheme cyclone libraries)
|
||||||
(import (scheme base)
|
(import (scheme base)
|
||||||
(scheme read)
|
(scheme read)
|
||||||
|
@ -21,7 +35,211 @@
|
||||||
lib:get-all-import-deps
|
lib:get-all-import-deps
|
||||||
lib:get-dep-list
|
lib:get-dep-list
|
||||||
)
|
)
|
||||||
(include "libraries.scm")
|
(begin
|
||||||
;(begin
|
; (define read cyc-read)
|
||||||
; (define read cyc-read))
|
|
||||||
)
|
(define (library? ast)
|
||||||
|
(tagged-list? 'define-library ast))
|
||||||
|
|
||||||
|
(define (lib:name ast) (cadr ast))
|
||||||
|
|
||||||
|
;; Convert name (as list of symbols) to a mangled string
|
||||||
|
(define (lib:name->string name)
|
||||||
|
(apply string-append (map mangle name)))
|
||||||
|
|
||||||
|
;; Convert library name to a unique symbol
|
||||||
|
(define (lib:name->symbol name)
|
||||||
|
(string->symbol
|
||||||
|
(string-append
|
||||||
|
"lib-init:" ;; Maybe make this an optional param? Trying to ensure uniqueness
|
||||||
|
(lib:name->string name))))
|
||||||
|
|
||||||
|
;; Helper function that returns an empty list as a default value
|
||||||
|
(define (lib:result result)
|
||||||
|
(if result result '()))
|
||||||
|
|
||||||
|
;; TODO: most of these below assume 0 or 1 instances of the directive.
|
||||||
|
;; may need to replace some of these later with filter operations to
|
||||||
|
;; support more than 1 instance.
|
||||||
|
(define (lib:exports ast)
|
||||||
|
(lib:result
|
||||||
|
(let ((code (assoc 'export (cddr ast))))
|
||||||
|
(if code (cdr code) #f))))
|
||||||
|
(define (lib:imports ast)
|
||||||
|
(lib:result
|
||||||
|
(let ((code (assoc 'import (cddr ast))))
|
||||||
|
(if code (cdr code) #f))))
|
||||||
|
(define (lib:body ast)
|
||||||
|
(lib:result
|
||||||
|
(let ((code (assoc 'begin (cddr ast))))
|
||||||
|
(if code (cdr code) #f))))
|
||||||
|
(define (lib:includes ast)
|
||||||
|
(map
|
||||||
|
(lambda (inc-lst)
|
||||||
|
(cadr inc-lst))
|
||||||
|
(filter
|
||||||
|
(lambda (code)
|
||||||
|
(tagged-list? 'include code))
|
||||||
|
(cddr ast))))
|
||||||
|
|
||||||
|
;; TODO: include-ci, cond-expand
|
||||||
|
|
||||||
|
;; Resolve library filename given an import.
|
||||||
|
;; Assumes ".sld" file extension if one is not specified.
|
||||||
|
(define (lib:import->filename import . ext)
|
||||||
|
(let* ((file-ext
|
||||||
|
(if (null? ext)
|
||||||
|
".sld"
|
||||||
|
(car ext)))
|
||||||
|
(filename*
|
||||||
|
(string-append
|
||||||
|
(apply
|
||||||
|
string-append
|
||||||
|
(map
|
||||||
|
(lambda (i)
|
||||||
|
(string-append "/" (symbol->string i)))
|
||||||
|
import))
|
||||||
|
file-ext))
|
||||||
|
(filename
|
||||||
|
(substring filename* 1 (string-length filename*))))
|
||||||
|
(if (tagged-list? 'scheme import)
|
||||||
|
(string-append (Cyc-installation-dir 'sld) "/" filename) ;; Built-in library
|
||||||
|
filename)))
|
||||||
|
|
||||||
|
;; Get path to directory that contains the library
|
||||||
|
(define (lib:import->path import)
|
||||||
|
(let* ((import-path (reverse (cdr (reverse import))))
|
||||||
|
(path
|
||||||
|
(apply
|
||||||
|
string-append
|
||||||
|
(map
|
||||||
|
(lambda (i)
|
||||||
|
(string-append (symbol->string i) "/"))
|
||||||
|
import-path))))
|
||||||
|
(if (tagged-list? 'scheme import)
|
||||||
|
(string-append (Cyc-installation-dir 'sld) "/" path) ;; Built-in library
|
||||||
|
path)))
|
||||||
|
|
||||||
|
;; Given a program's import set, resolve each import to its .o file, then
|
||||||
|
;; process each import recursively to get the .o files that each one of those
|
||||||
|
;; libs requires. will probably need to prune duplicates from completed list.
|
||||||
|
;; Longer-term, do we want to look at file timestamps to see if files need to
|
||||||
|
;; be recompiled?
|
||||||
|
;(define (lib:imports->objs imports)
|
||||||
|
; (apply
|
||||||
|
; append
|
||||||
|
; (map
|
||||||
|
; (lambda (i)
|
||||||
|
; (cons
|
||||||
|
; (lib:import->filename i ".o")
|
||||||
|
; (lib:imports->objs (lib:read-imports i))
|
||||||
|
; ))
|
||||||
|
; imports)))
|
||||||
|
|
||||||
|
;; Given a single import from an import-set, open the corresponding
|
||||||
|
;; library file and retrieve the library's import-set.
|
||||||
|
(define (lib:read-imports import)
|
||||||
|
(let* ((dir (lib:import->filename import))
|
||||||
|
(fp (open-input-file dir))
|
||||||
|
(lib (read-all fp))
|
||||||
|
(imports (lib:imports (car lib))))
|
||||||
|
(close-input-port fp)
|
||||||
|
imports))
|
||||||
|
|
||||||
|
;; Read export list for a given import
|
||||||
|
(define (lib:import->export-list import)
|
||||||
|
(let* ((dir (string-append (lib:import->filename import)))
|
||||||
|
(fp (open-input-file dir))
|
||||||
|
(lib (read-all fp))
|
||||||
|
(exports (lib:exports (car lib))))
|
||||||
|
(close-input-port fp)
|
||||||
|
exports))
|
||||||
|
|
||||||
|
;; Take a list of imports and resolve it to the imported vars
|
||||||
|
(define (lib:resolve-imports imports)
|
||||||
|
(apply
|
||||||
|
append
|
||||||
|
(map
|
||||||
|
(lambda (import)
|
||||||
|
(lib:import->export-list import))
|
||||||
|
imports)))
|
||||||
|
|
||||||
|
;; Given an import set, get all dependant import names that are required
|
||||||
|
;; The list of deps is intended to be returned in order, such that the
|
||||||
|
;; libraries can be initialized properly in sequence.
|
||||||
|
(define (lib:get-all-import-deps imports)
|
||||||
|
(letrec ((libraries/deps '())
|
||||||
|
(find-deps!
|
||||||
|
(lambda (import-set)
|
||||||
|
(for-each
|
||||||
|
(lambda (i)
|
||||||
|
(cond
|
||||||
|
;; Prevent cycles by only processing new libraries
|
||||||
|
((not (assoc i libraries/deps))
|
||||||
|
;; Find all dependencies of i (IE, libraries it imports)
|
||||||
|
(let ((deps (lib:read-imports i)))
|
||||||
|
(set! libraries/deps (cons (cons i deps) libraries/deps))
|
||||||
|
(find-deps! deps)
|
||||||
|
))))
|
||||||
|
import-set))))
|
||||||
|
(find-deps! imports)
|
||||||
|
;`((deps ,libraries/deps) ; DEBUG
|
||||||
|
; (result ,(lib:get-dep-list libraries/deps)))
|
||||||
|
(lib:get-dep-list libraries/deps)
|
||||||
|
))
|
||||||
|
|
||||||
|
;; Given a list of alists (library-name . imports), return an ordered
|
||||||
|
;; list of library names such that each lib is encounted after the
|
||||||
|
;; libraries it imports (it's dependencies).
|
||||||
|
(define (lib:get-dep-list libs/deps)
|
||||||
|
; Overall strategy is:
|
||||||
|
; for each library
|
||||||
|
; compute index of result that is after any libs that lib imports
|
||||||
|
; compute index of result that is before any libs that import lib
|
||||||
|
; if there is a 'hole' then insert lib into result in that space
|
||||||
|
; otherwise, throw an error (unfortunate but will identify problems)
|
||||||
|
;
|
||||||
|
; To test, run this from hello directory:
|
||||||
|
; (pp (lib:get-all-import-deps '((scheme base) (scheme eval) (scheme base)
|
||||||
|
; (scheme read) (scheme eval) (libs lib1) (libs lib2))))
|
||||||
|
;
|
||||||
|
(let ((result '()))
|
||||||
|
(for-each
|
||||||
|
(lambda (lib/dep)
|
||||||
|
(cond
|
||||||
|
((null? result)
|
||||||
|
(set! result (cons lib/dep '())))
|
||||||
|
(else
|
||||||
|
(let ((idx-my-imports 0) ; lib must be placed after this
|
||||||
|
(idx-imports-me (length result))) ; lib must be before any libs that import it
|
||||||
|
(define (loop i)
|
||||||
|
(cond
|
||||||
|
((= i (length result))
|
||||||
|
'done)
|
||||||
|
(else
|
||||||
|
;; Does lib import this one?
|
||||||
|
(if (and
|
||||||
|
(> i idx-my-imports)
|
||||||
|
(member (car (list-ref result i)) (cdr lib/dep)))
|
||||||
|
(set! idx-my-imports i))
|
||||||
|
|
||||||
|
;; Does this one import lib?
|
||||||
|
(if (and
|
||||||
|
(< i idx-imports-me)
|
||||||
|
(member (car lib/dep) (cdr (list-ref result i))))
|
||||||
|
(set! idx-imports-me i))
|
||||||
|
|
||||||
|
(loop (+ i 1)))))
|
||||||
|
(loop 0)
|
||||||
|
;(pp `(JAE DEBUG ,result ,lib/dep ,idx-imports-me ,idx-my-imports))
|
||||||
|
(if (<= idx-my-imports idx-imports-me)
|
||||||
|
(list-insert-at! result lib/dep
|
||||||
|
(if (= idx-my-imports idx-imports-me)
|
||||||
|
idx-my-imports
|
||||||
|
(+ 1 idx-my-imports)))
|
||||||
|
(error "Internal error: unable to import library"))))
|
||||||
|
))
|
||||||
|
libs/deps)
|
||||||
|
(map car result)))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,112 +1 @@
|
||||||
;;
|
#f
|
||||||
;; Cyclone Scheme
|
|
||||||
;; Copyright (c) 2015, Justin Ethier
|
|
||||||
;; All rights reserved.
|
|
||||||
;;
|
|
||||||
;; This module contains various utility functions.
|
|
||||||
;;
|
|
||||||
|
|
||||||
(define (tagged-list? tag exp)
|
|
||||||
(if (pair? exp)
|
|
||||||
(equal? (car exp) tag)
|
|
||||||
#f))
|
|
||||||
|
|
||||||
; if? : exp -> boolean
|
|
||||||
(define (if? exp)
|
|
||||||
(tagged-list? 'if exp))
|
|
||||||
|
|
||||||
; begin? : exp -> boolean
|
|
||||||
(define (begin? exp)
|
|
||||||
(tagged-list? 'begin exp))
|
|
||||||
|
|
||||||
; lambda? : exp -> boolean
|
|
||||||
(define (lambda? exp)
|
|
||||||
(tagged-list? 'lambda exp))
|
|
||||||
|
|
||||||
; char->natural : char -> natural
|
|
||||||
(define (char->natural c)
|
|
||||||
(let ((i (char->integer c)))
|
|
||||||
(if (< i 0)
|
|
||||||
(* -2 i)
|
|
||||||
(+ (* 2 i) 1))))
|
|
||||||
|
|
||||||
; integer->char-list : integer -> string
|
|
||||||
(define (integer->char-list n)
|
|
||||||
(string->list (number->string n)))
|
|
||||||
|
|
||||||
;; Simplified version of filter from SRFI 1
|
|
||||||
(define (filter pred lis)
|
|
||||||
(letrec ((recur (lambda (lis)
|
|
||||||
(if (null? lis)
|
|
||||||
lis
|
|
||||||
(let ((head (car lis))
|
|
||||||
(tail (cdr lis)))
|
|
||||||
(if (pred head)
|
|
||||||
(let ((new-tail (recur tail)))
|
|
||||||
(if (eq? tail new-tail) lis
|
|
||||||
(cons head new-tail)))
|
|
||||||
(recur tail)))))))
|
|
||||||
(recur lis)))
|
|
||||||
|
|
||||||
;; Based off corresponding SRFI-1 definition
|
|
||||||
(define (delete x lis)
|
|
||||||
(filter (lambda (y) (not (equal? x y))) lis))
|
|
||||||
|
|
||||||
;; Inefficient version based off code from SRFI-1
|
|
||||||
(define (delete-duplicates lis)
|
|
||||||
(define (recur lis) ; ((lis lis))
|
|
||||||
(if (null? lis) lis
|
|
||||||
(let* ((x (car lis))
|
|
||||||
(tail (cdr lis))
|
|
||||||
(new-tail (recur (delete x tail))))
|
|
||||||
(if (eq? tail new-tail) lis (cons x new-tail)))))
|
|
||||||
(recur lis))
|
|
||||||
|
|
||||||
;; Insert obj at index k of list, increasing length of list by one.
|
|
||||||
(define (list-insert-at! lis obj k)
|
|
||||||
(cond
|
|
||||||
((null? lis) (error "list-insert-at!, lis cannot be null"))
|
|
||||||
((and (> k 0) (null? (cdr lis)))
|
|
||||||
(set-cdr! lis (cons obj '())))
|
|
||||||
((zero? k)
|
|
||||||
(let ((old-car (car lis)))
|
|
||||||
(set-car! lis obj)
|
|
||||||
(set-cdr! lis (cons old-car (cdr lis)))))
|
|
||||||
(else
|
|
||||||
(list-insert-at! (cdr lis) obj (- k 1)))))
|
|
||||||
|
|
||||||
|
|
||||||
;; Name-mangling.
|
|
||||||
|
|
||||||
;; We have to "mangle" Scheme identifiers into
|
|
||||||
;; C-compatible identifiers, because names like
|
|
||||||
;; foo-bar/baz are not identifiers in C.
|
|
||||||
|
|
||||||
; mangle : symbol -> string
|
|
||||||
(define (mangle symbol)
|
|
||||||
(letrec
|
|
||||||
((m (lambda (chars)
|
|
||||||
(if (null? chars)
|
|
||||||
'()
|
|
||||||
(if (or (and (char-alphabetic? (car chars)) (not (char=? (car chars) #\_)))
|
|
||||||
(char-numeric? (car chars)))
|
|
||||||
(cons (car chars) (m (cdr chars)))
|
|
||||||
(cons #\_ (append (integer->char-list (char->natural (car chars)))
|
|
||||||
(m (cdr chars))))))))
|
|
||||||
(ident (list->string (m (string->list (symbol->string symbol))))))
|
|
||||||
(if (member (string->symbol ident) *c-keywords*)
|
|
||||||
(string-append "_" ident)
|
|
||||||
ident)))
|
|
||||||
|
|
||||||
(define (mangle-global symbol)
|
|
||||||
(string-append "__glo_" (mangle symbol)))
|
|
||||||
|
|
||||||
(define *c-keywords*
|
|
||||||
'(auto _Bool break case char _Complex const continue default do double else
|
|
||||||
enum extern float for goto if _Imaginary inline int long register restrict
|
|
||||||
return short signed sizeof static struct switch typedef union unsigned
|
|
||||||
void volatile while
|
|
||||||
list ;; Not a keyword but reserved type
|
|
||||||
))
|
|
||||||
;; END name mangling section
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
;;
|
||||||
|
;; Cyclone Scheme
|
||||||
|
;; Copyright (c) 2015, Justin Ethier
|
||||||
|
;; All rights reserved.
|
||||||
|
;;
|
||||||
|
;; This module contains various utility functions.
|
||||||
|
;;
|
||||||
(define-library (scheme cyclone util)
|
(define-library (scheme cyclone util)
|
||||||
(import (scheme base)
|
(import (scheme base)
|
||||||
(scheme char))
|
(scheme char))
|
||||||
|
@ -18,8 +25,112 @@
|
||||||
any
|
any
|
||||||
every
|
every
|
||||||
filter)
|
filter)
|
||||||
(include "util.scm")
|
|
||||||
(begin
|
(begin
|
||||||
|
|
||||||
|
(define (tagged-list? tag exp)
|
||||||
|
(if (pair? exp)
|
||||||
|
(equal? (car exp) tag)
|
||||||
|
#f))
|
||||||
|
|
||||||
|
; if? : exp -> boolean
|
||||||
|
(define (if? exp)
|
||||||
|
(tagged-list? 'if exp))
|
||||||
|
|
||||||
|
; begin? : exp -> boolean
|
||||||
|
(define (begin? exp)
|
||||||
|
(tagged-list? 'begin exp))
|
||||||
|
|
||||||
|
; lambda? : exp -> boolean
|
||||||
|
(define (lambda? exp)
|
||||||
|
(tagged-list? 'lambda exp))
|
||||||
|
|
||||||
|
; char->natural : char -> natural
|
||||||
|
(define (char->natural c)
|
||||||
|
(let ((i (char->integer c)))
|
||||||
|
(if (< i 0)
|
||||||
|
(* -2 i)
|
||||||
|
(+ (* 2 i) 1))))
|
||||||
|
|
||||||
|
; integer->char-list : integer -> string
|
||||||
|
(define (integer->char-list n)
|
||||||
|
(string->list (number->string n)))
|
||||||
|
|
||||||
|
;; Simplified version of filter from SRFI 1
|
||||||
|
(define (filter pred lis)
|
||||||
|
(letrec ((recur (lambda (lis)
|
||||||
|
(if (null? lis)
|
||||||
|
lis
|
||||||
|
(let ((head (car lis))
|
||||||
|
(tail (cdr lis)))
|
||||||
|
(if (pred head)
|
||||||
|
(let ((new-tail (recur tail)))
|
||||||
|
(if (eq? tail new-tail) lis
|
||||||
|
(cons head new-tail)))
|
||||||
|
(recur tail)))))))
|
||||||
|
(recur lis)))
|
||||||
|
|
||||||
|
;; Based off corresponding SRFI-1 definition
|
||||||
|
(define (delete x lis)
|
||||||
|
(filter (lambda (y) (not (equal? x y))) lis))
|
||||||
|
|
||||||
|
;; Inefficient version based off code from SRFI-1
|
||||||
|
(define (delete-duplicates lis)
|
||||||
|
(define (recur lis) ; ((lis lis))
|
||||||
|
(if (null? lis) lis
|
||||||
|
(let* ((x (car lis))
|
||||||
|
(tail (cdr lis))
|
||||||
|
(new-tail (recur (delete x tail))))
|
||||||
|
(if (eq? tail new-tail) lis (cons x new-tail)))))
|
||||||
|
(recur lis))
|
||||||
|
|
||||||
|
;; Insert obj at index k of list, increasing length of list by one.
|
||||||
|
(define (list-insert-at! lis obj k)
|
||||||
|
(cond
|
||||||
|
((null? lis) (error "list-insert-at!, lis cannot be null"))
|
||||||
|
((and (> k 0) (null? (cdr lis)))
|
||||||
|
(set-cdr! lis (cons obj '())))
|
||||||
|
((zero? k)
|
||||||
|
(let ((old-car (car lis)))
|
||||||
|
(set-car! lis obj)
|
||||||
|
(set-cdr! lis (cons old-car (cdr lis)))))
|
||||||
|
(else
|
||||||
|
(list-insert-at! (cdr lis) obj (- k 1)))))
|
||||||
|
|
||||||
|
|
||||||
|
;; Name-mangling.
|
||||||
|
|
||||||
|
;; We have to "mangle" Scheme identifiers into
|
||||||
|
;; C-compatible identifiers, because names like
|
||||||
|
;; foo-bar/baz are not identifiers in C.
|
||||||
|
|
||||||
|
; mangle : symbol -> string
|
||||||
|
(define (mangle symbol)
|
||||||
|
(letrec
|
||||||
|
((m (lambda (chars)
|
||||||
|
(if (null? chars)
|
||||||
|
'()
|
||||||
|
(if (or (and (char-alphabetic? (car chars)) (not (char=? (car chars) #\_)))
|
||||||
|
(char-numeric? (car chars)))
|
||||||
|
(cons (car chars) (m (cdr chars)))
|
||||||
|
(cons #\_ (append (integer->char-list (char->natural (car chars)))
|
||||||
|
(m (cdr chars))))))))
|
||||||
|
(ident (list->string (m (string->list (symbol->string symbol))))))
|
||||||
|
(if (member (string->symbol ident) *c-keywords*)
|
||||||
|
(string-append "_" ident)
|
||||||
|
ident)))
|
||||||
|
|
||||||
|
(define (mangle-global symbol)
|
||||||
|
(string-append "__glo_" (mangle symbol)))
|
||||||
|
|
||||||
|
(define *c-keywords*
|
||||||
|
'(auto _Bool break case char _Complex const continue default do double else
|
||||||
|
enum extern float for goto if _Imaginary inline int long register restrict
|
||||||
|
return short signed sizeof static struct switch typedef union unsigned
|
||||||
|
void volatile while
|
||||||
|
list ;; Not a keyword but reserved type
|
||||||
|
))
|
||||||
|
;; END name mangling section
|
||||||
|
|
||||||
;; Simplified versions of every/any from SRFI-1
|
;; Simplified versions of every/any from SRFI-1
|
||||||
(define (any pred lst)
|
(define (any pred lst)
|
||||||
(let any* ((l (map pred lst)))
|
(let any* ((l (map pred lst)))
|
||||||
|
@ -36,4 +147,5 @@
|
||||||
(every* (cdr l)))
|
(every* (cdr l)))
|
||||||
(else
|
(else
|
||||||
#f))))
|
#f))))
|
||||||
|
|
||||||
))
|
))
|
||||||
|
|
Loading…
Add table
Reference in a new issue