d4rt (pronounced "dart") is an interpreter and runtime for the Dart language, written in Dart.
It allows yo
8000
u to execute Dart code dynamically, bridge native classes, and build advanced scripting or plugin systems in your Dart/Flutter applications.
- Dart interpreter: Run Dart code dynamically at runtime.
- Full generics support: Complete support for generic classes, functions, and type constraints with runtime validation.
- Type bounds checking: Enforce generic type constraints (e.g.,
T extends num
) with dynamic resolution. - Bridging system: Expose your own Dart/Flutter classes, enums, and methods to interpreted code.
- Async/await support: Handle asynchronous code and Futures.
- Class, enum, and extension support: Use most Dart language features, including classes, inheritance, mixins, enums, and extensions.
- Pattern matching: Support for Dart's pattern matching in switch/case and assignments.
- Runtime type validation: Validate generic type arguments and method parameters at runtime.
- Custom logging: Integrated, configurable logger for debugging interpreted code.
- Extensible: Add your own bridges for custom types and native APIs.
Add to your pubspec.yaml
:
dependencies:
d4rt: # latest version
Then run:
dart pub get
import 'package:d4rt/d4rt.dart';
void main() {
final code = '''
int fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
main() {
return fib(6);
}
''';
final interpreter = D4rt();
final result = interpreter.execute(source: code);
print('Result: $result'); // Result: 8
}
You can expose your own Dart classes and enums to the interpreter using the bridge system. Here are minimal examples:
import 'package:d4rt/d4rt.dart';
class MyClass {
int value;
MyClass(this.value);
int doubleValue() => value * 2;
}
final myClassBridge = BridgedClassDefinition(
nativeType: MyClass,
name: 'MyClass',
constructors: {
'': (InterpreterVisitor visitor, List<Object?> positionalArgs, Map<String, Object?> namedArgs) {
if (positionalArgs.length == 1 && positionalArgs[0] is int) {
return MyClass(positionalArgs[0] as int);
}
throw ArgumentError('MyClass constructor expects one integer argument.');
},
},
methods: {
'doubleValue': (InterpreterVisitor visitor, Object target, List<Object?> positionalArgs, Map<String, Object?> namedArgs) {
if (target is MyClass) {
return target.doubleValue();
}
throw TypeError();
},
},
getters: {
'value': (InterpreterVisitor? visitor, Object target) {
if (target is MyClass) {
return target.value;
}
throw TypeError();
},
},
);
void main() {
final interpreter = D4rt();
interpreter.registerBridgedClass(myClassBridge, 'package:example/my_class_library.dart');
final code = '''
import 'package:example/my_class_library.dart';
main() {
var obj = MyClass(21);
return obj.doubleValue();
}
''';
final result = interpreter.execute(source: code);
print(result); // 42
}
import 'package:d4rt/d4rt.dart';
enum Color { red, green, blue }
final colorEnumBridge = BridgedEnumDefinition<Color>(
name: 'Color',
values: Color.values,
);
void main() {
final interpreter = D4rt();
interpreter.registerBridgedEnum(colorEnumBridge, 'package:example/my_enum_library.dart');
final code = '''
import 'package:example/my_enum_library.dart';
main() {
var favoriteColor = Color.green;
print('My favorite color is \${favoriteColor.name}');
return favoriteColor.index;
}
''';
final result = interpreter.execute(source: code);
print(result); // 1
}
Feature | Status / Notes |
---|---|
Classes & Inheritance | ✅ Full support (abstract, inheritance, mixins, interfaces, sealed, base, final) |
Enums | ✅ Full support (fields, methods, static, named values, index, name) |
Mixins | ✅ Supported (declaration, application, on clause, constraints) |
Extensions | ✅ Supported (methods, getters, setters, operators) |
Async/await | ✅ Supported (async functions, await, Futures) |
Pattern matching | ✅ Supported (switch/case, if-case, destructuring, list/map/record patterns) |
Collections (List, Map, Set) | ✅ Supported (literals, spread, if/for, nested, null-aware, records) |
Top-level functions | ✅ Supported (named, anonymous, closures, nested) |
Getters/Setters | ✅ Supported (instance, static, extension, bridge) |
Static members | ✅ Supported (fields, methods, getters/setters, bridge) |
Switch/case | ✅ Supported (classic, pattern, default, fallthrough, exhaustive checks) |
Try/catch/finally | ✅ Supported (multiple catch, on/type, rethrow, stacktrace) |
Imports | ✅ Supported (URIs, show/hide clauses for libraries defined in sources ) |
Generics | ✅ Full support (generic classes/functions, type constraints, runtime validation) |
Operator overloading | |
FFI | 🚫 Not supported |
Isolates | 🚫 Not supported |
Reflection/Mirrors | 🚫 Not supported |
Records | ✅ Supported (positional, named, pattern matching) |
String interpolation | ✅ Supported |
Cascade notation (.. ) |
✅ Supported |
Null safety | ✅ Supported (null-aware ops, checks, patterns) |
Type tests (is , as ) |
✅ Supported |
Exception handling | ✅ Supported (throw, rethrow, custom errors) |
See the documentation for details and limitations.
- Operator overloading is partially supported (via extensions, not via class operator methods).
- Some advanced Dart features (isolates, FFI, mirrors) are not available.
- The interpreter is not a full Dart VM: some language features may behave differently.
Contributions are welcome!
Feel free to open issues, suggest features, or submit pull requests.
MIT License. See LICENSE.
d4rt is a play on the word "dart", using "4" as a stylized "A".
It is pronounced exactly like "dart".