implement comma in Sex sources

This commit is contained in:
2025-05-29 22:08:14 +03:00
parent 32ed90295b
commit b8d0efafcb
3 changed files with 112 additions and 32 deletions

View File

@@ -1,18 +1,20 @@
* The Sex language * The Sex language
Sex is a S-expressions language, which transpiles to C. Sex is a S-expressions language, which transpiles to C.
* Compilation and usage Sex is also Chicken, since all source processing and compile-time
Sex is written in Chicken Scheme, so first you'll need to get yourself computations are written in Chicken.
a Chicken.
It also has a couple of Chicken deps. And Chicken is R5RS Scheme.
* Compilation and usage
First, get yourself a Chicken. Second, one Chicken deps.
** Install Chicken Eggs ** Install Chicken Eggs
By the way, there's a way to make Chicken install eggs non-globally. Refer to By the way, there's a way to make Chicken install eggs non-globally. Refer to
the documentation for more info: the documentation for more info:
https://wiki.call-cc.org/man/5/Extension%20tools#changing-the-repository-location https://wiki.call-cc.org/man/5/Extension%20tools#changing-the-repository-location
~chicken-install fmt tree brev-separate~ ~chicken-install fmt~
** Compilation ** Compilation
~make~ ~make~
@@ -24,6 +26,43 @@ cat hello-world.sex | sexc > hello_world.c
cc hello_world.c -o hello_world cc hello_world.c -o hello_world
#+end_src #+end_src
* Example
Here is an example, demonstrating what Sex source looks like, and what
it compiles too. An avid reader also shall notice how we call Chicken
procedures in Sex source.
The Sex source:
#+begin_src
(include stdio.h)
(define (foo)
"Hello from Chicken code!\n")
(fn int main ((int argc) (char **argv))
(puts "Hello from Sex!")
(var (array char 512) name)
(puts "What is your name?")
(scanf "%s" &name)
(printf "Hello, %s!\n" name)
(printf ,(foo))
0)
#+end_src
The resulting C source:
#+begin_src
#include <stdio.h>
int main (int argc, char **argv) {
puts("Hello from Sex!");
char name[512];
puts("What is your name?");
scanf("%s", &name);
printf("Hello, %s!\n", name);
printf("Hello from Chicken code!\n");
return 0;
}
#+end_src
* Features * Features
** Full C interoperability ** Full C interoperability
Just ~(include "Your/Favourite/Library.h")~ and use it as you would Just ~(include "Your/Favourite/Library.h")~ and use it as you would

View File

@@ -1,10 +1,13 @@
(include stdio.h) (include stdio.h)
(include unistd.h)
(define (foo)
"Hello from Chicken code!\n")
(fn int main ((int argc) (char **argv)) (fn int main ((int argc) (char **argv))
(puts "Hello from Sex!") (puts "Hello from Sex!")
(var (array char 513) name) (var (array char 512) name)
(puts "What is your name?") (puts "What is your name?")
(scanf "%s" &name) (scanf "%s" &name)
(printf "Hello, %s!\n" name) (printf "Hello, %s!\n" name)
(printf ,(foo))
0) 0)

View File

@@ -1,33 +1,71 @@
(import brev-separate fmt fmt-c tree (chicken string)) (import fmt fmt-c (chicken string))
(define (unkebabify sym) (define (unkebabify sym)
(string->symbol (string->symbol
(string-translate (symbol->string sym) #\- #\_))) (string-translate (symbol->string sym) #\- #\_)))
(define (map-filter-tree map-proc filter-proc tree)
"Walk the tree, checking each element with filter-proc.
If filter-proc returns #t:
- if the element is list, process it recursively,
- if the element is an atom, process it with map-proc.
If filter-proc returns #f, ignore the element.
If filter-proc returns something other, use it instead of processing the element."
(let ((cont (cut map-filter-tree map-proc filter-proc <>)))
(if (null? tree) '()
(let ((filter-res (filter-proc (car tree))))
;(fmt #t "Filter res for " tree " is " filter-res "\n")
(case filter-res
((#t) (cons
(if (atom? (car tree))
(map-proc (car tree))
(cont (car tree)))
(cont (cdr tree))))
((#f) (cont (cdr tree)))
(else (cons filter-res (cont (cdr tree)))))))))
(define (walk-tree tree)
(map-filter-tree
(lambda (elem)
(case elem
((fn) '%fun)
((var) '%var)
((begin) '%begin)
((pointer) '%pointer)
((array) '%array)
(([]) 'vector-ref)
((include) '%include)
((cast) '%cast)
(else
(if (symbol? elem)
(unkebabify elem)
elem))))
(lambda (subtree)
(if (list? subtree)
(case (car subtree)
((unquote)
(eval (cadr subtree)))
(else #t))
#t))
tree))
(define (loop) (define (loop)
(let ((r (read))) (call/cc
(unless (eof-object? r) (lambda (return)
(cond ((eqv? (car r) 'define) (eval r)) (let ((r (read)))
(#t (when (eof-object? r)
(fmt #t (return '()))
(c-expr (case (car r)
(tree-map ((define)
(fn (eval r)
(case x (fmt #t "\n"))
((fn) '%fun) (else
((var) '%var) (let ((result (walk-tree r)))
((begin) '%begin) (when result
((pointer) '%pointer) (fmt #t (c-expr
((array) '%array) result))))))
(([]) 'vector-ref) (loop)))))
((include) '%include)
((cast) '%cast)
(else
(if (symbol? x)
(unkebabify x)
x))))
r)))
(fmt #t "\n")))
(loop))))
(loop) (loop)