Externum โ Compiler & Transpiler
Pipelineโ
Source (.ext) โ Lexer โ Parser โ AST โ Transpiler โ Target
1. Lexerโ
Tokenises the source into tokens:
- Keywords, identifiers, operators, literals
- Handles f-strings, multi-line strings, comments
- Supports Python-style indentation (optional braces)
2. Parserโ
Recursive descent parser with:
- Full operator precedence (14 levels)
- Expression parsing with Pratt algorithm
- Statement parsing (if, while, for, fn, class, try)
- Error recovery (continues parsing after errors)
3. ASTโ
Abstract syntax tree with typed nodes:
- Expressions: literals, binary ops, function calls, member access
- Statements: assignments, returns, imports, class definitions
- Declarations: functions, classes, modules
4. Transpilerโ
Three target backends:
Python Backendโ
- Direct AST โ Python translation
- Handles all Externum features via Python equivalents
- Generates clean, idiomatic Python output
- Supports all standard library imports
Bash Backendโ
- AST โ Bash script translation
- Limited to shell-compatible constructs
- Functions โ Bash functions
- Loops โ Bash loops
- I/O โ echo/printf/read
Binary Backendโ
- AST โ standalone executable
- Embeds Python interpreter or uses native compilation
- No runtime dependencies
Type Systemโ
Externum is dynamically typed with optional type hints:
fn add(a: int, b: int) -> int {
return a + b
}
Type hints are for documentation and IDE support โ not enforced at runtime.
Module Resolutionโ
# Import from standard library
import math
from string import capitalize
# Import own modules
import mymodule
from mypackage.sub import something
# Import with alias
import collections as coll
Resolution order:
- Check if
.extfile exists in current directory - Check if package directory with
__init__.extexists - Check standard library
Error Reportingโ
Error in file "main.ext" at line 15, column 8:
Undefined variable "x"
13 | fn main() {
14 | y = 10
>> 15 | print(x)
^
16 | }
Testsโ
120/120 tests covering:
- Lexer correctness (all token types)
- Parser correctness (all syntax constructs)
- Python transpiler output (matches expected)
- Bash transpiler output (matches expected)
- Binary compilation (produces runnable output)
- Standard library functions (all implemented)
- Edge cases (empty files, nested constructs, error recovery)