Skip to content

Internals: the compiler

Nico Williams edited this page Jul 31, 2023 · 2 revisions

The compiler consists of two parts: the parser (see src/parser.y), compiled with Bison, and utilities and bytecode generator in src/compile.c. The intermediate representation of jq programs uses the block C type, which is described in some detail in src/compile.c, and which consists of lists (really, trees, when sub-functions and argument list blocks are accounted for) of "blocks" of instructions.

The bytecode representation is as arrays of 16-bit values, and is produced as the last step of compilation, after a complete program block tree is linked.

Linking (src/linker.c) happens at the block representation stage. The defs in each file (e.g., ~/.jq, the upcoming library/module system, and the main program) are bound to each other from right to left using block_bind() and related functions. Libraries are bound to programs using block_bind_referenced(), which is like block_bind(), but drops unreferenced defs; this happens outside the parser.

TODO: Expand on this extensively.

Clone this wiki locally