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); |
+ } |
+} |