This module contains the code generation logic for VanCode. It takes the AST produced by your parser and generates bytecode for it, which can then be executed by the VM.
The code generator is designed to be modular and extensible, allowing you to easily hook into the code generation process to add support for new language features.
Types
CodeGen {.acyclic.} = ref object module*: Module ## the global scope for this code generator. this is where all ## global variables and procs are declared case of gkToplevel, gkHtmlNest: nil of gkProc, gkBlockProc: of gkIterator: parserCallback*: ParserCallback ## a callback used to parse custom nodes allowExprResult*: bool
- a code generator for a module or proc.
CodeGenCache = object cachedAst*: Table[string, Ast]
- A cache for code generation. This is used to store the ASTs of included files, so that they don't need to be re-parsed every time they're included
ParserCallback = proc (astProgram: var Ast; path: string)
- Used to parse custom nodes during code generation.
Procs
proc addIterator(script: Script; module: Module; name: string) {....raises: [], tags: [], forbids: [].}
- Add a foreign iterator into the specified module.
proc collectGenericParams(gen: CodeGen; genericParams: Node): Option[seq[Sym]] {. ...raises: [KeyError, CodeGenError, ValueError, Exception], tags: [RootEffect], forbids: [].}
proc genArrayAccess(gen: CodeGen; node: Node): Sym {. ...raises: [Exception, CodeGenError, ValueError, KeyError], tags: [RootEffect], forbids: [].}
proc genComment(gen: CodeGen; node: Node) {....raises: [], tags: [], forbids: [].}
proc genContinue(gen: CodeGen; node: Node) {....raises: [CodeGenError, ValueError], tags: [], forbids: [].}
proc genGetField(gen: CodeGen; node: Node): Sym {. ...raises: [Exception, KeyError, CodeGenError, ValueError], tags: [RootEffect], forbids: [].}
proc genIterator(gen: CodeGen; node: Node; isInstantiation = false): Sym {. ...raises: [KeyError, CodeGenError, ValueError, Exception], tags: [RootEffect], forbids: [].}
proc genObjectStorage(gen: CodeGen; node: Node; isInstantiation = false): Sym {. ...raises: [CodeGenError, ValueError, KeyError, Exception], tags: [RootEffect], forbids: [].}
proc genTypeDef(gen: CodeGen; node: Node): Sym {....raises: [Exception], tags: [RootEffect], forbids: [].}
proc getDefaultSym(gen: CodeGen; kind: NodeKind): Sym {....raises: [KeyError], tags: [], forbids: [].}
- Returns the default type for the given node kind.
proc initCodeGen(script: Script; module: Module; chunk: Chunk; kind = gkToplevel; ctxAllocator: ContextAllocator = nil; pkgr: Packager = nil; parserCallback: ParserCallback = nil): CodeGen {. ...raises: [], tags: [], forbids: [].}
proc initCompiler(script: Script; module: Module; chunk: Chunk; pkgr: Packager; stdlibs: StandardLibrary; parserCallback: ParserCallback = nil; triggerFromPath: Option[string] = none(string)): CodeGen {. ...raises: [], tags: [], forbids: [].}
-
Initialize a new code generator with a new script and module
This is the main entry point for code generation, and can be called by your main module or by other modules to initialize code generation for a new script
proc newProc(script: Script; name, impl: Node; params: seq[ProcParam]; returnTy: Sym; kind: ProcKind; exported = false; genKind: GenKind = gkToplevel): (Sym, Proc) {. ...raises: [CodeGenError, ValueError], tags: [], forbids: [].}
- Creates a procedure for the given script. Returns its symbol and Proc object. This does not add the procedure to the script!
proc resolveGenerics(gen: CodeGen; callable: var Sym; callArgTypes: seq[Sym]; errorNode: Node) {....raises: [KeyError, Exception, CodeGenError, ValueError], tags: [RootEffect], forbids: [].}
- Helper used to resolve generic parameters via inference.
proc tryElideWhile(gen: CodeGen; node: Node): bool {. ...raises: [CodeGenError, ValueError, Exception, KeyError], tags: [RootEffect], forbids: [].}