SPPCompiler.Compiler.Program module¶
- class SPPCompiler.Compiler.Program.Program¶
Bases:
CompilerStages
The Program class holds a list of modules and performs each stage of the compiler on them. It is interacted with from the Compiler class, and is used to abstract boilerplate code per compiler stage.
- modules: list[Asts.ModulePrototypeAst]¶
- llvm_modules: list[ir.Module]¶
The list of module prototype ASTs (from parsing).
- lex(progress_bar=None, module_tree=None)¶
Lex every module into a list of tokens. Move the list of tokens into the
Module
instance. Create anErrorFormatter
for each module, which in turns contains the token list. This allows error messages use the correct set of tokens depending on the source of the error.- Parameters:
progress_bar (Optional[Progress]) – Progress meter for the lexing stage.
module_tree (ModuleTree) – List of modules included in the compilation.
- Return type:
None
- parse(progress_bar=None, module_tree=None)¶
Parse every module’s tokenstream into an AST. Set the AST into the
Module
instance. Save the resultingModulePrototypeAst
nodes into themodules
list on theProgram
.- Parameters:
progress_bar (Optional[Progress]) – Progress meter for the parsing stage.
module_tree (ModuleTree) – List of modules included in the compilation.
- Return type:
None
- Returns:
- pre_process(context, progress_bar=None, module_tree=None)¶
The preprocessor stage performs mutations on ASTs, introduces new ASTs, and removes some ASTs. This allows for single-method processing of multiple ASTs, such as functions vs types with function classes superimposed over them. This stage directly affects what symbols are generated. :param ctx: The pre-processing context that owns the AST being pre-processed.
- Return type:
None
- generate_top_level_scopes(sm, progress_bar=None, module_tree=None)¶
! The generate top-level scopes stage generates all module and superimposition level scopes and symbols. This includes classes, attributes, functions, sup-methods, aliases and global constants. No generation is done for symbols inside functions. The symbols are generated here so that they can be used in any module, allowing for circular imports. :param sm The scope manager.
- Return type:
None
- generate_top_level_aliases(sm, progress_bar=None, module_tree=None)¶
! The generate top-level aliases stage generates all aliases at the module/sup level. This must come after the symbol generation stage, as it requires symbol knowledge to attach the correct “old types”. It must also come before the load sup scopes stage, because superimposing over aliases requires the alias to exist beforehand, in any order of compilation. :param sm The scope manager. :param kwargs Additional keyword arguments.
- Return type:
None
- qualify_types(sm, progress_bar=None, module_tree=None)¶
… :type sm: ScopeManager :param sm: :param kwargs: :rtype: None :return:
- load_super_scopes(sm, progress_bar=None, attachment_progress_bar=None, module_tree=None)¶
- Return type:
None
- pre_analyse_semantics(sm, progress_bar=None, module_tree=None)¶
- Return type:
None
- analyse_semantics(sm, progress_bar=None, module_tree=None)¶
The semantic analysis stage is the most complex, and final analysis, stage of the semantic pipeline. This stage performs all the semantic checks, type inference, and type checking. This stage requires all symbols to be generated, and all types to be aliased, loaded, and post-processed. All functions scopes are inspected. :param sm The scope manager. :param kwargs Additional keyword arguments.
- Return type:
None
- check_memory(sm, progress_bar=None, module_tree=None)¶
The check memory stage is the final stage of the semantic pipeline. This stage performs all the memory checks, and has to happen after, and not during semantic analysis, because sometimes the ASTs are analysed out of order to allow for type-inference. This messes up the strict order of memory checks, so the additional stage enforces the order of memory checks. :type sm: ScopeManager :param sm: The scope manager. :param kwargs: Additional keyword arguments.
- Return type:
None
- code_gen_pass_1(sm, progress_bar=None, module_tree=None)¶
The first pass of the code generation handles declarations. This includes type declarations (no memory layout set), and function declarations (no body set). This is because for class attributes, the types need to have already been created :type sm: ScopeManager :param sm: The scope manager. :param llvm_module: The LLVM module to generate code for. :param kwargs: Additional keyword arguments.
- Return type:
list[ir.Module]
- code_gen_pass_2(sm, progress_bar=None, module_tree=None)¶
The second pass of the code generation handles definitions. This includes type definitions (memory layout set), and function definitions (body set). :type sm: ScopeManager :param sm: The scope manager. :param llvm_module: The LLVM module to generate code for. :param kwargs: Additional keyword arguments.
- Return type:
None