Architecture¶
MultiGen's architecture is designed for extensibility, type safety, and clean separation of concerns.
Overview¶
MultiGen consists of:
- Frontend: Python AST analysis, type inference, optimization
- Pipeline: 7-phase conversion pipeline
- Backends: Language-specific code generation (7 backends)
- Runtime: Self-contained runtime libraries for each backend
- Verification: Optional Z3-based formal verification
7-Phase Pipeline¶
All code conversion goes through these phases:
- Validation -- Parse Python source to AST, validate syntax, check for unsupported constructs
- Analysis -- Analyze types and dependencies, build symbol tables, detect variable scopes
- Python Optimization -- Optimize Python AST, simplify expressions, constant folding
- Mapping -- Map Python constructs to target language (types, operations, containers)
- Target Optimization -- Backend-specific optimizations (inlining, loop unrolling, container selection)
- Generation -- Emit target language code, format, add includes/imports
- Build -- Optional compilation, Makefile generation, runtime library linking
Core Abstractions¶
LanguageBackend¶
Base class for all backends:
class LanguageBackend(ABC):
@abstractmethod
def convert(self, source: str) -> str:
"""Convert Python source to target language"""
@abstractmethod
def get_emitter(self) -> AbstractEmitter:
"""Get code emitter"""
@abstractmethod
def get_factory(self) -> AbstractFactory:
"""Get object factory"""
AbstractEmitter¶
Generates target language code:
class AbstractEmitter(ABC):
@abstractmethod
def emit_function(self, node: ast.FunctionDef) -> str:
"""Emit a function definition"""
@abstractmethod
def emit_class(self, node: ast.ClassDef) -> str:
"""Emit a class definition"""
AbstractFactory¶
Creates backend-specific objects:
class AbstractFactory(ABC):
@abstractmethod
def create_type_mapper(self) -> TypeMapper:
"""Create type mapper"""
@abstractmethod
def create_builder(self) -> AbstractBuilder:
"""Create builder"""
Backend Architecture¶
Each backend follows this structure:
backends/
<language>/
__init__.py # Backend registration
backend.py # LanguageBackend implementation
converter.py # Code converter
factory.py # Object factory
builder.py # Build system
type_inference.py # Type inference (optional)
runtime/ # Runtime library
Design Patterns¶
Visitor Pattern¶
Used for statement conversion in Haskell backend:
class HaskellStatementVisitor(ABC):
@abstractmethod
def visit_assign(self, node: ast.Assign) -> str: ...
class MainFunctionVisitor(HaskellStatementVisitor):
"""IO-based visitor for main()"""
class PureFunctionVisitor(HaskellStatementVisitor):
"""Pure functional visitor"""
Strategy Pattern¶
Used for type inference and loop conversion, shared across C++, Rust, Go backends (30% code reuse):
class TypeInferenceStrategy(ABC):
@abstractmethod
def infer(self, node: ast.AST) -> Optional[str]: ...
class ConstantInferenceStrategy(TypeInferenceStrategy):
"""Infer from literal values"""
class BinOpInferenceStrategy(TypeInferenceStrategy):
"""Infer from binary operations"""
Factory Pattern¶
Creates backend-specific components:
class CFactory(AbstractFactory):
def create_emitter(self) -> CEmitter:
return CEmitter()
def create_builder(self) -> CMakeBuilder:
return CMakeBuilder()
Type System¶
Type Mapping¶
Python types map to backend types:
Python C++ Rust Go
------ --- ---- --
int int i32 int
float double f64 float64
str std::string String string
list[int] vector<int> Vec<i32> []int
dict[str,int] map<str,int> HashMap<...> map[string]int
set[int] set<int> HashSet<i32> map[int]bool
Runtime Libraries¶
Each backend includes a self-contained runtime:
| Backend | Lines | Notes |
|---|---|---|
| C | ~2,500 | STC container templates, file I/O, string ops |
| C++ | 357 | Header-only, STL wrappers |
| Rust | 304 | Pure std library |
| Go | 413 | Reflection-based comprehensions |
| Haskell | 214 | List/Map/Set helpers |
| OCaml | 216 | Mutable references, association lists |
| LLVM | ~8,300 | C runtime library for native compilation |
Code Quality¶
- 1353 tests (100% passing)
- Strict mypy type checking
- 79% complexity reduction (design patterns)
- 49/49 benchmarks passing across all 7 backends