Lisparser
Lisparser is another parser invented by User:Hakerh400 (the previous one was Elevated Parser). Lisparser uses a Lisp-like syntax to parse a Lisp-like source code. This parser does not have an intermediate state. It does not construct abstract syntax tree initially (if we do not count pure lists as tree nodes). Instead, it starts to interpret the program while the program is still being parsed. It saves a lot of time and speeds up the computation.
Overview
The source code of a program that can be parsed using Lisparser consists of elements. Each element is either a list or an identifier. A list contains zero or more elements. An identifier can contain any character except whitespace and parentheses.
Example of a program's source code:
(program (var x 5) (var y 7) (var z (+ x y)) (print z) )
Lisparser can be used to write a simple parser to parse and execute this program (parsing and executing happens at the same time in Lisparser).
Commands
Lisparser has the following commands:
(s x)
- Checks whether elementx
is a scalar (an identifier)(v x)
- Checks whether elementx
is a vector (a list)(ident x)
- Asserts that elementx
is an identifier(ident x y)
- Asserts that elementx
is an identifier whose string representation isy
(list x)
- Asserts that elementx
is a list(uni x)
- Asserts thatx
has exactly one element and returns that element(n x)
- Asserts thatx
is a list and returns its length(m x)
- Asserts thatx
is an ident and returns its name as a string(is-nat x)
- Checks whetherx
is an identifier representing a natural number (but asserts thatx
is an identifier)(is-int x)
- Checks whetherx
is an identifier representing an integer (but asserts thatx
is an identifier)(get-nat x)
- Asserts thatx
is an identifier representing a natural number and returns its value as a bigint(get-int x)
- Asserts thatx
is an identifier representing an integer and returns its value as a bigint(len x y z)
- Asserts thatx
is a list whose length satisfies(lenp x y)
- Asserts thatx
is a list whose length satisfies(lenm x y)
- Asserts thatx
is a list whose length satisfies(e x i)
- Asserts thatx
is a list with at least elements and return -th element (0-indexed)(a x i f)
- Asserts thatx
is a list with at least elements and return its elements as an array starting from index with unary functionf
applied to each element(ta x t f)
- Asserts thatx
is a list with at least 1 element and that the first element is an identifier whose string representation ist
, and return its elements as an array starting from index 1 with unary functionf
applied to each element(empty x)
- Checks whetherx
is an empty list (but asserts thatx
is a list)(type x t)
- Asserts thatx
is a list with at least 1 element and that the first element is an identifier whose string representation ist
(fst x)
- Same as(e x 0)
(snd x)
- Same as(e x 1)
(last x)
- Same as(e x (- (n x) 1))
- this is basically the last element ofx
(elems x)
- Same(a x 0 (lambda (x) x))
- this simply returns all the elements ofx
(which is implicitly asserted to be a list)(ch-num x)
- For an ident returns 0, for a list returns the number of elements(get-ch x i)
- Similar to(e x i)
, but can be used only in recursive iterations (not very important to explain that)(top-down x f)
- Iteratex
as a tree using a top-down iterator callingf
for each element(bottom-up x f)
- Iteratex
as a tree using a bottom-up iterator callingf
for each element(iter x f)
- Iteratex
using a top-down and then bottom-up iterator callingf
for each element and passing an extra argument that is 0 for top-down and 1 for bottom-up(cont)
- Skip a branch in the iteration process(break)
- Skip the entire sub-tree in the iteration process(to-str x)
- Returns a stringified representation ofx
(spacing-type x s)
- For listx
sets the spacing type tos
(used when callingto-str
)(spacing-start x i)
- For listx
sets the spacing start to index (used when callingto-str
) - basically all whitespace between elements before index are space characters, whiles
is used starting from
Exceptions
(err x msg)
- Throws an error with messagemsg
with all relevant information (source file path, line, stack trace and the message)(warn x msg)
- Same aserr
, but shows a warning instead of throwing an error.
Integration with Node.js
The parser is written in Node.js and implements all commands as JavaScript methods. It uses generator functions trick to allow unlimited recursion depth. For example, you can recursively traverse a list containing hundreds of millions of nested lists without triggering a stack overflow.
Examples
Brainlisp is an example of a program that uses Lisparser. See the Brainlisp interpreter.
Interpreters
These interpreters use the parser.