4.3 KiB
The Sex language
Sex is a S-expressions language. Sex is written in Chicken, which is a R5RS Scheme. Sex is statically typed, compiled general purpose language.
Compilation
First, get yourself a Chicken, then, some Chicken deps. You also will need a C compiler.
Install Chicken Eggs
Tip: there's a way to make Chicken install eggs non-globally. You need
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 `cat dependencies.txt`
Compilation
make
Usage
Summary
Usage: sexc [options] filename [-- options-for-c-compiler]
Options:
--c-compiler=ARG Select C compiler. Defaults to value of SEX_CC
environment variable, or if it is empty, to cc
-c, --compile-object Compile object file instead of executable program
-C, --preprocess Emit C code
--public-interface Get module's public interface
-h, --help Show this help
-m, --macro-expand Emit macro-expanded semantically processed Sex code
(sort of IR). May be useful for debugging
-o, --output=ARG Write output to file. Default file name is a.out.
If -E or -m options are provided, defaults to stdout
Compiling Hello World
sexc ./examples/hello-world.sex -o hello
That's it. Now you should have executable named hello in your
directory. Sex uses C under the hood, the default C compiler is cc,
but you can pass any using --c-compiler option, or by setting
SEX_CC environment variable.
Example
An example of Sex source:
(include stdio.h)
(pub fn main ((argc int) (argv [* const char])) int
(puts "Hello from Sex!")
(var name [char 512])
(puts "What is your name?")
(scanf "%s" (cast (& name) (* char)))
(printf "Hello, %s!\n" name)
(return 0))
Compile and run:
~/dev/sex $ ./sexc ./example/hello-world.sex -o hello-world
~/dev/sex $ ./hello-world
Hello from Sex!
What is your name?
Alex
Hello, Alex!
Features
Full C interoperability
Just (include "Your/Favourite/Library.h") and use it as you would
have is C.
Auto kebabification
For hardcore fans of traditional Lisp naming convention,
Sex offers automatic kebabification of all symbols, i.e. no more
ugly GL_ARRAY_BUFFER s in your code, they may be written in their
proper form: GL-ARRAY-BUFFER.
Modules
Each source file is a module. Module can provide public interface and
be imported by using (import path/to/module) expression. Module
search path consists of two parts: first is relative to the source
being compiled location, and the second is SEX_MODULE_PATH
environment variable.
Module's public interface consists of everything declared
pub. Structures, function, macros, types, variables can be
public.
Syntactic macros
Sex has support for syntactic macros. Macro definitions look like functions: they have a name, an argument list and a body. Macro should return Sex code.
Examples:
Structure with templated value type
(pub defmacro (list-T type)
(let ((list-type (cat 'list- type)))
`(struct ,list-type
((value ,type)
(next (* ,list-type))))))
(list-T int)
->
(struct list_int
((value int)
(next (* list_int))))
Wrapper for checking return codes
(pub defmacro (check-sdl-return call message ret-code)
`(if (< 0 ,call)
(begin
(puts ,message)
(return ,ret-code))))
(pub fn init () int
(check-sdl-return
(SDL-Init SDL-INIT-VIDEO) "Failed to initialize SDL" 1)
...)
->
(pub fn init () int
(if (< 0 (SDL_Init SDL_INIT_VIDEO))
(begin (puts "Failed to initialize SDL") (return 1)))
...)
Use an established environment for development
As Sex is S-expressions, you always have Emacs with paredit as your best option.
sex-mode.el
To harness the power of sex-mode, add the following lines to your
$HOME/.config/emacs/init.el:
(use-package sex-mode
:load-path "/path/to/sex"
:mode ("\\.sex\\'"))