| Index: packages/petitparser/example/lispshell/lispshell.dart
|
| diff --git a/packages/petitparser/example/lispshell/lispshell.dart b/packages/petitparser/example/lispshell/lispshell.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9ef6e51c5386e661da1934e06451193a72aa03ed
|
| --- /dev/null
|
| +++ b/packages/petitparser/example/lispshell/lispshell.dart
|
| @@ -0,0 +1,88 @@
|
| +library petitparser.example.lispshell;
|
| +
|
| +import 'dart:io';
|
| +import 'dart:async';
|
| +import 'dart:convert';
|
| +
|
| +import 'package:petitparser/petitparser.dart';
|
| +import 'package:petitparser/lisp.dart';
|
| +
|
| +/// Read, evaluate, print loop.
|
| +void evalInteractive(Parser parser, Environment env, Stream<String> input,
|
| + IOSink output, IOSink error) {
|
| + output.write('>> ');
|
| + input.listen((String line) {
|
| + try {
|
| + output.writeln('=> ${evalString(parser, env, line)}');
|
| + } on ParserError catch (exception) {
|
| + error.writeln('Parser error: ' + exception.toString());
|
| + } on Error catch (exception) {
|
| + error.writeln(exception.toString());
|
| + }
|
| + output.write('>> ');
|
| + });
|
| +}
|
| +
|
| +/// Entry point for the command line interpreter.
|
| +void main(List<String> arguments) {
|
| +
|
| + // default options
|
| + var standardLibrary = true;
|
| + var interactiveMode = false;
|
| + var files = new List();
|
| +
|
| + // parse arguments
|
| + for (var option in arguments) {
|
| + if (option.startsWith('-') && files.isEmpty) {
|
| + if (option == '-n') {
|
| + standardLibrary = false;
|
| + } else if (option == '-i') {
|
| + interactiveMode = true;
|
| + } else if (option == '-?') {
|
| + print('${Platform.executable} lisp.dart -n -i [files]');
|
| + print(' -i enforces the interactive mode');
|
| + print(' -n does not load the standard library');
|
| + exit(0);
|
| + } else {
|
| + print('Unknown option: $option');
|
| + exit(1);
|
| + }
|
| + } else {
|
| + var file = new File(option);
|
| + if (file.existsSync()) {
|
| + files.add(file);
|
| + } else {
|
| + print('File not found: $option');
|
| + exit(2);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // evaluation context
|
| + var environment = Natives.import(new Environment());
|
| +
|
| + // add additional primitives
|
| + environment.define(new Name('exit'), (env, args) => exit(args == null ? 0 : args.head));
|
| + environment.define(new Name('sleep'), (env, args) => sleep(new Duration(milliseconds: args.head)));
|
| +
|
| + // process standard library
|
| + if (standardLibrary) {
|
| + environment = Standard.import(environment.create());
|
| + }
|
| +
|
| + // create empty context
|
| + environment = environment.create();
|
| +
|
| + // process files given as argument
|
| + files.forEach((file) {
|
| + evalString(lispParser, environment, file.readAsStringSync());
|
| + });
|
| +
|
| + // process console input
|
| + if (interactiveMode || files.isEmpty) {
|
| + var input = stdin
|
| + .transform(SYSTEM_ENCODING.decoder)
|
| + .transform(new LineSplitter());
|
| + evalInteractive(lispParser, environment, input, stdout, stderr);
|
| + }
|
| +}
|
|
|