scexp - s-expression to C translation

scexp is a program for translating a s-expression based syntax tree for the C language into actual C source code. This manual describes the language implemented by scexp, and the public functions for invoking the translator.

Packages

scexp - scexp internal functions
The scexp package contains all of the internal functions for scexp, and exports the functions for invoking the translator.

scexp-read - read package for scexp code

All scexp code is read into the scexp-read package. In addition, the readtable is configured as following when reading scexp code:

scexp-user - read package for macros and other user code

The scexp-user package is used to read scexp forms preceded by the [ read macro. When that occurs the readtable is configured such that { is a macro character which reads a form into scexp-read with the reader configuration described there. The form must be terminated by a closing bracket, }.

Exported Functions

translate-file file - translate a scexp file into C
translate-file translates a single scexp file into C. Specify its pathname in the same way you would to compile-file. If a file named "test.scexp" or "test" is supplied, the output will go to "test.c".
install-scexp-read-macro
Installs the { reader macro into the current readtable. { will read a single form in the scexp-read package with the readtable described above. The form must be terminated by }.

The scexp Language

scexp is designed to encompass the semantics of a large subset of the C language, while providing additional clarity and lisp source code transformation. A scexp source file is composed of top-level forms, each of which is either a macro definition, macro use, or generates some output in the C.

Top-Level Forms

defun return-type name ((type arg) *) [implicit-let] - defines a function
defun defines a new C function, with the given name, return-type, and arguments with given types. The body of a defun is an implicit let form.

deftype name typespec - defines a new type

deftype defines a new C type with name name, which is equivalent to the supplied typespec.

defstruct name (type var)* - defines a C structure

defstruct defines a C structure type with name name. The structure has elements with types and names as supplied.

defvar type name [optional-binding] - defines a global variable

defvar defines a C global variable with type and name, and binding as supplied.

cpp-include [optional :system] file - generate a C preprocessor include

cpp-include generates a preprocessor include. If the :system keyword is supplied as the first argument, it will generate a system-path include.

defmacro name (lambda-list*) body* - define a new macro

The defmacro form must be read into the scexp-user package by use of the [ read macro. It defines a new macro that will be expanded upon use in C toplevel and ordinary forms. Use the { read macro in the definition to refer to variables and functions in the scexp-read package.

Type Specifications

Primitive Types

Primitive types such as int, char, and long are specified by their name, either as a list or a symbol. The following are all valid primitive types:
int
(int)
void
char
(long)
Function types are specified in a list with at least one argument for the return type. Additional arguments are used as argument types to the function. The following are examples of function types:
(function void void)
(function int (char))
(function int (char) long)
Structures are named in a list whose first element is the symbol struct. The following are examples of structure types:
(struct my_struct)

Type Qualifiers

Type qualifiers can be appended to the head of any valid type (as list) to output an appropriately qualified type. The following qualifiers are supported: Type qualifiers are composed from right to left. Thus (const pointer int) refers to a constant pointer to an int, and (pointer const int) refers to a pointer to a constant int.

The following are all valid qualified types:

(register int)
(const long int)
(const * const short int)
(pointer function (pointer const int) (volatile int) char)

Ordinary Forms

Function definitions are composed of sequences of forms.

Forms producing values

+, - arg0 arg1*
If only one argument is supplied, generates unary + or -; otherwise, generates composed addition or subtraction.
* arg0 arg1*
If only one argument is supplied, generates unary dereference (*); otherwise, generates composed multiplication.
/ arg0 arg1 arg2* - generates composed division

mod arg0 arg1 arg2* - generates composed modular residue

==, <, >, <=, >=, != arg0 arg1 arg2* - generates composed comparison operations

setq lval rval - sets lval to rval

not val - logical negation of val

deref val - dereference val, same as unary *

incf, post-incf, decf, post-decf val - Increment or decrement val. In the case of the post- operators, returns the original value of val; otherwise, returns the new value.

log-and, log-or arg0 arg1 arg2* Compose logical AND / OR over the supplied arguments.

bit-and, bit-or, bit-xor arg0 arg1 arg2* Compose bitwise AND / OR / XOR over the supplied arguments.

if test conseq [optional-else]

If test evaluates to non-zero, performs conseq, otherwise performs optional-else if supplied. If a value is expected from the if statement, the else clause must be supplied.
progn form0 form1*
Executes form0 form1* in order. If a value is expected, the value of the last form is returned.
sizeof typespec - returns the number of bytes required to store a value of type typespec

aref array ref0 ref1*

Performs array lookup in the array array, which must have dimensions corresponding to the number of indices supplied.
ref var - returns a pointer to the supplied variable or location

cond (test form0 form1*)* [(else form0 form1*)]

cond is a multiple-test conditional statement. Each test is evaluated in sequence. When one of them returns non-zero, its corresponding forms will be evaluated. If an else form is supplied, it will be evaluated if no other test returns true. else is not optional if a value is expected.
elt. structure var
Retrieves the variable named var from the struct structure.
elt-> structure var
Retrieves the variable named var from the pointer to a struct named structure. Shorthand for (elt. (deref structure) var).
cast val type
Casts val to the typespec denoted by type. The two types must be compatible.


Control structures

for (init-form*) test (increment-form*) body-form*
At the beginning of the for statement, executes all init-forms. test is evaluated; if it returns non-zero, the loop continues by evaluating the body-forms in sequence and then each increment-form.

Shorthand for (progn init-form* (while test body-form* increment-form*)).

do/while (body-form*) test
Executes each body-form, then evaluates test. If it is non-zero, the loop starts again. Always executes the body-forms at least once.
while test body-form*
Evaluates test. If it is non-zero, executes body-forms and loops.
let ((type name [optional-binding])*) body*
Executes body* in a lexical block where the supplied variables named by name are present. These variables have type supplied in type and are optionally initialized to optional-binding.
switch value body*
Compares value for simple equality to the case statements included in body*. If value is equal to any of them, jump to that position and begin executing in body*. Otherwise, if there is a default in body*, jump to there and begin executing.
case value
Creates a position for switch to jump to inside of a switch body.
break
While executing a switch body, escape out of the switch statement. While executing in a for, while, or do/while statement, break out of the loop.
default - Creates a default branch for a switch statement.

label name - Creates a goto label.

goto name - Jumps to the label named name in the current function.


Copyright 2004 Brian Mastenbrook | scexp home page
Last edited: Fri Jan 14 17:09:37 2005 CST

Valid HTML 2.0!