Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1792)

Unified Diff: packages/petitparser/test/lisp_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « packages/petitparser/test/json_test.dart ('k') | packages/petitparser/test/petitparser_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/petitparser/test/lisp_test.dart
diff --git a/packages/petitparser/test/lisp_test.dart b/packages/petitparser/test/lisp_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..2c88884ce90638b51a148135ecec3cbd13697e22
--- /dev/null
+++ b/packages/petitparser/test/lisp_test.dart
@@ -0,0 +1,438 @@
+library petitparser.test.lisp_test;
+
+import 'package:test/test.dart';
+
+import 'package:petitparser/lisp.dart';
+
+void main() {
+ var root = new Environment();
+ var native = Natives.import(root);
+ var standard = Standard.import(native.create());
+
+ dynamic exec(String value, [Environment env]) {
+ return evalString(lispParser, env != null ? env : standard.create(), value);
+ }
+
+ group('Cell', () {
+ test('Name', () {
+ var cell1 = new Name('foo');
+ var cell2 = new Name('foo');
+ var cell3 = new Name('bar');
+ expect(cell1, cell2);
+ expect(cell1, same(cell2));
+ expect(cell1, isNot(cell3));
+ expect(cell1, isNot(same(cell3)));
+ });
+ test('Cons', () {
+ var cell = new Cons(1, 2);
+ expect(cell.head, 1);
+ expect(cell.tail, 2);
+ cell.head = 3;
+ expect(cell.head, 3);
+ expect(cell.tail, 2);
+ cell.tail = new Cons(4, 5);
+ expect(cell.head, 3);
+ expect(cell.tail.head, 4);
+ expect(cell.tail.tail, 5);
+ expect(cell == cell, isTrue);
+ expect(cell.hashCode, isNonZero);
+ expect(cell.toString(), '(3 4 . 5)');
+ });
+ });
+ group('Environment', () {
+ var env = standard.create();
+ test('Standard', () {
+ expect(env.owner, isNotNull);
+ expect(env.keys, isEmpty);
+ expect(env.owner.keys, isNot(isEmpty));
+ });
+ test('Create', () {
+ var sub = env.create();
+ expect(sub.owner, same(env));
+ expect(sub.keys, isEmpty);
+ });
+ });
+ group('Parser', () {
+ var definition = new LispParserDefinition();
+ var atom = definition.build(start: definition.atom);
+ test('Name', () {
+ var cell = atom.parse('foo').value;
+ expect(cell, new isInstanceOf<Name>());
+ expect(cell.toString(), 'foo');
+ });
+ test('Name for operator', () {
+ var cell = atom.parse('+').value;
+ expect(cell, new isInstanceOf<Name>());
+ expect(cell.toString(), '+');
+ });
+ test('Name for special', () {
+ var cell = atom.parse('set!').value;
+ expect(cell, new isInstanceOf<Name>());
+ expect(cell.toString(), 'set!');
+ });
+ test('String', () {
+ var cell = atom.parse('"foo"').value;
+ expect(cell, new isInstanceOf<String>());
+ expect(cell, 'foo');
+ });
+ test('String with escape', () {
+ var cell = atom.parse('"\\""').value;
+ expect(cell, '"');
+ });
+ test('Number integer', () {
+ var cell = atom.parse('123').value;
+ expect(cell, 123);
+ });
+ test('Number negative integer', () {
+ var cell = atom.parse('-123').value;
+ expect(cell, -123);
+ });
+ test('Number positive integer', () {
+ var cell = atom.parse('+123').value;
+ expect(cell, 123);
+ });
+ test('Number floating', () {
+ var cell = atom.parse('123.45').value;
+ expect(cell, 123.45);
+ });
+ test('Number floating exponential', () {
+ var cell = atom.parse('1.23e4').value;
+ expect(cell, 1.23e4);
+ });
+ test('List empty', () {
+ var cell = atom.parse('()').value;
+ expect(cell, isNull);
+ });
+ test('List empty []', () {
+ var cell = atom.parse('[ ]').value;
+ expect(cell, isNull);
+ });
+ test('List empty {}', () {
+ var cell = atom.parse('{ }').value;
+ expect(cell, isNull);
+ });
+ test('List one element', () {
+ var cell = atom.parse('(1)').value;
+ expect(cell, new isInstanceOf<Cons>());
+ expect(cell.head, 1);
+ expect(cell.tail, isNull);
+ });
+ test('List two elements', () {
+ var cell = atom.parse('(1 2)').value;
+ expect(cell, new isInstanceOf<Cons>());
+ expect(cell.head, 1);
+ expect(cell.tail, new isInstanceOf<Cons>());
+ expect(cell.tail.head, 2);
+ expect(cell.tail.tail, isNull);
+ });
+ test('List three elements', () {
+ var cell = atom.parse('(+ 1 2)').value;
+ expect(cell, new isInstanceOf<Cons>());
+ expect(cell.head, new isInstanceOf<Name>());
+ expect(cell.head.toString(), '+');
+ expect(cell.tail, new isInstanceOf<Cons>());
+ expect(cell.tail.head, 1);
+ expect(cell.tail.tail, new isInstanceOf<Cons>());
+ expect(cell.tail.tail.head, 2);
+ expect(cell.tail.tail.tail, isNull);
+ });
+ });
+ group('Natives', () {
+ test('Define', () {
+ expect(exec('(define a 1)'), 1);
+ expect(exec('(define a 2) a'), 2);
+ expect(exec('((define (a) 3))'), 3);
+ expect(exec('(define (a) 4) (a)'), 4);
+ expect(exec('((define (a x) x) 5)'), 5);
+ expect(exec('(define (a x) x) (a 6)'), 6);
+ });
+ test('Lambda', () {
+ expect(exec('((lambda () 1) 2)'), 1);
+ expect(exec('((lambda (x) x) 2)'), 2);
+ expect(exec('((lambda (x) (+ x x)) 2)'), 4);
+ expect(exec('((lambda (x y) (+ x y)) 2 4)'), 6);
+ expect(exec('((lambda (x y z) (+ x y z)) 2 4 6)'), 12);
+ });
+ test('Quote', () {
+ expect(exec('(quote)'), null);
+ expect(exec('(quote 1)'), new Cons(1, null));
+ expect(exec('(quote + 1)'), new Cons(new Name('+'), new Cons(1, null)));
+ });
+ test('Quote (syntax)', () {
+ expect(exec('\'()'), null);
+ expect(exec('\'(1)'), new Cons(1, null));
+ expect(exec('\'(+ 1)'), new Cons(new Name('+'), new Cons(1, null)));
+ });
+ test('Eval', () {
+ expect(exec('(eval (quote + 1 2))'), 3);
+ });
+ test('Apply', () {
+ expect(exec('(apply + 1 2 3)'), 6);
+ expect(exec('(apply + 1 2 3 (+ 2 2))'), 10);
+ });
+ test('Let', () {
+ expect(exec('(let ((a 1)) a)'), 1);
+ expect(exec('(let ((a 1) (b 2)) a)'), 1);
+ expect(exec('(let ((a 1) (b 2)) b)'), 2);
+ expect(exec('(let ((a 1) (b 2)) (+ a b))'), 3);
+ expect(exec('(let ((a 1) (b 2)) (+ a b) 4)'), 4);
+ });
+ test('Set!', () {
+ var env = standard.create();
+ env.define(new Name('a'), null);
+ expect(exec('(set! a 1)', env), 1);
+ expect(exec('(set! a (+ 1 2))', env), 3);
+ expect(exec('(set! a (+ 1 2)) (+ a 1)', env), 4);
+ });
+ test('Set! (undefined)', () {
+ expect(() => exec('(set! a 1)'), throws);
+ expect(() => standard[new Name('a')], throws);
+ });
+ test('If', () {
+ expect(exec('(if true)'), isNull);
+ expect(exec('(if false)'), isNull);
+ expect(exec('(if true 1)'), 1);
+ expect(exec('(if false 1)'), isNull);
+ expect(exec('(if true 1 2)'), 1);
+ expect(exec('(if false 1 2)'), 2);
+ });
+ test('If (lazyness)', () {
+ expect(exec('(if (= 1 1) 3 4)'), 3);
+ expect(exec('(if (= 1 2) 3 4)'), 4);
+ });
+ test('While', () {
+ var env = standard.create();
+ env.define(new Name('a'), 0);
+ exec('(while (< a 3) (set! a (+ a 1)))', env);
+ expect(env[new Name('a')], 3);
+ });
+ test('True', () {
+ expect(exec('true'), isTrue);
+ });
+ test('False', () {
+ expect(exec('false'), isFalse);
+ });
+ test('And', () {
+ expect(exec('(and)'), isTrue);
+ expect(exec('(and true)'), isTrue);
+ expect(exec('(and false)'), isFalse);
+ expect(exec('(and true true)'), isTrue);
+ expect(exec('(and true false)'), isFalse);
+ expect(exec('(and false true)'), isFalse);
+ expect(exec('(and false false)'), isFalse);
+ expect(exec('(and true true true)'), isTrue);
+ expect(exec('(and true true false)'), isFalse);
+ expect(exec('(and true false true)'), isFalse);
+ expect(exec('(and true false false)'), isFalse);
+ expect(exec('(and false true true)'), isFalse);
+ expect(exec('(and false true false)'), isFalse);
+ expect(exec('(and false false true)'), isFalse);
+ expect(exec('(and false false false)'), isFalse);
+ });
+ test('And (lazyness)', () {
+ var env = standard.create();
+ env.define(new Name('a'), null);
+ exec('(and false (set! a true))', env);
+ expect(env[new Name('a')], isNull);
+ exec('(and true (set! a true))', env);
+ expect(env[new Name('a')], isTrue);
+ });
+ test('Or', () {
+ expect(exec('(or)'), isFalse);
+ expect(exec('(or true)'), isTrue);
+ expect(exec('(or false)'), isFalse);
+ expect(exec('(or true true)'), isTrue);
+ expect(exec('(or true false)'), isTrue);
+ expect(exec('(or false true)'), isTrue);
+ expect(exec('(or false false)'), isFalse);
+ expect(exec('(or true true true)'), isTrue);
+ expect(exec('(or true true false)'), isTrue);
+ expect(exec('(or true false true)'), isTrue);
+ expect(exec('(or true false false)'), isTrue);
+ expect(exec('(or false true true)'), isTrue);
+ expect(exec('(or false true false)'), isTrue);
+ expect(exec('(or false false true)'), isTrue);
+ expect(exec('(or false false false)'), isFalse);
+ });
+ test('Or (lazyness)', () {
+ var env = standard.create();
+ env.define(new Name('a'), null);
+ exec('(or true (set! a true))', env);
+ expect(env[new Name('a')], isNull);
+ exec('(or false (set! a true))', env);
+ expect(env[new Name('a')], isTrue);
+ });
+ test('Not', () {
+ expect(exec('(not true)'), isFalse);
+ expect(exec('(not false)'), isTrue);
+ });
+ test('Add', () {
+ expect(exec('(+ 1)'), 1);
+ expect(exec('(+ 1 2)'), 3);
+ expect(exec('(+ 1 2 3)'), 6);
+ expect(exec('(+ 1 2 3 4)'), 10);
+ });
+ test('Sub', () {
+ expect(exec('(- 1)'), -1);
+ expect(exec('(- 1 2)'), -1);
+ expect(exec('(- 1 2 3)'), -4);
+ expect(exec('(- 1 2 3 4)'), -8);
+ });
+ test('Mul', () {
+ expect(exec('(* 2)'), 2);
+ expect(exec('(* 2 3)'), 6);
+ expect(exec('(* 2 3 4)'), 24);
+ });
+ test('Div', () {
+ expect(exec('(/ 24)'), 24);
+ expect(exec('(/ 24 3)'), 8);
+ expect(exec('(/ 24 3 2)'), 4);
+ });
+ test('Mod', () {
+ expect(exec('(% 24)'), 24);
+ expect(exec('(% 24 5)'), 4);
+ expect(exec('(% 24 5 3)'), 1);
+ });
+ test('Less', () {
+ expect(exec('(< 1 2)'), isTrue);
+ expect(exec('(< 1 1)'), isFalse);
+ expect(exec('(< 2 1)'), isFalse);
+ });
+ test('Less equal', () {
+ expect(exec('(<= 1 2)'), isTrue);
+ expect(exec('(<= 1 1)'), isTrue);
+ expect(exec('(<= 2 1)'), isFalse);
+ });
+ test('Equal', () {
+ expect(exec('(= 1 1)'), isTrue);
+ expect(exec('(= 1 2)'), isFalse);
+ expect(exec('(= 2 1)'), isFalse);
+ });
+ test('Not equal', () {
+ expect(exec('(!= 1 1)'), isFalse);
+ expect(exec('(!= 1 2)'), isTrue);
+ expect(exec('(!= 2 1)'), isTrue);
+ });
+ test('Larger', () {
+ expect(exec('(> 1 1)'), isFalse);
+ expect(exec('(> 1 2)'), isFalse);
+ expect(exec('(> 2 1)'), isTrue);
+ });
+ test('Larger equal', () {
+ expect(exec('(>= 1 1)'), isTrue);
+ expect(exec('(>= 1 2)'), isFalse);
+ expect(exec('(>= 2 1)'), isTrue);
+ });
+ test('Cons', () {
+ expect(exec('(cons 1 2)'), new Cons(1, 2));
+ });
+ test('Car', () {
+ expect(exec('(car null)'), isNull);
+ expect(exec('(car (cons 1 2))'), 1);
+ });
+ test('Car!', () {
+ expect(exec('(car! null 3)'), isNull);
+ expect(exec('(car! (cons 1 2) 3)'), new Cons(3, 2));
+ });
+ test('Cdr', () {
+ expect(exec('(cdr null)'), isNull);
+ expect(exec('(cdr (cons 1 2))'), 2);
+ });
+ test('Cdr!', () {
+ expect(exec('(cdr! null 3)'), isNull);
+ expect(exec('(cdr! (cons 1 2) 3)'), new Cons(1, 3));
+ });
+ });
+ group('Library', () {
+ test('Null', () {
+ expect(exec('null'), isNull);
+ });
+ test('Null? (true)', () {
+ expect(exec('(null? \'())'), isTrue);
+ expect(exec('(null? null)'), isTrue);
+ });
+ test('Null? (false)', () {
+ expect(exec('(null? 1)'), isFalse);
+ expect(exec('(null? "a")'), isFalse);
+ expect(exec('(null? (quote a))'), isFalse);
+ expect(exec('(null? true)'), isFalse);
+ expect(exec('(null? false)'), isFalse);
+ });
+ test('Length', () {
+ expect(exec('(length \'())'), 0);
+ expect(exec('(length \'(1))'), 1);
+ expect(exec('(length \'(1 1))'), 2);
+ expect(exec('(length \'(1 1 1))'), 3);
+ expect(exec('(length \'(1 1 1 1))'), 4);
+ expect(exec('(length \'(1 1 1 1 1))'), 5);
+ });
+ test('Append', () {
+ expect(exec('(append \'() \'())'), isNull);
+ expect(exec('(append \'(1) \'())'), exec('\'(1)'));
+ expect(exec('(append \'() \'(1))'), exec('\'(1)'));
+ expect(exec('(append \'(1) \'(2))'), exec('\'(1 2)'));
+ expect(exec('(append \'(1 2) \'(3))'), exec('\'(1 2 3)'));
+ expect(exec('(append \'(1) \'(2 3))'), exec('\'(1 2 3)'));
+ });
+ test('List Head', () {
+ expect(exec('(list-head \'(5 6 7) 0)'), 5);
+ expect(exec('(list-head \'(5 6 7) 1)'), 6);
+ expect(exec('(list-head \'(5 6 7) 2)'), 7);
+ expect(exec('(list-head \'(5 6 7) 3)'), isNull);
+ });
+ test('List Tail', () {
+ expect(exec('(list-tail \'(5 6 7) 0)'), exec('\'(6 7)'));
+ expect(exec('(list-tail \'(5 6 7) 1)'), exec('\'(7)'));
+ expect(exec('(list-tail \'(5 6 7) 2)'), isNull);
+ });
+ test('Map', () {
+ expect(exec('(map \'() (lambda (x) (* 2 x)))'), isNull);
+ expect(exec('(map \'(2) (lambda (x) (* 2 x)))'), exec('\'(4)'));
+ expect(exec('(map \'(2 3) (lambda (x) (* 2 x)))'), exec('\'(4 6)'));
+ expect(exec('(map \'(2 3 4) (lambda (x) (* 2 x)))'), exec('\'(4 6 8)'));
+ });
+ test('Inject', () {
+ expect(exec('(inject \'() 5 (lambda (s e) (+ s e 1)))'), 5);
+ expect(exec('(inject \'(2) 5 (lambda (s e) (+ s e 1)))'), 8);
+ expect(exec('(inject \'(2 3) 5 (lambda (s e) (+ s e 1)))'), 12);
+ });
+ });
+ group('Examples', () {
+ test('Fibonacci', () {
+ var env = standard.create();
+ exec('(define (fib n)'
+ ' (if (<= n 1)'
+ ' 1'
+ ' (+ (fib (- n 1)) (fib (- n 2)))))', env);
+ expect(exec('(fib 0)', env), 1);
+ expect(exec('(fib 1)', env), 1);
+ expect(exec('(fib 2)', env), 2);
+ expect(exec('(fib 3)', env), 3);
+ expect(exec('(fib 4)', env), 5);
+ expect(exec('(fib 5)', env), 8);
+ });
+ test('Closure', () {
+ var env = standard.create();
+ exec('(define (mul n)'
+ ' (lambda (x) (* n x)))', env);
+ expect(exec('((mul 2) 3)', env), 6);
+ expect(exec('((mul 3) 4)', env), 12);
+ expect(exec('((mul 4) 5)', env), 20);
+ });
+ test('Object', () {
+ var env = standard.create();
+ exec('(define (counter start)'
+ ' (let ((count start))'
+ ' (lambda ()'
+ ' (set! count (+ count 1)))))', env);
+ exec('(define a (counter 10))', env);
+ exec('(define b (counter 20))', env);
+ expect(exec('(a)', env), 11);
+ expect(exec('(b)', env), 21);
+ expect(exec('(a)', env), 12);
+ expect(exec('(b)', env), 22);
+ expect(exec('(a)', env), 13);
+ expect(exec('(b)', env), 23);
+ });
+ });
+}
« no previous file with comments | « packages/petitparser/test/json_test.dart ('k') | packages/petitparser/test/petitparser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698