# (chibi ast)

Abstract Syntax Tree. Interface to the types used by the compiler, and other core types less commonly needed in user code, plus related utilities.

## Analysis and Expansion

#### `(analyze x [env])`

Expands and analyzes the expression `x` and returns the resulting AST.

#### `(optimize ast)`

Runs an optimization pass on `ast` and returns the resulting simplified expression.

#### `(flatten-dot x)`

#### `(macroexpand x)`

Performs a full syntax expansion of the form `x` and returns the resulting s-expression.

#### `(ast->sexp ast)`

Convert `ast` to a s-expression, renaming variables if necessary.

## Identifier Macros

#### `(make-variable-transformer proc)`

Returns a new procedure wrapping the input procedure `proc`. The returned procedure, if used as a macro transformer procedure, can expand an instance of `set!` with its keyword on the left hand side.

#### `(identifier-syntax clauses ...)`

A high-level form for creating identifier macros. See the R6RS specification.

## Types

All objects have an associated type, and types may have parent types. When using SRFI-9 `define-record-type`, the name is bound to a first class type object. The following core types are also available by name, and may be used in the `match` `($ ...)` syntax.

- `Object` - the parent of all types
- `Number` - abstract numeric type
- `Bignum` - arbitrary precision exact integers
- `Flonum` - inexact real numbers
- `Integer` - abstract integer type
- `Symbol` - symbols
- `Char` - character
- `Boolean` - `#t` or `#f`
- `String` - strings of characters
- `Byte-Vector` - uniform vector of octets
- `Pair` - a `car` and `cdr`, the basis for lists
- `Vector` - vectors
- `Opcode` - a primitive opcode or C function
- `Procedure` - a closure
- `Bytecode` - the compiled code for a closure
- `Env` - an environment structure
- `Macro` - a macro object, usually not first-class
- `Lam` - a lambda AST type
- `Cnd` - an conditional AST type (i.e. `if`)
- `Ref` - a reference AST type
- `Set` - a mutation AST type (i.e. `set!`)
- `Seq` - a sequence AST type
- `Lit` - a literal AST type
- `Sc` - a syntactic closure
- `Context` - a context object (including threads)
- `Exception` - an exception object

The following extended type predicates may also be used to test individual objects for their type:

- `environment?`
- `bytecode?`
- `macro?`
- `syntactic-closure?`
- `lambda?`
- `cnd?`
- `ref?`
- `set?`
- `seq?`
- `lit?`
- `opcode?`
- `type?`
- `context?`
- `exception?`

#### `(type-of x)`

Returns the type of any object `x`.

#### `(type-name type)`

Returns the name of type `type`.

#### `(type-parent type)`

Returns the immediate parent of type `type`, or `#f` for a type with no parent.

#### `(type-cpl type)`

Returns the class precedence list of type `type` as a vector, or `#f` for a type with no parent.

#### `(type-slots type)`

Returns the slot list of type `type`.

## Accessors

This section describes additional accessors on AST and other core types.

### Procedures

#### `(procedure-name x)`

- `(procedure-code f)` - the compiled bytecode object
- `(procedure-vars f)` - the variables closed over by `f`
- `(procedure-name f)` - the name of `f` if known, else `#f`

#### `(procedure-name-set! x name)`

### Macros

- `(macro-procedure f)` - the macro procedure
- `(macro-env f)` - the environment the macro was defined in
- `(macro-source f)` - the source location the macro was defined in
- `(macro-aux f)` - custom auxiliary data stored with the macro
- `(macro-aux-set! f x)`

### Bytecode Objects

- `(bytecode-name bc)` - the macro procedure
- `(bytecode-literals bc)` - literals the bytecode references
- `(bytecode-source bc)` - the source location the procedure was defined in

### Syntactic Closures

- `(syntactic-closure-env sc)`
- `(syntactic-closure-vars sc)`
- `(syntactic-closure-expr sc)`

Return the environment, free variables, and expression associated with `sc` respectively.

### Exceptions

- `(exception-kind exn)`
- `(exception-message exn)`
- `(exception-irritants exn)`

Return the kind, message, and irritants associated with `exn` respectively.

### Lambdas

- `(lambda-name lam)` - the name of the lambda, if known
- `(lambda-name-set! lam x)`
- `(lambda-params lam)` - the lambda parameter list
- `(lambda-params-set! lam x)`
- `(lambda-body lam)` - the body of the lambda
- `(lambda-body-set! lam x)`
- `(lambda-defs lam)` - internal definitions of the lambda
- `(lambda-defs-set! lam x)`
- `(lambda-locals lam)` - local variables as a list of identifiers
- `(lambda-locals-set! lam x)`
- `(lambda-flags lam)` - various flags describing the lambda
- `(lambda-flags-set! lam x)`
- `(lambda-free-vars lam)` - free variables the lambda will need to close over
- `(lambda-free-vars-set! lam x)`
- `(lambda-set-vars lam)` - variables the lambda mutates
- `(lambda-set-vars-set! lam x)`
- `(lambda-return-type lam)` - the return type of the lambda
- `(lambda-return-type-set! lam x)`
- `(lambda-param-types lam)` - the types of the input parameters
- `(lambda-param-types-set! lam x)`
- `(lambda-source lam)` - the source code of the lambda
- `(lambda-source-set! lam x)`

### Conditionals

- `(cnd-test cnd)` - the test for the conditional
- `(cnd-test-set! cnd x)`
- `(cnd-pass cnd)` - the success branch
- `(cnd-pass-set! cnd x)`
- `(cnd-fail cnd)` - the failure branch
- `(cnd-fail-set! cnd x)`

### Sequences

- `(seq-ls seq)` - the list of sequence expressions
- `(seq-ls-set! seq x)`

### References

- `(ref-name ref)` - the name of the referenced variable
- `(ref-name-set! ref x)`
- `(ref-cell ref)` - the environment cell the reference resolves to
- `(ref-cell-set! ref x)`

### Mutations

- `(set-var set)` - a reference to the mutated variable
- `(set-var-set! set x)`
- `(set-value set)` - the value to set the variable to
- `(set-value-set! set x)`

### Literals

- `(lit-value lit)` - the literal value
- `(lit-value-set! lit x)`

### Pairs

- `(pair-source x)`
- `(pair-source-set! x source)`

Set or return the source code info associated with a pair x. Source info is represented as another pair whose `car` is the source file name and whose `cdr` is the line number.

## Miscellaneous Utilities

#### `(gc)`

Force a garbage collection.

#### `(object-size x)`

Returns the heap space directly used by `x`, not counting any elements of `x`.

#### `(integer->immediate n)`

Returns the interpretation of the integer `n` as an immediate object, useful for debugging.

#### `(string-contains str pat [start])`

#### `procedure-name-set!`

Returns the first string cursor of `pat` in `str`, of `#f` if it's not found.

#### `(string-cursor-copy! dst src from start end)`

Copies the characters from `src`[`start`..`end`] to `dst` starting at `from`.

#### `(safe-setenv name value)`

Equivalent to `setenv` but does nothing and returns `#f` if `value` is a function definition. Used to circumvent the vulnerability of the shellshock bug.

#### `(atomically expr)`

Run `expr` atomically, disabling yields. Ideally should only be used for brief, deterministic expressions. If used incorrectly (e.g. running an infinite loop) can render the system unusable. Never expose to a sandbox.

#### `(thread-interrupt! thread)`