All Projects → thosakwe → samurai

thosakwe / samurai

Licence: MIT license
JS Interpreter in Dart.

Programming Languages

dart
5743 projects
javascript
184084 projects - #8 most used programming language

samurai

Pub build status

Portable JS engine, written in Dart.

Screenshot in terminal

Possibilities

  • Existing JS libraries that cannot be easily ported can be wrapped (I'm looking at you, Hammer, and esprima!)
  • Server-side rendering of compiled JS apps
    • Will require a headless DOM for Samurai
  • Embedding of sandboxed, safe scripts in Dart applications

Strong Mode

As of this writing, this package is incompatible with strong mode, due to a transitive dependency on package:lists, which is not only old, but has its issue tracker disabled (nice!).

The source of this dependency is unknown, as the dependencies of samurai seem to all be Dart 2-compatible libraries that are frequently used with current versions of Dart, and have either few dependencies or no dependency themselves.

Usage

Command-Line

The samurai executable has similar syntax to Node.js; it can be passed a single argument to execute a file, or none to start a REPL, complete with colorful printing.

Programmatically

In most cases, create a Samurai instance, and inject a console object into its global scope (enabling console.log, etc.):

import 'package:logging/logging.dart';
import 'package:parsejs/parsejs.dart';
import 'package:samurai/samurai.dart';

void main() {
  var samurai = new Samurai();
  var logger = new Logger('samurai');
  samurai.global.properties['console'] = new JsConsole(logger);
}

Next, parse an AST of the source text you wish to execute, and pass it to the interpreter:

void main() {
  // ...
  var program = parsejs('<source text>', filename: 'foo.js');
  samurai.visitProgram(program);
}

Once the program has been run (synchronously!), you might then wish to query its global scope, which is an instance of SymbolTable:

void main() {
  // ...
  var exports = samurai.globalScope.resolve('exports').value;
  print('Exports: ${exports.properties}');
}

Interaction with Dart

If you just wanted a JavaScript interpreter, you'd probably want to use Node.js. samurai's entire API is public; therefore, you can freely exchange data between the two languages.

void main() {
  // ...
  var module = samurai.global.properties['module'] = new JsObject();
  var exports = module.properties['exports'] = new JsObject();
  exports['thirtyTwo'] = new JsNumber(32);
  exports['someFunction'] = new JsFunction(samurai.global, (samurai, arguments, ctx) {
    return new JsString('Hello from Dart!!!');
  });
}

Acknowledgements and Contributions

  • A huge thanks to Asger Feldthaus and his parsejs library.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].