Skip to content
Irakli Gozalishvili edited this page Nov 17, 2013 · 2 revisions

Analyzer takes read wisp code form and performs both syntax & macro expansions over it, producing AST nodes that are hash maps that implement following interface:

```clj
{:type :keyword
 :form '(read data)}
```

The :type key is mapped to a keyword representing the AST variant type. All the AST nodes produced by analyzer comply to some AST type interface described by this document.

The :form key is mapped to an actual form that was analyzed producing AST node containing it. Note that raw forms mapped to the key will also typically have a metadata containing source location information of the node.

Location information contains start (the position of the first character of the parsed source region) & and an end position (the position of the first character after the parsed source region):

Both :start and :end positions contain (0-indexed) :line number and a (0-indexed) :column number that can be obtained as illustrated in the examples below:

```clj
;; Start line position
(:line (:start (meta (:form node))))
;; Start column position
(:column (:start (meta (:form node))))

;; End line position
(:line (:end (meta (:form node))))
;; End columnt position
(:column (:end (meta (:form node))))
```

LiteralNode

Primitive types are represented by an AST nodes of :literal types:

```clj
{:type :literal
 :form Nil | String | Boolean | Number | Pattern | Keyword}
```

Forms in :literal AST node are mapped to primitive types and there for they don't carry any metadata.

IdentifierNode

Identifier nodes typically represent either referces to a specific bindings or an identifiers that define bindings:

```clj
{:type :identifier
 :form Symbol
 :binding DeclarationNode}
```

The :binding is mapped to node representing definition of the binding it references. If node is an identifier of the binding itself, it's :binding is mapped to nil.

There are three types of bindings declarations, but they all implement generic declaration interface:

```clj
{:id IdentifierNode
 :init Node
 :depth Number
 :shadow DeclarationNode
 :form List}
```

The :id is mapped to an IdentifierNode that represents an identifier of the binding itself and there for it's :binding field is mapped to nil.

The :depth is a number representing a depth at which binding shadows the outer scope binding with a same name. If binding does not shadows any outer scope binding it's considered to be shadowing unresolved top level binding and :depth is 1.

The :shadow is mapped to an another, outer scope, Binding node that is being shadowed by this node. If binding node in the outer scope can't be resolved it's mapped to a Binding node of :unresloved-binding type node.

DeclarationNode

There are several type of declaration nodes:

ParameterNode

```clj
{:type :parameter
 :id IdentifierNode
 :depth Number
 :shadow DeclarationNode
 :form Symbol}
```

BindingNode

```clj
{:type :binding
 :id IdentifierNode
 :depth Number
 :shadow DeclarationNode
 :init Node
 :form List}
```

DefinitionNode

```clj
{:type :def
 :doc String | nil
 :id IdentifierNode
 :init Node
 :export Boolean
 :depth Number
 :shadow DeclarationNode
 :init Node}
```

IfNode

```clj
{:type :if
 :test Node
 :consequent Node
 :alternate Node}

ThrowNode

```clj
{:type :throw
 :throw Node
 :form List}
```

AssignmentNode

```clj
{:type :assignment
 :target Node
 :value Node
 :form List}

NewNode

```
{:type :instantiation
 :constructor Node
 :}

Clone this wiki locally