blob: 08d2df0a0d1627cdc72f3065c620c67d234cdcf9 [file] [log] [blame]
library petitparser.example.lispshell;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:petitparser/petitparser.dart';
import '../lisp/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 = <File>[];
// 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
Environment environment = new NativeEnvironment();
// add additional primitives
environment.define(new Name('exit'), (Environment env, Cons args) {
exit(args == null ? 0 : args.head);
});
environment.define(new Name('sleep'), (Environment env, Cons args) {
sleep(new Duration(milliseconds: args.head));
});
// process standard library
if (standardLibrary) {
environment = new StandardEnvironment(environment);
}
// create empty context
environment = environment.create();
// process files given as argument
for (var file in files) {
evalString(lispParser, environment, file.readAsStringSync());
}
// process console input
if (interactiveMode || files.isEmpty) {
var input = stdin.transform(SYSTEM_ENCODING.decoder).transform(const LineSplitter());
evalInteractive(lispParser, environment, input, stdout, stderr);
}
}