Programming in the language Sassy usually consists of calling the procedure
sassy
, and then either passing the returned result to an
output module or manipulating the result directly with the
procedures from Sassy’s output API.
—procedure: sassy input [options] -> sassy-output
sassy
assembles the contents of input and returns a
record of type sassy-ouput that contains the results. The
input should be either a file composed wholly of Sassy’s
directives at its “top level”, or a list of directives. The [options] may be omitted; see below.
(sassy-make-elf "sysexit.o" (sassy '((entry _start) (text (label _start (begin (mov eax 1) (mov ebx 0) (int #x80))))))) (sassy-text-list (sassy '((entry _start) (text (label _start (begin (mov eax 1) (mov ebx 0) (int #x80))))))) ==> '(184 1 0 0 0 187 0 0 0 0 205 128)
You may invoke one of the following [options] by supplying the quoted symbol as shown:
'dont-expand
– Skip the macro-expansion step. By supplying this option, you indicate that the input contains macro-calls or definitions, and that sassy
may immediately generate output. Supplying this option generally speeds up sassy
, but also precludes the use certain forms, since some supplied forms are macros. For a list of these disallowed forms, see Appendix A.
Since Sassy is embedded in Scheme, write numbers, characters, and
strings just as you would in Scheme. Normally, to write an assembly
label (denoting an address, and annotated as <label-name>
in the
grammars), you write a Scheme symbol. Write s-expressions for
everything else.
The only caveat concerning the use of Scheme symbols for labels is
that in the
current Scheme standard “case is insignificant,” and thus writing
symbols with uppercase letters may be problematic. As well, symbols
may not begin with a period. There are two solutions: either use a
Scheme implementation with a reader that accepts the Scheme symbols
you want to write, or use Sassy’s special escape form to call, for
instance, string->symbol
. You may also define the result of
this call to be a constant using Sassy’s internal macro system.
(sassy '((macro dot-dot-weird (! (string->symbol "..WEirD"))) (text (label dot-dot-weird (begin ...)))))
The resulting label will be ’..WEirD
’.
(! <scheme-expression>)
Use this special “escape” form to tell sassy
to suspend itself momentarily and request that the host Scheme evaluate <scheme-expression>
. This way, you can take advantage of Scheme’s more advanced macro systems or perform conditional compilation, for instance.
An escape, which is not a directive, can occur in any position in a Sassy program. Normally the result returned by the evaluation of the <scheme-expression>
must be a syntactically correct form that sassy
can directly substitute in place for the escape. The exception occurs when sassy
is looking for a directive (i.e. at the top level) and instead encounters an escape. In this case if the escape returns 'void
, then sassy
ignores the 'void
and continues processing.
(define (foo x) (+ x 4)) (define-syntax get-dogs (syntax-rules () ((_) '(export lucky toto spot)))) (sassy '((! (get-dogs)) (! (if (file-exists? "sassy-libs/cats") '(include "sassy-libs/cats")) 'void) (text (mov eax (& spot (! (foo 4)))))))
sassy
processes the special escape forms and substitutes the return values in place of the escapes during macro expansion. sassy
calls eval
in the following manner:
(eval <scheme-expression> (interaction-environment))