Rumoca
A Modelica compiler written in Rust. Rumoca parses Modelica source files and exports to the DAE IR Format (supporting both implicit and explicit model serialization), or via user-customizable templates using MiniJinja. The DAE IR format is consumed by Cyecca for model simulation, analysis, and Python library integration with CasADi, SymPy, and other backends.
Note: Rumoca is in early development. While already usable for many practical tasks, you may encounter issues. Please file bug reports to help improve the compiler.
Quick Start
# Install
# Compile to DAE IR (JSON)
# Format Modelica files
# Lint Modelica files
Installation
Rust (Compiler, Formatter, Linter)
Python
The Python package bundles the Rust compiler, so no separate Rust installation is needed:
# Compile a Modelica file
=
# Get as JSON string or Python dict
=
=
# Compile from string
=
Rust Library
[]
= "0.7"
use Compiler;
Tools
| Tool | Description |
|---|---|
rumoca |
Main compiler - parses Modelica and exports DAE IR (JSON) |
rumoca-fmt |
Code formatter for Modelica files (like rustfmt) |
rumoca-lint |
Linter for Modelica files (like clippy) |
rumoca-lsp |
Language Server Protocol server for editor integration |
Formatter
Configuration: Create .rumoca_fmt.toml in your project:
= 2
= false
= 100
= 1
Linter
Available Rules:
| Rule | Level | Description |
|---|---|---|
naming-convention |
note | CamelCase for types, camelCase for variables |
missing-documentation |
note | Classes without documentation strings |
unused-variable |
warning | Declared but unused variables |
undefined-reference |
error | References to undefined variables |
parameter-no-default |
help | Parameters without default values |
empty-section |
note | Empty equation or algorithm sections |
magic-number |
help | Magic numbers that should be constants |
complex-expression |
note | Overly complex/deeply nested expressions |
inconsistent-units |
warning | Potential unit inconsistencies |
redundant-extends |
warning | Duplicate or circular extends |
Configuration: Create .rumoca_lint.toml in your project:
= "warning"
= ["magic-number", "missing-documentation"]
= false
Custom Code Generation
Rumoca supports MiniJinja templates for custom code generation:
Example template:
# Generated from {{ dae.model_name }}
{% for name, comp in dae.x | items %}
{{ name }}: {{ comp.type_name }} (start={{ comp.start }})
{% endfor %}
See templates/examples/ for complete examples (CasADi, SymPy, Base Modelica).
VSCode Extension
Search for "Rumoca Modelica" in the VSCode Extensions marketplace, or install from the marketplace page.

The extension includes a bundled rumoca-lsp language server - no additional installation required.
Features:
- Syntax highlighting (semantic tokens)
- Real-time diagnostics with type checking
- Autocomplete for keywords, built-in functions, and class members
- Go to definition / Find references
- Document symbols and outline
- Code formatting
- Hover information
- Signature help
- Code folding
- Inlay hints
- Code lens with reference counts
- Rename symbol
- Call hierarchy
- Document links
Configuring Library Paths:
Alternatively, set the MODELICAPATH environment variable. See the extension documentation for details.
Integration with Cyecca
=
# Use model for simulation, analysis, code generation, etc.
Modelica Language Support
Fully Supported
- Class definitions:
model,class,block,connector,record,type,package,function - Components: Declarations with modifications, array subscripts
- Inheritance:
extendsclause with recursive resolution - Equations: Simple, connect, if, for, when equations
- Algorithms: Assignment, if, for, while, when statements
- Expressions: Binary/unary operators, function calls, if-expressions, arrays
- Type prefixes:
flow,stream,discrete,parameter,constant,input,output - Modifications: Component and class modifications
- Packages: Nested packages,
package.mo/package.orderdirectory structure, MODELICAPATH - Imports: Qualified, renamed, unqualified (
.*), selective ({a,b}) - Functions: Single and multi-output functions, tuple equations
(a,b) = func() - Built-in operators:
der(),pre(),reinit(),time, trig functions, array functions - Event functions:
noEvent,smooth,sample,edge,change,initial,terminal - Annotations: Parsed and exported to JSON on components
Partially Supported
| Feature | Status |
|---|---|
| Connect equations | Flow/potential semantics implemented; stream not yet supported |
| External functions | external keyword recognized; no linking |
| Inner/outer | Basic outer→inner resolution implemented; nested scopes in progress |
| Complex operators | Complex record expansion; operator overloading in progress |
Not Yet Implemented
| Feature | Notes |
|---|---|
| Stream connectors | inStream, actualStream operators |
| Redeclarations | redeclare, replaceable parsed only |
| Overloaded operators | operator class prefix recognized only |
| State machines | Synchronous language elements (Ch. 17) |
| Expandable connectors | Dynamic connector sizing |
| Overconstrained connectors | Connections.root, branch, etc. |
MSL Compatibility
Rumoca is tested against the Modelica Standard Library 4.1.0.
| Metric | Result |
|---|---|
| Parse Rate | 100% (2551/2551 files) |
| Compile Rate | 100% (2283/2283 models) |
Balance Check Results:
| Status | Count | Percentage | Description |
|---|---|---|---|
| Balanced | 790 | 34.6% | Fully determined (equations = unknowns) |
| Partial | 1072 | 47.0% | Under-determined by design (external connectors) |
| Unbalanced | 421 | 18.4% | Needs further work |
Partial models have external connector flow variables that receive equations when connected in a larger system.
What Works Well:
- Modelica.Blocks (Integrator, Der, Gain, etc.)
- Modelica.Electrical.Analog.Basic
- Array handling with
size()and parameter-dependent dimensions - Conditional equations with parameter evaluation
- When equations and discrete event handling
Known Limitations (421 unbalanced models):
| Category | Notes |
|---|---|
| Algorithm sections | Assignments not yet counted as equations |
| Complex enumerations | Some types not yet substituted |
| Stream connectors | inStream/actualStream not implemented |
| External functions | Functions without equation bodies |
| Operator records | Operator overloading not implemented |
Architecture
Modelica Source -> Parse -> Flatten -> BLT -> DAE -> DAE IR (JSON)
(AST) (Flat) (Match) (DAE)
|
Cyecca
|
CasADi/SymPy/JAX/etc.
Structural Analysis:
- Hopcroft-Karp matching (O(E√V)) for equation-variable assignment
- Tarjan's SCC algorithm for topological ordering and algebraic loop detection
- Pantelides algorithm for DAE index reduction (detects high-index systems)
- Tearing for algebraic loops (reduces nonlinear system size)
Development
Roadmap
Export Targets:
Import Targets:
- Base Modelica (MCP-0031) - interface with OpenModelica, Dymola, etc.
Contributing
Contributions welcome! All contributions must be made under the Apache-2.0 license.
License
Apache-2.0 (LICENSE)
Citation
See Also
- Modelica IR - DAE IR specification
- Cyecca - Model simulation, analysis, and code generation
- Modelica Language