init method
void
init({
- bool useDefaultModuleAndBinding = true,
- Map<
String, Function> externalFunctions = const {}, - Map<
String, HTExternalMethod> externalMethods = const {}, - Map<
String, HTExternalFunctionTypedef> externalFunctionTypedef = const {}, - List<
HTExternalClass> externalClasses = const [], - List<
HTExternalTypeReflection> externalTypeReflections = const [],
Initialize the interpreter, prepare it with preincluded modules, bind it with HTExternalFunction, HTExternalFunctionTypedef, HTExternalClass, etc.
A uninitted Hetu can still eval certain script,
it cannot use any of the pre-included functions like print and the Dart apis on number & string, etc.
Implementation
void init({
bool useDefaultModuleAndBinding = true,
Map<String, Function> externalFunctions = const {},
Map<String, HTExternalMethod> externalMethods = const {},
Map<String, HTExternalFunctionTypedef> externalFunctionTypedef = const {},
List<HTExternalClass> externalClasses = const [],
List<HTExternalTypeReflection> externalTypeReflections = const [],
}) {
if (_isInitted) return;
if (useDefaultModuleAndBinding) {
final numBinding = HTNumberClassBinding();
final iterableBinding = HTIterableClassBinding();
interpreter.bindExternalClass(numBinding);
interpreter
.bindExternalClass(HTIntegerClassBinding(superClass: numBinding));
interpreter
.bindExternalClass(HTFloatClassBinding(superClass: numBinding));
interpreter.bindExternalClass(HTBigIntClassBinding());
interpreter.bindExternalClass(HTBooleanClassBinding());
interpreter.bindExternalClass(HTStringClassBinding());
interpreter.bindExternalClass(HTIteratorClassBinding());
interpreter.bindExternalClass(iterableBinding);
interpreter
.bindExternalClass(HTListClassBinding(superClass: iterableBinding));
interpreter
.bindExternalClass(HTSetClassBinding(superClass: iterableBinding));
interpreter.bindExternalClass(HTMapClassBinding());
interpreter.bindExternalClass(HTRandomClassBinding());
interpreter.bindExternalClass(HTFutureClassBinding());
interpreter.bindExternalClass(HTCryptoClassBinding());
interpreter.bindExternalClass(HTConsoleClassBinding(console: console));
interpreter.bindExternalClass(HTJSONClassBinding(lexicon: lexicon));
// bind dynamic external functions or static method
interpreter.bindExternalFunction('print',
({positionalArgs, namedArgs}) => console.log(positionalArgs));
interpreter.bindExternalFunction(
'eval', ({positionalArgs, namedArgs}) => eval(positionalArgs.first));
interpreter.bindExternalFunction('require',
({positionalArgs, namedArgs}) => require(positionalArgs.first));
interpreter.bindExternalFunction(
'help', ({positionalArgs, namedArgs}) => help(positionalArgs.first));
interpreter.bindExternalFunction('Object.fromJSON', (
{positionalArgs, namedArgs}) {
final jsonData = positionalArgs.first as Map<dynamic, dynamic>;
return interpreter.createStructfromJSON(jsonData);
});
interpreter.bindExternalFunction('Object.assign', (
{positionalArgs, namedArgs}) {
final target = positionalArgs[0] as HTStruct;
final source = positionalArgs[1] as HTStruct;
target.assign(source);
});
interpreter.bindExternalFunction('Object.merge', (
{positionalArgs, namedArgs}) {
final target = positionalArgs[0] as HTStruct;
final source = positionalArgs[1] as HTStruct;
target.merge(source);
});
// bind dynamic external method
interpreter.bindExternalMethod('ClassRoot::toString', (
{object, positionalArgs, namedArgs}) {
return lexicon.stringify(object);
});
interpreter.bindExternalMethod('Object::iterator', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.keys.iterator;
});
interpreter.bindExternalMethod('Object::keys', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.keys;
});
interpreter.bindExternalMethod('Object::values', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.values;
});
interpreter.bindExternalMethod('Object::contains', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.contains(positionalArgs.first);
});
interpreter.bindExternalMethod('Object::containsKey', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.containsKey(positionalArgs.first);
});
interpreter.bindExternalMethod('Object::isEmpty', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.isEmpty;
});
interpreter.bindExternalMethod('Object::isNotEmpty', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.isNotEmpty;
});
interpreter.bindExternalMethod('Object::length', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.length;
});
interpreter.bindExternalMethod('Object::remove', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
struct.remove(positionalArgs.first);
});
interpreter.bindExternalMethod('Object::clone', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
return struct.clone();
});
interpreter.bindExternalMethod('Object::assign', (
{object, positionalArgs, namedArgs}) {
final struct = object as HTStruct;
final other = positionalArgs.first as HTStruct;
struct.assign(other);
});
// must convert the return type to let dart know its return value type.
interpreter.bindExternalFunctionType(
'VoidCallback',
(HTFunction function) {
return () {
return function.call();
};
},
);
interpreter.bindExternalFunctionType(
'ValueCallback',
(HTFunction function) {
return (value) {
return function.call(positionalArgs: [value]);
};
},
);
// bind non-dynamic external functions
for (var key in preincludeFunctions.keys) {
interpreter.bindExternalFunction(key, preincludeFunctions[key]!);
}
// load precompiled core module.
final coreModule = Uint8List.fromList(hetuCoreModule);
interpreter.loadBytecode(
bytes: coreModule,
module: 'hetu',
globallyImport: true,
);
interpreter.define(
'kHetuVersion',
HTValueBinding(
id: 'kHetuVersion',
value: kHetuVersion.toString(),
isMutable: false,
),
);
interpreter.define(
lexicon.kThis,
HTValueBinding(
id: lexicon.kThis,
value: interpreter.globalNamespace,
isMutable: false,
),
);
interpreter.define(
lexicon.idGlobal,
HTValueBinding(
id: lexicon.idGlobal,
value: interpreter.globalNamespace,
isMutable: false,
),
);
// interpreter.assign('console', console);
HTInterpreter.classRoot = interpreter.globalNamespace
.memberGet(lexicon.idGlobalObject, isRecursive: true);
HTInterpreter.structRoot = interpreter.globalNamespace
.memberGet(lexicon.idGlobalPrototype, isRecursive: true);
}
for (final key in externalFunctions.keys) {
interpreter.bindExternalFunction(key, externalFunctions[key]!);
}
for (final key in externalMethods.keys) {
interpreter.bindExternalMethod(key, externalMethods[key]!);
}
for (final key in externalFunctionTypedef.keys) {
interpreter.bindExternalFunctionType(key, externalFunctionTypedef[key]!);
}
for (final value in externalClasses) {
interpreter.bindExternalClass(value);
}
for (final value in externalTypeReflections) {
interpreter.bindExternalReflection(value);
}
interpreter.currentNamespace = interpreter.globalNamespace;
_isInitted = true;
}