Linter Demo Errors: 115Warnings: 18File: /home/fstrocco/Dart/dart/benchmark/petitparser/lib/lisp.dart library ppp.lisp; import 'dart:collection'; import 'petitparser.dart'; final lispParser = new LispParser(); eval(Environment env, expr) { if (expr is Cons) { return eval(env, expr.head)(env, expr.tail); } else if (expr is Name) { return env[expr]; } else { return expr; } } evalList(Environment env, expr) { var result = null; while (expr is Cons) { result = eval(env, expr.head); expr = expr.tail; } return result; } evalArguments(Environment env, args) { if (args is Cons) { return new Cons(eval(env, args.head), evalArguments(env, args.tail)); } else { return null; } } evalString(Parser parser, Environment env, String script) { var result = null; for (var cell in parser.parse(script).value) { result = eval(env, cell); } return result; } class Cons { dynamic head; dynamic tail; Cons(this.head, this.tail); @override bool operator ==(other) { return other is Cons && head == other.head && tail == other.tail; } @override int get hashCode => 31 * head.hashCode + tail.hashCode; @override String toString() { var buffer = new StringBuffer(); buffer.write('('); var current = this; while (current is Cons) { buffer.write(current.head.toString()); current = current.tail; if (current != null) { buffer.write(' '); } } if (current != null) { buffer.write('. '); buffer.write(current); } buffer.write(')'); return buffer.toString(); } } class Environment { final Environment _owner; final Map _bindings; Environment([this._owner]) : _bindings = new Map(); Environment create() => new Environment(this); operator [](Name key) { if (_bindings.containsKey(key)) { return _bindings[key]; } else if (_owner != null) { return _owner[key]; } else { return _invalidBinding(key); } } void operator []=(Name key, value) { if (_bindings.containsKey(key)) { _bindings[key] = value; } else if (_owner != null) { _owner[key] = value; } else { _invalidBinding(key); } } define(Name key, value) { return _bindings[key] = value; } Iterable get keys => _bindings.keys; Environment get owner => _owner; _invalidBinding(Name key) { throw new ArgumentError('Unknown binding for $key'); } } class LispGrammar extends GrammarParser { LispGrammar() : super(new LispGrammarDefinition()); } class LispGrammarDefinition extends GrammarDefinition { start() => ref(atom).star().end(); atom() => ref(atom_).trim(ref(space)); atom_() => ref(list) | ref(number) | ref(string) | ref(symbol) | ref(quote) | ref(quasiquote) | ref(unquote) | ref(splice); list() => ref(bracket, '()', ref(cells)) | ref(bracket, '[]', ref(cells)) | ref(bracket, '{}', ref(cells)); cells() => ref(cell) | ref(empty); cell() => ref(atom) & ref(cells); empty() => ref(space).star(); number() => ref(number_).flatten(); number_() => anyIn('-+').optional() & char('0').or(digit().plus()) & char('.').seq(digit().plus()).optional() & anyIn('eE').seq(anyIn('-+').optional()).seq(digit().plus()).optional(); string() => ref(bracket, '""', ref(character).star()); character() => ref(characterEscape) | ref(characterRaw); characterEscape() => char('\\') & any(); characterRaw() => pattern('^"'); symbol() => ref(symbol_).flatten(); symbol_() => pattern('a-zA-Z!#\$%&*/:<=>?@\\^_|~+-') & pattern('a-zA-Z0-9!#\$%&*/:<=>?@\\^_|~+-').star(); quote() => char('\'') & ref(list); quasiquote() => char('`') & ref(list); unquote() => char(',') & ref(list); splice() => char('@') & ref(list); space() => whitespace() | ref(comment); comment() => char(';') & Token.newlineParser().neg().star(); bracket(String brackets, Parser parser) => char(brackets[0]) & parser & char(brackets[1]); } class Name { static final Map _interned = new HashMap(); factory Name(String name) { return _interned.putIfAbsent(name, () => new Name._internal(name)); } final String _name; Name._internal(this._name); String toString() => _name; } class Natives { static Environment import(Environment environment) { environment.define(new Name('define'), _define); environment.define(new Name('lambda'), _lambda); environment.define(new Name('quote'), _quote); environment.define(new Name('eval'), _eval); environment.define(new Name('apply'), _apply); environment.define(new Name('let'), _let); environment.define(new Name('set!'), _set); environment.define(new Name('print'), _print); environment.define(new Name('if'), _if); environment.define(new Name('while'), _while); environment.define(new Name('and'), _and); environment.define(new Name('or'), _or); environment.define(new Name('not'), _not); environment.define(new Name('+'), _plus); environment.define(new Name('-'), _minus); environment.define(new Name('*'), _multiply); environment.define(new Name('/'), _divide); environment.define(new Name('%'), _modulo); environment.define(new Name('<'), _smaller); environment.define(new Name('<='), _smallerOrEqual); environment.define(new Name('='), _equal); environment.define(new Name('!='), _notEqual); environment.define(new Name('>'), _larger); environment.define(new Name('>='), _largerOrEqual); environment.define(new Name('cons'), _cons); environment.define(new Name('car'), _car); environment.define(new Name('car!'), _carSet); environment.define(new Name('cdr'), _cdr); environment.define(new Name('cdr!'), _cdrSet); return environment; } static _define(Environment env, args) { if (args.head is Name) { return env.define(args.head, evalList(env, args.tail)); } else if (args.head.head is Name) { return env.define(args.head.head, _lambda(env, new Cons(args.head.tail, args.tail))); } else { throw new ArgumentError('Invalid define: $args'); } } static _lambda(Environment lambda_env, lambda_args) { return (Environment env, args) { var inner = lambda_env.create(); var names = lambda_args.head; var values = evalArguments(env, args); while (names != null && values != null) { inner.define(names.head, values.head); names = names.tail; values = values.tail; } return evalList(inner, lambda_args.tail); }; } static _quote(Environment env, args) { return args; } static _eval(Environment env, args) { return eval(env.create(), eval(env, args.head)); } static _apply(Environment env, args) { return eval(env, args.head)(env.create(), args.tail); } static _let(Environment env, args) { var inner = env.create(); var binding = args.head; while (binding != null) { inner.define(binding.head.head, eval(env, binding.head.tail.head)); binding = binding.tail; } return evalList(inner, args.tail); } static _set(Environment env, args) { return env[args.head] = eval(env, args.tail.head); } static _print(Environment env, args) { var buffer = new StringBuffer(); while (args != null) { buffer.write(eval(env, args.head)); args = args.tail; } print(buffer); return null; } static _if(Environment env, args) { var condition = eval(env, args.head); if (condition) { if (args.tail != null) { return eval(env, args.tail.head); } } else { if (args.tail != null && args.tail.tail != null) { return eval(env, args.tail.tail.head); } } return null; } static _while(Environment env, args) { var result = null; while (eval(env, args.head)) { result = evalList(env, args.tail); } return result; } static _and(Environment env, args) { while (args != null) { if (!eval(env, args.head)) { return false; } args = args.tail; } return true; } static _or(Environment env, args) { while (args != null) { if (eval(env, args.head)) { return true; } args = args.tail; } return false; } static _not(Environment env, args) { return !eval(env, args.head); } static _plus(Environment env, args) { var value = eval(env, args.head); for (args = args.tail; args != null; args = args.tail) { value += eval(env, args.head); } return value; } static _minus(Environment env, args) { var value = eval(env, args.head); if (args.tail == null) { return -value; } for (args = args.tail; args != null; args = args.tail) { value -= eval(env, args.head); } return value; } static _multiply(Environment env, args) { var value = eval(env, args.head); for (args = args.tail; args != null; args = args.tail) { value *= eval(env, args.head); } return value; } static _divide(Environment env, args) { var value = eval(env, args.head); for (args = args.tail; args != null; args = args.tail) { value /= eval(env, args.head); } return value; } static _modulo(Environment env, args) { var value = eval(env, args.head); for (args = args.tail; args != null; args = args.tail) { value %= eval(env, args.head); } return value; } static _smaller(Environment env, args) { return eval(env, args.head) < eval(env, args.tail.head); } static _smallerOrEqual(Environment env, args) { return eval(env, args.head) <= eval(env, args.tail.head); } static _equal(Environment env, args) { return eval(env, args.head) == eval(env, args.tail.head); } static _notEqual(Environment env, args) { return eval(env, args.head) != eval(env, args.tail.head); } static _larger(Environment env, args) { return eval(env, args.head) > eval(env, args.tail.head); } static _largerOrEqual(Environment env, args) { return eval(env, args.head) >= eval(env, args.tail.head); } static _cons(Environment env, args) { return new Cons(eval(env, args.head), eval(env, args.tail.head)); } static _car(Environment env, args) { var cons = eval(env, args.head); return cons is Cons ? cons.head : null; } static _carSet(Environment env, args) { var cons = eval(env, args.head); if (cons is Cons) { cons.head = eval(env, args.tail.head); } return cons; } static _cdr(Environment env, args) { var cons = eval(env, args.head); return cons is Cons ? cons.tail : null; } static _cdrSet(Environment env, args) { var cons = eval(env, args.head); if (cons is Cons) { cons.tail = eval(env, args.tail.head); } return cons; } } class LispParser extends GrammarParser { LispParser() : super(new LispParserDefinition()); } class LispParserDefinition extends LispGrammarDefinition { list() => super.list().map((each) => each[1]); cell() => super.cell().map((each) => new Cons(each[0], each[1])); empty() => super.empty().map((each) => null); string() => super.string().map((each) => new String.fromCharCodes(each[1])); characterEscape() => super.characterEscape().map((each) => each[1].codeUnitAt(0)); characterRaw() => super.characterRaw().map((each) => each.codeUnitAt(0)); symbol() => super.symbol().map((each) => new Name(each)); number() => super.number().map((each) { var floating = double.parse(each); var integral = floating.toInt(); if (floating == integral && each.indexOf('.') == -1) { return integral; } else { return floating; } }); quote() => super.quote().map((each) => new Cons(Natives._quote, each[1])); } class Standard { static Environment import(Environment environment) { evalString(lispParser, environment, _standardLibrary); return environment; } static String _standardLibrary = """ ; null functions (define null '()) (define (null? x) (= '() x)) ; booleans (define true (and)) (define false (or)) ; list functions (define (length list) (if (null? list) 0 (+ 1 (length (cdr list))))) (define (append list1 list2) (if (null? list1) list2 (cons (car list1) (append (cdr list1) list2)))) (define (list-head list index) (if (= index 0) (car list) (list-head (cdr list) (- index 1)))) (define (list-tail list index) (if (= index 0) (cdr list) (list-tail (cdr list) (- index 1)))) (define (for-each list proc) (while (not (null? list)) (proc (car list)) (set! list (cdr list)))) (define (map list proc) (if (null? list) '() (cons (proc (car list)) (map (cdr list) proc)))) (define (inject list value proc) (if (null? list) value (inject (cdr list) (proc value (car list)) proc))) """; }