Code generation improvements #7
8
Makefile
8
Makefile
@@ -12,9 +12,9 @@ main.o: main.scm
|
|||||||
%.o: %.scm
|
%.o: %.scm
|
||||||
|
|
|||||||
$(CHICKEN_C) $< -e -c -o $@
|
$(CHICKEN_C) $< -e -c -o $@
|
||||||
|
|
||||||
sex-tests: $(OBJ) tests/run.scm
|
sex-tests: $(OBJ) tests/*.scm
|
||||||
$(CHICKEN_C) tests/run.scm -c -o sex-tests.o
|
cd ./tests && $(CHICKEN_C) run.scm -c -o sex-tests.o
|
||||||
$(CHICKEN_C) $(OBJ) sex-tests.o -o sex-tests
|
$(CHICKEN_C) $(OBJ) ./tests/sex-tests.o -o sex-tests
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) sexc sex-tests main.o sex-test.o
|
rm -f $(OBJ) sexc sex-tests main.o ./tests/sex-tests.o
|
||||||
|
|||||||
@@ -38,9 +38,10 @@
|
|||||||
|
|
||||||
(pub defmacro (list-for-each list-type list-var elt-type elt-var what-do)
|
(pub defmacro (list-for-each list-type list-var elt-type elt-var what-do)
|
||||||
(let ((list-var-2 (cat list-var '-2)))
|
(let ((list-var-2 (cat list-var '-2)))
|
||||||
`((var (pointer ,list-type) ,list-var-2 ,list-var)
|
`((begin
|
||||||
(var ,elt-type ,elt-var (-> ,list-var-2 value))
|
(var (pointer ,list-type) ,list-var-2 ,list-var)
|
||||||
(while (!= (-> ,list-var-2 next) NULL)
|
(var ,elt-type ,elt-var (-> ,list-var-2 value))
|
||||||
,what-do
|
(while (!= (-> ,list-var-2 next) NULL)
|
||||||
(= ,list-var-2 (-> ,list-var-2 next))
|
,what-do
|
||||||
(= ,elt-var (-> ,list-var-2 value))))))
|
(= ,list-var-2 (-> ,list-var-2 next))
|
||||||
|
(= ,elt-var (-> ,list-var-2 value)))))))
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
(include stdlib.h)
|
(include stdlib.h)
|
||||||
(include stddef.h)
|
(include stddef.h)
|
||||||
(include stdbool.h)
|
|
||||||
(include stdio.h)
|
(include stdio.h)
|
||||||
|
|
||||||
(chicken-import srfi-1 brev-separate) ; list routines, e.g. fold
|
(chicken-import srfi-1 brev-separate) ; list routines, e.g. fold
|
||||||
@@ -16,7 +15,7 @@
|
|||||||
((const char *) c)
|
((const char *) c)
|
||||||
((fn bool ((bool val))) not)))
|
((fn bool ((bool val))) not)))
|
||||||
|
|
||||||
(var foo f #((= .a-field 1.2)))
|
(var foo f)
|
||||||
|
|
||||||
(list-T int)
|
(list-T int)
|
||||||
(make-list-T int #f)
|
(make-list-T int #f)
|
||||||
@@ -26,7 +25,7 @@
|
|||||||
|
|
||||||
(extern fn void puk ((int a) (float b)))
|
(extern fn void puk ((int a) (float b)))
|
||||||
(fn int bar () (return ,(imports-test 10 20 30)))
|
(fn int bar () (return ,(imports-test 10 20 30)))
|
||||||
(pub fn void baz () true)
|
(pub fn bool baz () (return true))
|
||||||
|
|
||||||
(extern var int i)
|
(extern var int i)
|
||||||
(var int j)
|
(var int j)
|
||||||
@@ -34,15 +33,15 @@
|
|||||||
|
|
||||||
(pub fn int main ()
|
(pub fn int main ()
|
||||||
(var (* list-int) l (make-list-int))
|
(var (* list-int) l (make-list-int))
|
||||||
(printf "Size of the list: %zu\n" (length-list-int l))
|
(printf "Size of the list: %lu\n" (length-list-int l))
|
||||||
(add-value-list-int l 3)
|
(add-value-list-int l 3)
|
||||||
(add-value-list-int l 4)
|
(add-value-list-int l 4)
|
||||||
(printf "Size of the list: %zu\n" (length-list-int l))
|
(printf "Size of the list: %lu\n" (length-list-int l))
|
||||||
(list-for-each list-int l int v
|
(list-for-each list-int l int v
|
||||||
(printf "%d " v))
|
(printf "%d " v))
|
||||||
(printf "\n")
|
(printf "\n")
|
||||||
(printf "Size of the list: %zu\n" (length-list-int l))
|
(printf "Size of the list: %lu\n" (length-list-int l))
|
||||||
(printf "%p\n" l->next)
|
(printf "%p\n" (cast void* l->next))
|
||||||
(return 0))
|
(return 0))
|
||||||
|
|
||||||
(pub fn void print-list (((const list-int) *l))
|
(pub fn void print-list (((const list-int) *l))
|
||||||
|
|||||||
57
fmt-c.scm
57
fmt-c.scm
@@ -15,7 +15,6 @@
|
|||||||
(define (fmt-macro-params st) (fmt-ref st 'macro-params))
|
(define (fmt-macro-params st) (fmt-ref st 'macro-params))
|
||||||
(define (fmt-expression? st) (fmt-ref st 'expression?))
|
(define (fmt-expression? st) (fmt-ref st 'expression?))
|
||||||
(define (fmt-return? st) (fmt-ref st 'return?))
|
(define (fmt-return? st) (fmt-ref st 'return?))
|
||||||
(define (fmt-default-type st) (fmt-ref st 'default-type 'int))
|
|
||||||
(define (fmt-newline-before-brace? st) (fmt-ref st 'newline-before-brace?))
|
(define (fmt-newline-before-brace? st) (fmt-ref st 'newline-before-brace?))
|
||||||
(define (fmt-braceless-bodies? st) (fmt-ref st 'braceless-bodies?))
|
(define (fmt-braceless-bodies? st) (fmt-ref st 'braceless-bodies?))
|
||||||
(define (fmt-non-spaced-ops? st) (fmt-ref st 'non-spaced-ops?))
|
(define (fmt-non-spaced-ops? st) (fmt-ref st 'non-spaced-ops?))
|
||||||
@@ -27,6 +26,8 @@
|
|||||||
|
|
||||||
(define (c-in-expr proc) (fmt-let 'expression? #t proc))
|
(define (c-in-expr proc) (fmt-let 'expression? #t proc))
|
||||||
(define (c-in-stmt proc) (fmt-let 'expression? #f proc))
|
(define (c-in-stmt proc) (fmt-let 'expression? #f proc))
|
||||||
|
(define (c-reset-newline proc) (fmt-let 'newline-before-brace? #f proc))
|
||||||
|
|
||||||
(define (c-in-test proc) (fmt-let 'in-cond? #t (c-in-expr proc)))
|
(define (c-in-test proc) (fmt-let 'in-cond? #t (c-in-expr proc)))
|
||||||
(define (c-with-op op proc) (fmt-let 'op op proc))
|
(define (c-with-op op proc) (fmt-let 'op op proc))
|
||||||
|
|
||||||
@@ -218,6 +219,7 @@
|
|||||||
((apply cpp-if/aux (substring/shared (symbol->string (car x)) 1)
|
((apply cpp-if/aux (substring/shared (symbol->string (car x)) 1)
|
||||||
(cdr x)) st))
|
(cdr x)) st))
|
||||||
((%endif) ((apply cpp-endif (cdr x)) st))
|
((%endif) ((apply cpp-endif (cdr x)) st))
|
||||||
|
((%block-begin) ((apply c-braced-block #f (cdr x)) st))
|
||||||
((%block) ((apply c-braced-block (cdr x)) st))
|
((%block) ((apply c-braced-block (cdr x)) st))
|
||||||
((%comment) ((apply c-comment (cdr x)) st))
|
((%comment) ((apply c-comment (cdr x)) st))
|
||||||
((:) ((apply c-label (cdr x)) st))
|
((:) ((apply c-label (cdr x)) st))
|
||||||
@@ -487,8 +489,12 @@
|
|||||||
|
|
||||||
(define (c-open-brace st)
|
(define (c-open-brace st)
|
||||||
(if (fmt-newline-before-brace? st)
|
(if (fmt-newline-before-brace? st)
|
||||||
(cat nl (c-current-indent-string st) "{" nl)
|
(begin
|
||||||
(cat " {" nl)))
|
(fmt-set! st 'newline-before-brace? #t)
|
||||||
|
(cat "{" nl))
|
||||||
|
(begin
|
||||||
|
(fmt-set! st 'newline-before-brace? #t)
|
||||||
|
(cat " {" nl))))
|
||||||
|
|
||||||
(define (c-close-brace st)
|
(define (c-close-brace st)
|
||||||
(dsp "}"))
|
(dsp "}"))
|
||||||
@@ -521,7 +527,7 @@
|
|||||||
|
|
||||||
(define (c-braced-block/aux offset header . body)
|
(define (c-braced-block/aux offset header . body)
|
||||||
(lambda (st)
|
(lambda (st)
|
||||||
((cat header (c-open-brace st) (c-indent st offset)
|
((cat (if header header "") (c-open-brace st) (c-indent st offset)
|
||||||
(apply c-begin body) fl
|
(apply c-begin body) fl
|
||||||
(c-current-indent-string st offset) (c-close-brace st))
|
(c-current-indent-string st offset) (c-close-brace st))
|
||||||
st)))
|
st)))
|
||||||
@@ -590,24 +596,26 @@
|
|||||||
;; basic control structures
|
;; basic control structures
|
||||||
|
|
||||||
(define (c-while check . body)
|
(define (c-while check . body)
|
||||||
(cat (c-block (cat "while (" (c-in-test (c-expr check)) ")")
|
(c-reset-newline
|
||||||
(c-in-stmt (apply c-begin body)))
|
(cat (c-block (cat "while (" (c-in-test (c-expr check)) ")")
|
||||||
fl))
|
(c-in-stmt (apply c-begin body)))
|
||||||
|
fl)))
|
||||||
|
|
||||||
(define (c-for init check update . body)
|
(define (c-for init check update . body)
|
||||||
(cat
|
(c-reset-newline
|
||||||
(c-block
|
(cat
|
||||||
(c-in-expr
|
(c-block
|
||||||
(cat "for (" (c-expr init) "; " (c-in-test (c-expr check)) "; "
|
(c-in-expr
|
||||||
(c-expr update ) ")"))
|
(cat "for (" (c-expr init) "; " (c-in-test (c-expr check)) "; "
|
||||||
(c-in-stmt (apply c-begin body)))
|
(c-expr update ) ")"))
|
||||||
fl))
|
(c-in-stmt (apply c-begin body)))
|
||||||
|
fl)))
|
||||||
|
|
||||||
(define (c-param x)
|
(define (c-param x)
|
||||||
(cond
|
(cond
|
||||||
((procedure? x) x)
|
((procedure? x) x)
|
||||||
((pair? x) (c-type (car x) (cadr x)))
|
((pair? x) (c-type (car x) (cadr x)))
|
||||||
(else (cat (lambda (st) ((c-type (fmt-default-type st)) st)) " " x))))
|
(else (error "missing type" x))))
|
||||||
|
|
||||||
(define (c-field x)
|
(define (c-field x)
|
||||||
(cond
|
(cond
|
||||||
@@ -623,10 +631,12 @@
|
|||||||
(else (c-type (car x) (cadr x))))
|
(else (c-type (car x) (cadr x))))
|
||||||
(c-type (car x)
|
(c-type (car x)
|
||||||
(fmt-join c-expr (cdr x) ", "))))
|
(fmt-join c-expr (cdr x) ", "))))
|
||||||
(else (cat (lambda (st) ((c-type (fmt-default-type st)) st)) " " x))))
|
(else (error "missing type" x))))
|
||||||
|
|
||||||
(define (c-param-list ls)
|
(define (c-param-list ls)
|
||||||
(c-in-expr (fmt-join/dot c-param (lambda (dot) (dsp "...")) ls ", ")))
|
(if (null? ls)
|
||||||
|
(c-type 'void)
|
||||||
|
(c-in-expr (fmt-join/dot c-param (lambda (dot) (dsp "...")) ls ", "))))
|
||||||
|
|
||||||
(define (c-fun type name params . body)
|
(define (c-fun type name params . body)
|
||||||
(cat (c-block (c-in-expr (c-prototype type name params))
|
(cat (c-block (c-in-expr (c-prototype type name params))
|
||||||
@@ -759,12 +769,13 @@
|
|||||||
(c-wrap-stmt (cat "goto " (c-expr label))))
|
(c-wrap-stmt (cat "goto " (c-expr label))))
|
||||||
|
|
||||||
(define (c-switch val . clauses)
|
(define (c-switch val . clauses)
|
||||||
(lambda (st)
|
(c-reset-newline
|
||||||
((cat "switch (" (c-in-expr val) ")" (c-open-brace st)
|
(lambda (st)
|
||||||
(c-indent/switch st)
|
((cat "switch (" (c-in-expr val) ")" (c-open-brace st)
|
||||||
(c-in-stmt (apply c-begin/aux #t (map c-switch-clause clauses))) fl
|
(c-indent/switch st)
|
||||||
(c-current-indent-string st) (c-close-brace st) fl)
|
(c-in-stmt (apply c-begin/aux #t (map c-switch-clause clauses))) fl
|
||||||
st)))
|
(c-current-indent-string st) (c-close-brace st) fl)
|
||||||
|
st))))
|
||||||
|
|
||||||
(define (c-switch-clause/breaks x)
|
(define (c-switch-clause/breaks x)
|
||||||
(lambda (st)
|
(lambda (st)
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
|
|||||||
(put 'pub 'lisp-indent-function 'defun)
|
(put 'pub 'lisp-indent-function 'defun)
|
||||||
(put 'defmacro 'lisp-indent-function 'defun)
|
(put 'defmacro 'lisp-indent-function 'defun)
|
||||||
(put 'struct 'lisp-indent-function 'defun)
|
(put 'struct 'lisp-indent-function 'defun)
|
||||||
|
(put 'union 'lisp-indent-function 'defun)
|
||||||
(put 'var 'lisp-indent-function 0)
|
(put 'var 'lisp-indent-function 0)
|
||||||
(put 'import 'lisp-indent-function 1)
|
(put 'import 'lisp-indent-function 1)
|
||||||
|
|
||||||
|
|||||||
22
sexc.scm
22
sexc.scm
@@ -1,7 +1,8 @@
|
|||||||
(declare (unit sexc)
|
(declare (unit sexc)
|
||||||
(uses fmt-c
|
(uses fmt-c
|
||||||
sex-macros
|
sex-macros
|
||||||
sex-modules))
|
sex-modules
|
||||||
|
sex-types))
|
||||||
|
|
||||||
(include "utils.macros.scm")
|
(include "utils.macros.scm")
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
(chicken pretty-print)
|
(chicken pretty-print)
|
||||||
(chicken process)
|
(chicken process)
|
||||||
(chicken process-context)
|
(chicken process-context)
|
||||||
|
(chicken port)
|
||||||
(chicken string)
|
(chicken string)
|
||||||
fmt
|
fmt
|
||||||
getopt-long
|
getopt-long
|
||||||
@@ -36,7 +38,7 @@
|
|||||||
((fn) '%fun)
|
((fn) '%fun)
|
||||||
((prototype) '%prototype)
|
((prototype) '%prototype)
|
||||||
((var) '%var)
|
((var) '%var)
|
||||||
((begin) '%begin)
|
((begin) '%block-begin)
|
||||||
((define) '%define)
|
((define) '%define)
|
||||||
((pointer) '%pointer)
|
((pointer) '%pointer)
|
||||||
((array) '%array)
|
((array) '%array)
|
||||||
@@ -44,6 +46,10 @@
|
|||||||
((@) 'vector-ref)
|
((@) 'vector-ref)
|
||||||
((include) '%include)
|
((include) '%include)
|
||||||
((cast) '%cast)
|
((cast) '%cast)
|
||||||
|
;; uh things we do for c89 compatibility
|
||||||
|
((bool) 'int)
|
||||||
|
((true) 1)
|
||||||
|
((false) 0)
|
||||||
(else
|
(else
|
||||||
(if (symbol? atom)
|
(if (symbol? atom)
|
||||||
(unkebabify atom)
|
(unkebabify atom)
|
||||||
@@ -281,19 +287,19 @@
|
|||||||
"cc"))
|
"cc"))
|
||||||
(out-file (if (eq? output 'default)
|
(out-file (if (eq? output 'default)
|
||||||
"a.out"
|
"a.out"
|
||||||
output))
|
output)))
|
||||||
(temp-c-out (create-temporary-file ".sex.c")))
|
|
||||||
(with-output-to-file temp-c-out
|
|
||||||
(lambda ()
|
|
||||||
(emit-c sex-forms)))
|
|
||||||
(call-with-values
|
(call-with-values
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(process compiler (append (list temp-c-out "-o" out-file)
|
(process compiler (append (list "-o" out-file "-std=c89" "-pedantic" "-x" "c")
|
||||||
(if (get-arg args 'compile-object #f)
|
(if (get-arg args 'compile-object #f)
|
||||||
(list "-c")
|
(list "-c")
|
||||||
(list))
|
(list))
|
||||||
|
(list "-") ; read stdin
|
||||||
(get-c-compiler-args args))))
|
(get-c-compiler-args args))))
|
||||||
(lambda (out-port in-port pid)
|
(lambda (out-port in-port pid)
|
||||||
|
(with-output-to-port in-port
|
||||||
|
(lambda () (emit-c sex-forms)))
|
||||||
|
(close-output-port in-port)
|
||||||
(process-wait pid)))))
|
(process-wait pid)))))
|
||||||
|
|
||||||
(define (process-input input raw-forms)
|
(define (process-input input raw-forms)
|
||||||
|
|||||||
31
tests/basic.scm
Normal file
31
tests/basic.scm
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
;;; unkebabify
|
||||||
|
Seems it needs to be updated too Seems it needs to be updated too
```suggestion
(test '%block-begin (atom-to-fmt-c 'begin))
```
|
|||||||
|
(test '- (unkebabify '-))
|
||||||
|
(test '-- (unkebabify '--))
|
||||||
|
(test '-> (unkebabify '->))
|
||||||
|
(test '-= (unkebabify '-=))
|
||||||
|
(test 'kebab_case (unkebabify 'kebab-case))
|
||||||
|
(test '_what_ (unkebabify '-what-))
|
||||||
|
(test 'this->member (unkebabify 'this->member))
|
||||||
|
(test '_this_->_member_ (unkebabify '-this-->-member-))
|
||||||
|
(test '__->>> (unkebabify '--->>>))
|
||||||
|
|
||||||
|
;;; atom-to-fmt-c
|
||||||
|
(test '%fun (atom-to-fmt-c 'fn))
|
||||||
|
(test '%prototype (atom-to-fmt-c 'prototype))
|
||||||
|
(test '%var (atom-to-fmt-c 'var))
|
||||||
|
(test '%block-begin (atom-to-fmt-c 'begin))
|
||||||
|
(test '%define (atom-to-fmt-c 'define))
|
||||||
|
(test '%pointer (atom-to-fmt-c 'pointer))
|
||||||
|
(test '%array (atom-to-fmt-c 'array))
|
||||||
|
(test 'vector-ref (atom-to-fmt-c '@))
|
||||||
|
(test '%include (atom-to-fmt-c 'include))
|
||||||
|
(test '%cast (atom-to-fmt-c 'cast))
|
||||||
|
|
||||||
|
;;; c89 stuff
|
||||||
|
(test 'int (atom-to-fmt-c 'bool))
|
||||||
|
(test 1 (atom-to-fmt-c 'true))
|
||||||
|
(test 0 (atom-to-fmt-c 'false))
|
||||||
|
|
||||||
|
;;; make-field-access
|
||||||
|
(test 'a.b (make-field-access '(.b a)))
|
||||||
|
(test 'a.b.c (make-field-access '(.c a.b)))
|
||||||
@@ -6,32 +6,8 @@
|
|||||||
srfi-1
|
srfi-1
|
||||||
test)
|
test)
|
||||||
|
|
||||||
;;; unkebabify
|
(include "basic.scm")
|
||||||
(test '- (unkebabify '-))
|
(include "types.scm")
|
||||||
(test '-- (unkebabify '--))
|
|
||||||
(test '-> (unkebabify '->))
|
|
||||||
(test '-= (unkebabify '-=))
|
|
||||||
(test 'kebab_case (unkebabify 'kebab-case))
|
|
||||||
(test '_what_ (unkebabify '-what-))
|
|
||||||
(test 'this->member (unkebabify 'this->member))
|
|
||||||
(test '_this_->_member_ (unkebabify '-this-->-member-))
|
|
||||||
(test '__->>> (unkebabify '--->>>))
|
|
||||||
|
|
||||||
;;; atom-to-fmt-c
|
|
||||||
(test '%fun (atom-to-fmt-c 'fn))
|
|
||||||
(test '%prototype (atom-to-fmt-c 'prototype))
|
|
||||||
(test '%var (atom-to-fmt-c 'var))
|
|
||||||
(test '%begin (atom-to-fmt-c 'begin))
|
|
||||||
(test '%define (atom-to-fmt-c 'define))
|
|
||||||
(test '%pointer (atom-to-fmt-c 'pointer))
|
|
||||||
(test '%array (atom-to-fmt-c 'array))
|
|
||||||
(test 'vector-ref (atom-to-fmt-c '@))
|
|
||||||
(test '%include (atom-to-fmt-c 'include))
|
|
||||||
(test '%cast (atom-to-fmt-c 'cast))
|
|
||||||
|
|
||||||
;;; make-field-access
|
|
||||||
(test 'a.b (make-field-access '(.b a)))
|
|
||||||
(test 'a.b.c (make-field-access '(.c a.b)))
|
|
||||||
|
|
||||||
;;; Should be the last in the test suite
|
;;; Should be the last in the test suite
|
||||||
(test-exit)
|
(test-exit)
|
||||||
|
|||||||
1
tests/types.scm
Normal file
1
tests/types.scm
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(test "char *" (to-c-type '(%pointer char)))
|
||||||
Reference in New Issue
Block a user
Update cleanup accordingly.