diff --git a/Makefile b/Makefile index 9ae4fab..f25a7ae 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CHICKEN_C = csc -MODULES = sexc sex-macros sex-modules utils fmt-c +MODULES = sexc sex-macros sex-modules sex-types utils fmt-c OBJ = $(MODULES:%=%.o) sexc: main.o $(OBJ) diff --git a/Readme.org b/Readme.org index d08d78e..93aa815 100644 --- a/Readme.org +++ b/Readme.org @@ -12,7 +12,7 @@ to export ~CHICKEN_INSTALL_REPOSITORY~ and ~CHICKEN_REPOSITORY_PATH~ environment variables. Refer to the documentation for more info: https://wiki.call-cc.org/man/5/Extension%20tools#changing-the-repository-location -~chicken-install fmt getopt-long brev-separate test tree srfi-1 srfi-13~ +~chicken-install fmt getopt-long brev-separate test tree srfi-1 srfi-13 srfi-69~ ** Compilation ~make~ diff --git a/example/begin.sex b/example/begin.sex new file mode 100644 index 0000000..00e4002 --- /dev/null +++ b/example/begin.sex @@ -0,0 +1,8 @@ +(pub fn void other-fn () + (begin (while true (begin 1 2 3 4))) + (switch a + ((1) (begin + (var (const char *) str "121232132") + (puts "str"))) + ((2) (puts "2")) + (default (puts "more")))) diff --git a/example/fn-no-args.sex b/example/fn-no-args.sex new file mode 100644 index 0000000..a271620 --- /dev/null +++ b/example/fn-no-args.sex @@ -0,0 +1 @@ +(pub fn void no-args-fn () ()) diff --git a/example/hello-world.sex b/example/hello-world.sex index f5da6e2..871d6ea 100644 --- a/example/hello-world.sex +++ b/example/hello-world.sex @@ -1,8 +1,8 @@ (include stdio.h) (pub fn int main ((int argc) (char **argv)) - (puts "Hello from Sex!") (var (array char 512) name) + (puts "Hello from Sex!") (puts "What is your name?") (scanf "%s" (cast char* &name)) (printf "Hello, %s!\n" name) diff --git a/example/polymorphism.sex b/example/polymorphism.sex new file mode 100644 index 0000000..727943a --- /dev/null +++ b/example/polymorphism.sex @@ -0,0 +1,25 @@ +(include stdint.h) + +(struct vec2 + ((uint32_t x) + (uint32_t y))) + +(trait gui + (fn void update ((float dt))) + (fn void render ()) + (fn vec2 get-position ()) + (fn void add-child ((gui *w)))) + +(struct button + ((vector gui) children) + ((vec2 pos))) + +(impl gui button + (fn void update ((float dt)) + ()) + (fn void render () + ()) + (fn vec2 get-position () + (return self->pos)) + (fn void add-child ((gui *w)) + (push self->children w))) diff --git a/sex-mode.el b/sex-mode.el index 8eb676e..591f38d 100644 --- a/sex-mode.el +++ b/sex-mode.el @@ -35,11 +35,13 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") "define" "defmacro" "extern" + "impl" "import" "include" "fn" "pub" "struct" + "trait" "var" "union") 'word) @@ -57,6 +59,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") "for" "goto" "return" + "self" "switch" "var" "while") @@ -81,6 +84,8 @@ All commands in `lisp-mode-shared-map' are inherited by this map.") (put 'defmacro 'lisp-indent-function 'defun) (put 'struct 'lisp-indent-function 'defun) (put 'union 'lisp-indent-function 'defun) +(put 'trait 'lisp-indent-function 'defun) +(put 'impl 'lisp-indent-function 'defun) (put 'var 'lisp-indent-function 0) (put 'import 'lisp-indent-function 1) diff --git a/sex-types.scm b/sex-types.scm new file mode 100644 index 0000000..6aaeadb --- /dev/null +++ b/sex-types.scm @@ -0,0 +1,23 @@ +(declare + (unit sex-types) + (uses fmt-c)) + +(import fmt + srfi-69) + +(define +all-types+ (make-hash-table)) + +(define (normalize-type type) + ) + +(define (add-pointer type) + (list 'pointer type)) + +(define (add-const type) + (list 'const type)) + +(define (get-types-from-arglist arglist) + (list)) + +(define (to-c-type type) + (fmt #f (c-type type))) diff --git a/sexc.scm b/sexc.scm index 01a8f2c..aa353cf 100644 --- a/sexc.scm +++ b/sexc.scm @@ -180,24 +180,35 @@ (eval (cons 'import (cdr form))) acc) ((import) (append (process-raw-forms - (import-modules (cdr form)) (list)) acc)) (else (walk-sex-tree form acc)))) (define (process-raw-forms raw-forms acc) + "First processing pass" (if (null? raw-forms) (reverse acc) (process-raw-forms (cdr raw-forms) (process-form (car raw-forms) acc)))) +;;; Second pass + +(define (process-sex-forms forms) + "Second processing pass. + +In this pass we do form-rearranging manipulations, like docstring extraction." + forms) + +;;; Aux functions + (define (read-forms acc) (let ((r (read))) (if (eof-object? r) (reverse acc) (read-forms (cons r acc))))) (define (emit-c forms) + "Final conversion to C" (for-each (lambda (form) (fmt #t (c-expr form) nl)) forms)) @@ -338,7 +349,9 @@ (if (eq? input 'stdin) (read-forms (list)) (read-from-file input))) - (sex-forms (process-input input raw-forms))) + (sex-forms + (process-sex-forms + (process-input input raw-forms)))) (if (or (get-arg args 'macro-expand #f) (get-arg args 'preprocess #f)) ;; Preprocess or macroexpand