Internals: the compiler - troyp/jq GitHub Wiki

The compiler consists of two parts: the parser (see parser.y), compiled with Bison, and utilities and bytecode generator in compile.c. The intermediate representation of jq programs uses the block C type, which is described in some detail in 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 happens at the block representation stage, mostly in the parser as defs and expressions are parsed into block representation. 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() -- this happens in the parser. Libraries are bound to programs using block_bind_referenced(), which is like block_bind(), but drops unreferenced defs; this happens outside the parser.