yhara-ticketmap 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/.gitignore +2 -0
  2. data/.gitmodules +3 -0
  3. data/MANIFEST +29 -0
  4. data/README.rdoc +20 -0
  5. data/Rakefile +52 -0
  6. data/TODO +82 -0
  7. data/VERSION +1 -0
  8. data/controller/config.rb +9 -0
  9. data/controller/init.rb +7 -0
  10. data/controller/main.rb +11 -0
  11. data/controller/tickets.rb +49 -0
  12. data/db/migrate/001_create_tickets.rb +14 -0
  13. data/db/migrate/002_add_deleted_to_tickets.rb +13 -0
  14. data/db/migrate/003_add_timeouted_to_tickets.rb +13 -0
  15. data/main.rb +40 -0
  16. data/model/init.rb +32 -0
  17. data/model/ticket.rb +49 -0
  18. data/public/biwascheme/lib/biwascheme.js +106 -0
  19. data/public/biwascheme/lib/dumper.js +192 -0
  20. data/public/biwascheme/lib/extra_lib.js +534 -0
  21. data/public/biwascheme/lib/io.js +326 -0
  22. data/public/biwascheme/lib/prototype.js +4320 -0
  23. data/public/biwascheme/lib/r6rs_lib.js +2439 -0
  24. data/public/biwascheme/lib/stackbase.js +1697 -0
  25. data/public/biwascheme/lib/webscheme_lib.js +809 -0
  26. data/public/js/builder.js +136 -0
  27. data/public/js/controls.js +965 -0
  28. data/public/js/dragdrop.js +975 -0
  29. data/public/js/effects.js +1130 -0
  30. data/public/js/scriptaculous.js +60 -0
  31. data/public/js/slider.js +275 -0
  32. data/public/js/sound.js +55 -0
  33. data/public/js/unittest.js +568 -0
  34. data/public/scm/board.scm +23 -0
  35. data/public/scm/hand.scm +48 -0
  36. data/public/scm/main.scm +69 -0
  37. data/public/scm/server.scm +30 -0
  38. data/public/scm/ticket.scm +44 -0
  39. data/spec/config.rb +13 -0
  40. data/spec/helper.rb +2 -0
  41. data/spec/main.rb +13 -0
  42. data/spec/models.rb +34 -0
  43. data/spec/tickets.rb +65 -0
  44. data/ticketmap.gemspec +96 -0
  45. data/view/index.xhtml +63 -0
  46. data/view/track.xhtml +29 -0
  47. metadata +131 -0
@@ -0,0 +1,2439 @@
1
+ //
2
+ // R6RS Base library
3
+ //
4
+
5
+ if( typeof(BiwaScheme)!='object' ) BiwaScheme={}; with(BiwaScheme) {
6
+ /* --------------------------------------- namespace webscheme */
7
+
8
+ ///
9
+ /// Utility functions
10
+ ///
11
+
12
+ //
13
+ // Iterator - external iterator
14
+ //
15
+ BiwaScheme.Iterator = {
16
+ ForArray: Class.create({
17
+ initialize: function(arr){
18
+ this.arr = arr;
19
+ this.i = 0;
20
+ },
21
+ has_next: function(){
22
+ return this.i < this.arr.length;
23
+ },
24
+ next: function(){
25
+ return this.arr[this.i++];
26
+ }
27
+ }),
28
+ ForString: Class.create({
29
+ initialize: function(str){
30
+ this.str = str;
31
+ this.i = 0;
32
+ },
33
+ has_next: function(){
34
+ return this.i < this.str.length;
35
+ },
36
+ next: function(){
37
+ return Char.get(this.str.charAt(this.i++));
38
+ }
39
+ }),
40
+ ForList: Class.create({
41
+ initialize: function(ls){
42
+ this.ls = ls;
43
+ },
44
+ has_next: function(){
45
+ return (this.ls instanceof Pair) && this.ls != nil;
46
+ },
47
+ next: function(){
48
+ var pair = this.ls;
49
+ this.ls = this.ls.cdr;
50
+ return pair;
51
+ }
52
+ }),
53
+ ForMulti: Class.create({
54
+ initialize: function(objs){
55
+ this.objs = objs;
56
+ this.size = objs.length;
57
+ this.iterators = objs.map(function(x){
58
+ return Iterator.of(x);
59
+ })
60
+ },
61
+ has_next: function(){
62
+ for(var i=0; i<this.size; i++)
63
+ if(!this.iterators[i].has_next())
64
+ return false;
65
+
66
+ return true;
67
+ },
68
+ next: function(){
69
+ return this.iterators.map(function(ite){
70
+ return ite.next();
71
+ })
72
+ }
73
+ }),
74
+ of: function(obj){
75
+ switch(true){
76
+ case (obj instanceof Array):
77
+ return new this.ForArray(obj);
78
+ case (typeof(obj) == "string"):
79
+ return new this.ForString(obj);
80
+ case (obj instanceof Pair):
81
+ return new this.ForList(obj);
82
+ default:
83
+ throw new Bug("Iterator.of: unknown class: "+Object.inspect(obj));
84
+ }
85
+ }
86
+ }
87
+
88
+ //
89
+ // Call.foreach - wrapper of Call
90
+ // see "map" function for real example
91
+ //
92
+ BiwaScheme.Call.default_callbacks = {
93
+ call: function(x){ return new Call(this.proc, [x]) },
94
+ result: Prototype.emptyFunction,
95
+ finish: Prototype.emptyFunction
96
+ }
97
+ BiwaScheme.Call.foreach = function(obj, callbacks, is_multi){
98
+ is_multi || (is_multi = false);
99
+ ["call", "result", "finish"].each(function(key){
100
+ if(!callbacks[key])
101
+ callbacks[key] = Call.default_callbacks[key];
102
+ })
103
+
104
+ var iterator = null;
105
+ var x = null;
106
+
107
+ var loop = function(ar){
108
+ if(iterator){
109
+ var ret = callbacks["result"](ar[0], x);
110
+ if(ret !== undefined) return ret;
111
+ }
112
+ else{
113
+ if(is_multi)
114
+ iterator = new Iterator.ForMulti(obj);
115
+ else
116
+ iterator = Iterator.of(obj);
117
+ }
118
+
119
+ if(!iterator.has_next())
120
+ return callbacks["finish"]();
121
+ else{
122
+ x = iterator.next();
123
+ var result = callbacks["call"](x);
124
+ result.after = loop;
125
+ return result;
126
+ }
127
+ }
128
+ return loop(null);
129
+ }
130
+ BiwaScheme.Call.multi_foreach = function(obj, callbacks){
131
+ return Call.foreach(obj, callbacks, true);
132
+ }
133
+
134
+ //
135
+ // define_*func - define library functions
136
+ //
137
+ BiwaScheme.check_arity = function(len, min, max){
138
+ var fname = arguments.callee.caller
139
+ ? arguments.callee.caller.fname
140
+ : "";
141
+ if(len < min){
142
+ if(max && max == min)
143
+ throw new Error(fname+": wrong number of arguments (expected: "+min+" got: "+len+")");
144
+ else
145
+ throw new Error(fname+": too few arguments (at least: "+min+" got: "+len+")");
146
+ }
147
+ else if(max && max < len)
148
+ throw new Error(fname+": too many arguments (at most: "+max+" got: "+len+")");
149
+ }
150
+ BiwaScheme.define_libfunc = function(fname, min, max, func, is_raw){
151
+ var f = function(ar, intp){
152
+ check_arity(ar.length, min, max);
153
+ var result = func(ar, intp);
154
+ if (is_raw) {
155
+ return result;
156
+ }
157
+ else{
158
+ if (result === undefined){
159
+ throw new Bug("library function "+fname+" returned undefined");
160
+ }
161
+ else if (result === null){
162
+ throw new Bug("library function "+fname+" returned null");
163
+ }
164
+ else {
165
+ return result;
166
+ }
167
+ }
168
+ };
169
+
170
+ func["fname"] = fname; // for assert_*
171
+ f["fname"] = fname; // for check_arity
172
+ f["inspect"] = function(){ return this.fname; }
173
+ CoreEnv[fname] = f;
174
+ }
175
+ BiwaScheme.define_libfunc_raw = function(fname, min, max, func){
176
+ BiwaScheme.define_libfunc(fname, min, max, func, true);
177
+ }
178
+ BiwaScheme.define_syntax = function(sname, func) {
179
+ var s = new Syntax(sname, func);
180
+ TopEnv[sname] = s;
181
+ }
182
+ BiwaScheme.define_scmfunc = function(fname, min, max, str){
183
+ (new Interpreter).evaluate("(define "+fname+" "+str+"\n)");
184
+ }
185
+
186
+ // define_scmfunc("map+", 2, null,
187
+ // "(lambda (proc ls) (if (null? ls) ls (cons (proc (car ls)) (map proc (cdr ls)))))");
188
+
189
+ //
190
+ // assert_* : type assertion
191
+ //
192
+ var make_assert = function(check){
193
+ return function(/*args*/){
194
+ var fname = arguments.callee.caller
195
+ ? arguments.callee.caller.fname
196
+ : "";
197
+ check.apply(this, [fname].concat($A(arguments)));
198
+ }
199
+ }
200
+ var make_simple_assert = function(type, test){
201
+ return make_assert(function(fname, obj){
202
+ if(!test(obj))
203
+ throw new Error(fname + ": " + type + " required, but got " + to_write(obj));
204
+ })
205
+ }
206
+ var assert_number = make_simple_assert("number", function(obj){
207
+ return typeof(obj) == 'number' || (obj instanceof Complex);
208
+ })
209
+ var assert_integer = make_simple_assert("integer", function(obj){
210
+ return typeof(obj) == 'number' && (obj % 1 == 0)
211
+ })
212
+ var assert_symbol = make_simple_assert("symbol", function(obj){
213
+ return obj instanceof Symbol;
214
+ })
215
+ var assert_string = make_simple_assert("string", function(obj){
216
+ return typeof(obj) == 'string';
217
+ })
218
+ var assert_vector = make_simple_assert("vector", function(obj){
219
+ return (obj instanceof Array) && (obj.closure_p !== true);
220
+ })
221
+ var assert_pair = make_simple_assert("pair", function(obj){
222
+ return obj instanceof Pair;
223
+ })
224
+ var assert_char = make_simple_assert("character", function(obj){
225
+ return obj instanceof Char;
226
+ })
227
+ var assert_port = make_simple_assert("port", function(obj){
228
+ return obj instanceof Port;
229
+ })
230
+ var assert_date = make_simple_assert("date", function(obj){
231
+ return obj instanceof Date;
232
+ })
233
+ var assert_hashtable = make_simple_assert("hashtable", function(obj){
234
+ return obj instanceof Hash;
235
+ })
236
+ var assert_function = make_simple_assert("JavaScript function", function(obj){
237
+ return (obj instanceof Function) || (typeof obj == 'function');
238
+ })
239
+ var assert_closure = make_simple_assert("scheme function", function(obj){
240
+ return (obj instanceof Array) && (obj.closure_p === true);
241
+ })
242
+ var assert_between = make_assert(function(fname, obj, from, to){
243
+ if( typeof(obj) != 'number' || obj != Math.round(obj) )
244
+ throw new Error(fname + ": " + "number required, but got " + to_write(obj));
245
+
246
+ if( obj < from || to < obj )
247
+ throw new Error(fname + ": " + "number must be between " +
248
+ from + " and " + to + ", but got " + to_write(obj));
249
+ })
250
+ var assert = make_assert(function(fname, test){
251
+ })
252
+
253
+ ///
254
+ /// Classes
255
+ ///
256
+
257
+ BiwaScheme.Complex = Class.create({
258
+ initialize: function(real, imag){
259
+ this.real = real;
260
+ this.imag = imag;
261
+ },
262
+ magnitude: function(){
263
+ return Math.sqrt(this.real * this.real + this.imag * this.imag);
264
+ },
265
+ angle: function(){
266
+ return Math.acos(this.real / this.magnitude());
267
+ }
268
+ })
269
+ BiwaScheme.Complex.from_polar = function(r, theta){
270
+ var real = r * Math.cos(theta);
271
+ var imag = r * Math.sin(theta);
272
+ return new Complex(real, imag);
273
+ }
274
+ BiwaScheme.Complex.assure = function(num){
275
+ if(num instanceof Complex)
276
+ return num
277
+ else
278
+ return new Complex(num, 0);
279
+ }
280
+
281
+ BiwaScheme.Rational = Class.create({
282
+ initialize: function(numerator, denominator){
283
+ this.numerator = numerator;
284
+ this.denominator = denominator;
285
+ }
286
+ })
287
+
288
+ ///
289
+ /// R6RS Base library
290
+ ///
291
+
292
+ //
293
+ // 11.4 Expressions
294
+ //
295
+ // 11.4.1 Quotation
296
+ //(quote)
297
+ // 11.4.2 Procedures
298
+ //(lambda)
299
+ // 11.4.3 Conditionaar
300
+ //(if)
301
+ // 11.4.4 Assignments
302
+ //(set!)
303
+ // 11.4.5 Derived conditionaar
304
+
305
+ define_syntax("cond", function(x){
306
+ var clauses = x.cdr;
307
+ if(!(clauses instanceof Pair) || clauses === nil){
308
+ throw new Error("malformed cond: cond needs list but got " +
309
+ to_write_ss(clauses));
310
+ }
311
+ // TODO: assert that clauses is a proper list
312
+
313
+ var ret = null;
314
+ clauses.to_array().reverse().each(function(clause){
315
+ if(!(clause instanceof Pair)){
316
+ throw new Error("bad clause in cond: " + to_write_ss(clause));
317
+ }
318
+
319
+ if(clause.car === Sym("else")){
320
+ if(ret !== null){
321
+ throw new Error("'else' clause of cond followed by more clauses: " +
322
+ to_write_ss(clauses));
323
+ }
324
+ else if(clause.cdr === nil){
325
+ // pattern A: (else)
326
+ // -> #f ; not specified in R6RS...?
327
+ ret = false;
328
+ }
329
+ else if(clause.cdr.cdr === nil){
330
+ // pattern B: (else expr)
331
+ // -> expr
332
+ ret = clause.cdr.car;
333
+ }
334
+ else{
335
+ // pattern C: (else expr ...)
336
+ // -> (begin expr ...)
337
+ ret = new Pair(Sym("begin"), clause.cdr);
338
+ }
339
+ }
340
+ else if(ret === null){
341
+ // pattern D: no else clause
342
+ // -> #<undef>
343
+ ret = BiwaScheme.undef;
344
+ }
345
+ else{
346
+ var test = clause.car;
347
+ if(clause.cdr === nil){
348
+ // pattern 1: (test)
349
+ // -> (or test ret)
350
+ ret = [Sym("or"), test, ret].to_list();
351
+ }
352
+ else if (clause.cdr.cdr === nil){
353
+ // pattern 2: (test expr)
354
+ // -> (if test expr ret)
355
+ ret = [Sym("if"), test, clause.cdr.car, ret].to_list();
356
+ }
357
+ else if(clause.cdr.car === Sym("=>")){
358
+ // pattern 3: (test => expr)
359
+ // -> (let ((#<gensym1> test))
360
+ // (if test (expr #<gensym1>) ret))
361
+ var test = clause.car, expr = clause.cdr.cdr.car;
362
+ var tmp_sym = BiwaScheme.gensym();
363
+
364
+ ret = List(Sym("let"),
365
+ List( List(tmp_sym, test) ),
366
+ List(Sym("if"), test, List(expr, tmp_sym), ret));
367
+ }
368
+ else{
369
+ // pattern 4: (test expr ...)
370
+ // -> (if test (begin expr ...) ret)
371
+ ret = [Sym("if"), test,
372
+ new Pair(Sym("begin"), clause.cdr),
373
+ ret].to_list();
374
+ }
375
+ }
376
+ });
377
+ return ret;
378
+ });
379
+
380
+ define_syntax("case", function(x){
381
+ var tmp_sym = BiwaScheme.gensym();
382
+
383
+ if(x.cdr === nil){
384
+ throw new Error("case: at least one clause is required");
385
+ }
386
+ else if(!(x.cdr instanceof Pair)){
387
+ throw new Error("case: proper list is required");
388
+ }
389
+ else{
390
+ // (case key clauses ....)
391
+ // -> (let ((#<gensym1> key))
392
+ var key = x.cdr.car;
393
+ var clauses = x.cdr.cdr;
394
+
395
+ var ret = undefined;
396
+ clauses.to_array().reverse().each(function(clause){
397
+ if(clause.car === Sym("else")){
398
+ // pattern 0: (else expr ...)
399
+ // -> (begin expr ...)
400
+ if(ret === undefined){
401
+ ret = new Pair(Sym("begin"), clause.cdr);
402
+ }
403
+ else{
404
+ throw new Error("case: 'else' clause followed by more clauses: " +
405
+ to_write_ss(clauses));
406
+ }
407
+ }
408
+ else{
409
+ // pattern 1: ((datum ...) expr ...)
410
+ // -> (if (or (eqv? key (quote d1)) ...) (begin expr ...) ret)
411
+ ret = [
412
+ Sym("if"),
413
+ new Pair(Sym("or"), clause.car.to_array().map(function(d){
414
+ return [Sym("eqv?"),
415
+ tmp_sym,
416
+ [Sym("quote"), d].to_list() ].to_list();
417
+ }).to_list()),
418
+ new Pair(Sym("begin"), clause.cdr),
419
+ ret
420
+ ].to_list();
421
+ }
422
+ });
423
+ return new Pair(Sym("let1"),
424
+ new Pair(tmp_sym,
425
+ new Pair(key,
426
+ new Pair(ret, nil))));
427
+ }
428
+ });
429
+
430
+ define_syntax("and", function(x){
431
+ // (and a b c) => (if a (if b c #f) #f)
432
+ //todo: check improper list
433
+ if(x.cdr == nil) return true;
434
+
435
+ var objs = x.cdr.to_array();
436
+ var i = objs.length-1;
437
+ var t = objs[i];
438
+ for(i=i-1; i>=0; i--)
439
+ t = [Sym("if"), objs[i], t, false].to_list();
440
+
441
+ return t;
442
+ })
443
+
444
+ define_syntax("or", function(x){
445
+ // (or a b c) => (if a a (if b b (if c c #f)))
446
+ //todo: check improper list
447
+
448
+ var objs = x.cdr.to_array()
449
+ var f = false;
450
+ for(var i=objs.length-1; i>=0; i--)
451
+ f = [Sym("if"), objs[i], objs[i], f].to_list();
452
+
453
+ return f;
454
+ })
455
+
456
+ // 11.4.6 Binding constructs
457
+ define_syntax("let", function(x){
458
+ //(let ((a 1) (b 2)) (print a) (+ a b))
459
+ //=> ((lambda (a b) (print a) (+ a b)) 1 2)
460
+ var name = null;
461
+ if (x.cdr.car instanceof Symbol) {
462
+ name = x.cdr.car;
463
+ x = x.cdr;
464
+ }
465
+ var binds = x.cdr.car, body = x.cdr.cdr;
466
+
467
+ if(!(binds instanceof Pair))
468
+ throw new Error("let: need a pair for bindings: got "+to_write(binds));
469
+
470
+ var vars = nil, vals = nil;
471
+ for(var p=binds; p instanceof Pair && p!=nil; p=p.cdr){
472
+ vars = new Pair(p.car.car, vars);
473
+ vals = new Pair(p.car.cdr.car, vals);
474
+ }
475
+
476
+ var lambda = null;
477
+ if (name) {
478
+ // (let loop ((a 1) (b 2)) body ..)
479
+ //=> (letrec ((loop (lambda (a b) body ..))) (loop 1 2))
480
+ vars = vars.to_array().reverse().to_list();
481
+ vals = vals.to_array().reverse().to_list();
482
+
483
+ var body_lambda = new Pair(Sym("lambda"), new Pair(vars, body));
484
+ var init_call = new Pair(name, vals);
485
+
486
+ lambda = [Sym("letrec"),
487
+ new Pair([name, body_lambda].to_list(), nil),
488
+ init_call
489
+ ].to_list();
490
+ }
491
+ else {
492
+ lambda = new Pair(new Pair(Sym("lambda"),
493
+ new Pair(vars, body)),
494
+ vals);
495
+ }
496
+ return lambda;
497
+ })
498
+
499
+ define_syntax("let*", function(x){
500
+ //(let* ((a 1) (b a)) (print a) (+ a b))
501
+ //-> (let ((a 1))
502
+ // (let ((b a)) (print a) (+ a b)))
503
+ var binds = x.cdr.car, body = x.cdr.cdr;
504
+
505
+ if(!(binds instanceof Pair))
506
+ throw new Error("let*: need a pair for bindings: got "+to_write(binds));
507
+
508
+ var ret = null;
509
+ binds.to_array().reverse().each(function(bind){
510
+ ret = new Pair(Sym("let"),
511
+ new Pair(new Pair(bind, nil),
512
+ ret == null ? body : new Pair(ret, nil)));
513
+ })
514
+ return ret;
515
+ })
516
+
517
+ var expand_letrec_star = function(x){
518
+ var binds = x.cdr.car, body = x.cdr.cdr;
519
+
520
+ if(!(binds instanceof Pair))
521
+ throw new Error("letrec*: need a pair for bindings: got "+to_write(binds));
522
+
523
+ var ret = body;
524
+ binds.to_array().reverse().each(function(bind){
525
+ ret = new Pair(new Pair(Sym("set!"), bind),
526
+ ret);
527
+ })
528
+ var letbody = nil;
529
+ binds.to_array().reverse().each(function(bind){
530
+ letbody = new Pair(new Pair(bind.car,
531
+ new Pair(BiwaScheme.undef, nil)),
532
+ letbody);
533
+ })
534
+ return new Pair(Sym("let"),
535
+ new Pair(letbody,
536
+ ret));
537
+ }
538
+ define_syntax("letrec", expand_letrec_star);
539
+ define_syntax("letrec*", expand_letrec_star);
540
+ //let-values
541
+ //let*-values
542
+ // 11.4.7 Sequencing
543
+ //(begin)
544
+
545
+ //
546
+ // 11.5 Equivalence predicates
547
+ //
548
+ define_libfunc("eqv?", 2, 2, function(ar){
549
+ return ar[0] == ar[1] && (typeof(ar[0]) == typeof(ar[1]));
550
+ })
551
+ define_libfunc("eq?", 2, 2, function(ar){
552
+ return ar[0] === ar[1];
553
+ })
554
+ define_libfunc("equal?", 2, 2, function(ar){
555
+ //TODO: must terminate for cyclic objects
556
+ return to_write(ar[0]) == to_write(ar[1]);
557
+ })
558
+
559
+ //
560
+ // 11.6 Procedure predicate
561
+ //
562
+ //"procedure?", 1, 1
563
+ define_libfunc("procedure?", 1, 1, function(ar){
564
+ return ((ar[0] instanceof Array) && (ar[0].closure_p === true)
565
+ || (typeof ar[0] == "function"));
566
+ })
567
+
568
+ //
569
+ // 11.7 Arithmetic
570
+ //
571
+
572
+ // 11.7.1 Propagation of exactness and inexactness
573
+ // 11.7.2 Representability of infinities and NaNs
574
+ // 11.7.3 Semantics of common operations
575
+ // 11.7.3.1 Integer division
576
+ // 11.7.3.2 Transcendental functions
577
+ //(no functions are introduced by above sections)
578
+
579
+ //
580
+ // 11.7.4 Numerical operations
581
+ //
582
+
583
+ // 11.7.4.1 Numerical type predicates
584
+ define_libfunc("number?", 1, 1, function(ar){
585
+ return (typeof(ar[0]) == 'number') ||
586
+ (ar[0] instanceof Complex) ||
587
+ (ar[0] instanceof Rational);
588
+ });
589
+ define_libfunc("complex?", 1, 1, function(ar){
590
+ return (ar[0] instanceof Complex);
591
+ });
592
+ define_libfunc("real?", 1, 1, function(ar){
593
+ return (typeof(ar[0]) == 'number');
594
+ });
595
+ define_libfunc("rational?", 1, 1, function(ar){
596
+ return (ar[0] instanceof Rational);
597
+ });
598
+ define_libfunc("integer?", 1, 1, function(ar){
599
+ return typeof(ar[0]) == 'number' &&
600
+ ar[0] == Math.round(ar[0]) &&
601
+ ar[0] != Infinity &&
602
+ ar[0] != -Infinity;
603
+ });
604
+
605
+ //(real-valued? obj) procedure
606
+ //(rational-valued? obj) procedure
607
+ //(integer-valued? obj) procedure
608
+ //
609
+ //(exact? z) procedure
610
+ //(inexact? z) procedure
611
+
612
+ // 11.7.4.2 Generic conversions
613
+ //
614
+ //(inexact z) procedure
615
+ //(exact z) procedure
616
+ //
617
+ // 11.7.4.3 Arithmetic operations
618
+
619
+ //inf & nan: ok (for this section)
620
+ define_libfunc("=", 2, null, function(ar){
621
+ var v = ar[0];
622
+ assert_number(ar[0]);
623
+ for(var i=1; i<ar.length; i++){
624
+ assert_number(ar[i]);
625
+ if(ar[i] != v) return false;
626
+ }
627
+ return true;
628
+ });
629
+ define_libfunc("<", 2, null, function(ar){
630
+ assert_number(ar[0]);
631
+ for(var i=1; i<ar.length; i++){
632
+ assert_number(ar[i]);
633
+ if(!(ar[i-1] < ar[i])) return false;
634
+ }
635
+ return true;
636
+ });
637
+ define_libfunc(">", 2, null, function(ar){
638
+ assert_number(ar[0]);
639
+ for(var i=1; i<ar.length; i++){
640
+ assert_number(ar[i]);
641
+ if(!(ar[i-1] > ar[i])) return false;
642
+ }
643
+ return true;
644
+ });
645
+ define_libfunc("<=", 2, null, function(ar){
646
+ assert_number(ar[0]);
647
+ for(var i=1; i<ar.length; i++){
648
+ assert_number(ar[i]);
649
+ if(!(ar[i-1] <= ar[i])) return false;
650
+ }
651
+ return true;
652
+ });
653
+ define_libfunc(">=", 2, null, function(ar){
654
+ assert_number(ar[0]);
655
+ for(var i=1; i<ar.length; i++){
656
+ assert_number(ar[i]);
657
+ if(!(ar[i-1] >= ar[i])) return false;
658
+ }
659
+ return true;
660
+ });
661
+
662
+ define_libfunc("zero?", 1, 1, function(ar){
663
+ assert_number(ar[0]);
664
+ return ar[0] === 0;
665
+ });
666
+ define_libfunc("positive?", 1, 1, function(ar){
667
+ assert_number(ar[0]);
668
+ return (ar[0] > 0);
669
+ });
670
+ define_libfunc("negative?", 1, 1, function(ar){
671
+ assert_number(ar[0]);
672
+ return (ar[0] < 0);
673
+ });
674
+ define_libfunc("odd?", 1, 1, function(ar){
675
+ assert_number(ar[0]);
676
+ return (ar[0] % 2 == 1) || (ar[0] % 2 == -1);
677
+ })
678
+ define_libfunc("even?", 1, 1, function(ar){
679
+ assert_number(ar[0]);
680
+ return ar[0] % 2 == 0;
681
+ })
682
+ define_libfunc("finite?", 1, 1, function(ar){
683
+ assert_number(ar[0]);
684
+ return (ar[0] != Infinity) && (ar[0] != -Infinity) && !isNaN(ar[0]);
685
+ })
686
+ define_libfunc("infinite?", 1, 1, function(ar){
687
+ assert_number(ar[0]);
688
+ return (ar[0] == Infinity) || (ar[0] == -Infinity);
689
+ })
690
+ define_libfunc("nan?", 1, 1, function(ar){
691
+ assert_number(ar[0]);
692
+ return isNaN(ar[0]);
693
+ })
694
+ define_libfunc("max", 2, null, function(ar){
695
+ for(var i=0; i<ar.length; i++)
696
+ assert_number(ar[i]);
697
+
698
+ return Math.max.apply(null, ar)
699
+ });
700
+ define_libfunc("min", 2, null, function(ar){
701
+ for(var i=0; i<ar.length; i++)
702
+ assert_number(ar[i]);
703
+
704
+ return Math.min.apply(null, ar);
705
+ });
706
+
707
+ define_libfunc("+", 0,null, function(ar){
708
+ var n = 0;
709
+ for(var i=0; i<ar.length; i++){
710
+ assert_number(ar[i]);
711
+ n+=ar[i];
712
+ }
713
+ return n;
714
+ });
715
+ define_libfunc("*", 0,null, function(ar){
716
+ var n = 1;
717
+ for(var i=0; i<ar.length; i++){
718
+ assert_number(ar[i]);
719
+ n*=ar[i];
720
+ }
721
+ return n;
722
+ });
723
+ define_libfunc("-", 1,null, function(ar){
724
+ var len = ar.length;
725
+ assert_number(ar[0]);
726
+
727
+ if(len == 1)
728
+ return -ar[0];
729
+ else{
730
+ var n = ar[0];
731
+ for(var i=1; i<len; i++){
732
+ assert_number(ar[i]);
733
+ n-=ar[i];
734
+ }
735
+ return n;
736
+ }
737
+ });
738
+ //for r6rs specification, (/ 0 0) or (/ 3 0) raises '&assertion exception'
739
+ define_libfunc("/", 1,null, function(ar){
740
+ var len = ar.length;
741
+ assert_number(ar[0]);
742
+
743
+ if(len == 1)
744
+ return 1/ar[0];
745
+ else{
746
+ var n = ar[0];
747
+ for(var i=1; i<len; i++){
748
+ assert_number(ar[i]);
749
+ n/=ar[i];
750
+ }
751
+ return n;
752
+ }
753
+ });
754
+
755
+ define_libfunc("abs", 1, 1, function(ar){
756
+ assert_number(ar[0]);
757
+ return Math.abs(ar[0]);
758
+ });
759
+
760
+ var div = function(n, m){
761
+ return Math.floor(n / m);
762
+ }
763
+ var mod = function(n, m){
764
+ return n - Math.floor(n / m) * m;
765
+ }
766
+ var div0 = function(n, m){
767
+ return (n > 0) ? Math.floor(n / m) : Math.ceil(n / m);
768
+ }
769
+ var mod0 = function(n, m){
770
+ return (n > 0) ? n - Math.floor(n / m) * m
771
+ : n - Math.ceil(n / m) * m;
772
+ }
773
+ define_libfunc("div0-and-mod0", 2, 2, function(ar){
774
+ assert_number(ar[0]);
775
+ assert_number(ar[1]);
776
+ return new Values([div(ar[0], ar[1]), mod(ar[0], ar[1])]);
777
+ })
778
+ define_libfunc("div", 2, 2, function(ar){
779
+ assert_number(ar[0]);
780
+ assert_number(ar[1]);
781
+ return div(ar[0], ar[1]);
782
+ })
783
+ define_libfunc("mod", 2, 2, function(ar){
784
+ assert_number(ar[0]);
785
+ assert_number(ar[1]);
786
+ return mod(ar[0], ar[1]);
787
+ })
788
+ define_libfunc("div0-and-mod0", 2, 2, function(ar){
789
+ assert_number(ar[0]);
790
+ assert_number(ar[1]);
791
+ return new Values([div0(ar[0], ar[1]), mod0(ar[0], ar[1])]);
792
+ })
793
+ define_libfunc("div0", 2, 2, function(ar){
794
+ assert_number(ar[0]);
795
+ assert_number(ar[1]);
796
+ return div0(ar[0], ar[1]);
797
+ })
798
+ define_libfunc("mod0", 2, 2, function(ar){
799
+ assert_number(ar[0]);
800
+ assert_number(ar[1]);
801
+ return mod0(ar[0], ar[1]);
802
+ })
803
+
804
+ //(gcd n1 ...) procedure
805
+ //(lcm n1 ...) procedure
806
+
807
+ define_libfunc("numerator", 1, 1, function(ar){
808
+ assert_number(ar[0]);
809
+ if(ar[0] instanceof Rational)
810
+ return ar[0].numerator;
811
+ else
812
+ throw new Bug("todo");
813
+ })
814
+ define_libfunc("denominator", 1, 1, function(ar){
815
+ assert_number(ar[0]);
816
+ if(ar[0] instanceof Rational)
817
+ return ar[0].denominator;
818
+ else
819
+ throw new Bug("todo");
820
+ })
821
+ define_libfunc("floor", 1, 1, function(ar){
822
+ assert_number(ar[0]);
823
+ return Math.floor(ar[0]);
824
+ })
825
+ define_libfunc("ceiling", 1, 1, function(ar){
826
+ assert_number(ar[0]);
827
+ return Math.ceil(ar[0]);
828
+ })
829
+ define_libfunc("truncate", 1, 1, function(ar){
830
+ assert_number(ar[0]);
831
+ return (ar[0] < 0) ? Math.ceil(ar[0]) : Math.floor(ar[0]);
832
+ })
833
+ define_libfunc("round", 1, 1, function(ar){
834
+ assert_number(ar[0]);
835
+ return Math.round(ar[0]);
836
+ })
837
+
838
+ //(rationalize x1 x2) procedure
839
+
840
+ define_libfunc("exp", 1, 1, function(ar){
841
+ assert_number(ar[0]);
842
+ return Math.exp(ar[0]);
843
+ })
844
+ define_libfunc("log", 1, 2, function(ar){
845
+ var num = ar[0], base = ar[1];
846
+ assert_number(num);
847
+
848
+ if(base){ // log b num == log e num / log e b
849
+ assert_number(base);
850
+ return Math.log(num) / Math.log(b)
851
+ }
852
+ else
853
+ return Math.log(num);
854
+ })
855
+ define_libfunc("sin", 1, 1, function(ar){
856
+ assert_number(ar[0]);
857
+ return Math.sin(ar[0]);
858
+ })
859
+ define_libfunc("cos", 1, 1, function(ar){
860
+ assert_number(ar[0]);
861
+ return Math.cos(ar[0]);
862
+ })
863
+ define_libfunc("tan", 1, 1, function(ar){
864
+ assert_number(ar[0]);
865
+ return Math.tan(ar[0]);
866
+ })
867
+ define_libfunc("asin", 1, 1, function(ar){
868
+ assert_number(ar[0]);
869
+ return Math.asin(ar[0]);
870
+ })
871
+ define_libfunc("acos", 1, 1, function(ar){
872
+ assert_number(ar[0]);
873
+ return Math.asos(ar[0]);
874
+ })
875
+ define_libfunc("atan", 1, 2, function(ar){
876
+ assert_number(ar[0]);
877
+ if(ar[1]){
878
+ assert_number(ar[1]);
879
+ return Math.atan2(ar[0], ar[1]);
880
+ }
881
+ else
882
+ return Math.atan(ar[0]);
883
+ })
884
+ define_libfunc("sqrt", 1, 1, function(ar){
885
+ assert_number(ar[0]);
886
+ return Math.sqrt(ar[0]);
887
+ })
888
+ define_libfunc("exact-integer-sqrt", 1, 1, function(ar){
889
+ assert_number(ar[0]);
890
+ var sqrt_f = Math.sqrt(ar[0]);
891
+ var sqrt_i = sqrt_f - (sqrt_f % 1);
892
+ var rest = ar[0] - sqrt_i * sqrt_i;
893
+
894
+ return new Values([sqrt_i, rest]);
895
+ })
896
+ define_libfunc("expt", 2, 2, function(ar){
897
+ assert_number(ar[0]);
898
+ assert_number(ar[1]);
899
+ return Math.pow(ar[0], ar[1]);
900
+ })
901
+ define_libfunc("make-rectangular", 2, 2, function(ar){
902
+ assert_number(ar[0]);
903
+ assert_number(ar[1]);
904
+ return new Complex(ar[0], ar[1]);
905
+ })
906
+ define_libfunc("make-polar", 2, 2, function(ar){
907
+ assert_number(ar[0]);
908
+ assert_number(ar[1]);
909
+ return Complex.from_polar(ar[0], ar[1]);
910
+ })
911
+ define_libfunc("real-part", 1, 1, function(ar){
912
+ assert_number(ar[0]);
913
+ return Complex.assure(ar[0]).real;
914
+ })
915
+ define_libfunc("imag-part", 1, 1, function(ar){
916
+ assert_number(ar[0]);
917
+ return Complex.assure(ar[0]).imag;
918
+ })
919
+ define_libfunc("magnitude", 1, 1, function(ar){
920
+ assert_number(ar[0]);
921
+ return Complex.assure(ar[0]).magnitude();
922
+ })
923
+ define_libfunc("angle", 1, 1, function(ar){
924
+ assert_number(ar[0]);
925
+ return Complex.assure(ar[0]).angle();
926
+ })
927
+
928
+ //
929
+ // 11.7.4.4 Numerical Input and Output
930
+ //
931
+ define_libfunc("number->string", 1, 3, function(ar){
932
+ var z = ar[0], radix = ar[1], precision = ar[2];
933
+ if(precision)
934
+ throw new Bug("number->string: presition is not yet implemented");
935
+
936
+ radix = radix || 10; //TODO: check radix is 2, 8, 10, or 16.
937
+ return z.toString(radix);
938
+ })
939
+ define_libfunc("string->number", 1, 3, function(ar){
940
+ var s = ar[0], radix = ar[1] || 10;
941
+ switch(s){
942
+ case "+inf.0": return Infinity;
943
+ case "-inf.0": return -Infinity;
944
+ case "+nan.0": return NaN;
945
+ default: return parseInt(s, radix);
946
+ }
947
+ })
948
+
949
+ //
950
+ // 11.8 Booleans
951
+ //
952
+
953
+ define_libfunc("not", 1, 1, function(ar){
954
+ return (ar[0] === false) ? true : false;
955
+ });
956
+ define_libfunc("boolean?", 1, 1, function(ar){
957
+ return (ar[0] === false || ar[0] === true) ? true : false;
958
+ });
959
+ define_libfunc("boolean=?", 2, null, function(ar){
960
+ var len = ar.length;
961
+ for(var i=1; i<len; i++){
962
+ if(ar[i] != ar[0]) return false;
963
+ }
964
+ return true;
965
+ });
966
+
967
+ // 11.9 Pairs and lists
968
+
969
+ define_libfunc("pair?", 1, 1, function(ar){
970
+ return (ar[0] instanceof Pair && ar[0] != nil) ? true : false;
971
+ });
972
+ define_libfunc("cons", 2, 2, function(ar){
973
+ return new Pair(ar[0], ar[1]);
974
+ });
975
+ define_libfunc("car", 1, 1, function(ar){
976
+ //should raise &assertion for '()...
977
+ if(!ar[0] instanceof Pair) throw new Error("cannot take car of " + ar[0]);
978
+ return ar[0].car;
979
+ });
980
+ define_libfunc("cdr", 1, 1, function(ar){
981
+ //should raise &assertion for '()...
982
+ if(!ar[0] instanceof Pair) throw new Error("cannot take cdr of " + ar[0]);
983
+ return ar[0].cdr;
984
+ });
985
+ define_libfunc("set-car!", 2, 2, function(ar){
986
+ if(!ar[0] instanceof Pair) throw new Error("cannot take set-car! of " + ar[0]);
987
+ ar[0].car = ar[1];
988
+ return BiwaScheme.undef;
989
+ });
990
+ define_libfunc("set-cdr!", 2, 2, function(ar){
991
+ if(!ar[0] instanceof Pair) throw new Error("cannot take set-cdr! of " + ar[0]);
992
+ ar[0].cdr = ar[1];
993
+ return BiwaScheme.undef;
994
+ });
995
+
996
+ define_libfunc("caar", 1, 1, function(ar){ return ar[0].car.car; });
997
+ define_libfunc("cadr", 1, 1, function(ar){ return ar[0].cdr.car; });
998
+ define_libfunc("cdar", 1, 1, function(ar){ return ar[0].car.cdr; });
999
+ define_libfunc("cddr", 1, 1, function(ar){ return ar[0].cdr.cdr; });
1000
+ define_libfunc("caaar", 1, 1, function(ar){ return ar[0].car.car.car; });
1001
+ define_libfunc("caadr", 1, 1, function(ar){ return ar[0].cdr.car.car; });
1002
+ define_libfunc("cadar", 1, 1, function(ar){ return ar[0].car.cdr.car; });
1003
+ define_libfunc("caddr", 1, 1, function(ar){ return ar[0].cdr.cdr.car; });
1004
+ define_libfunc("cdaar", 1, 1, function(ar){ return ar[0].car.car.cdr; });
1005
+ define_libfunc("cdadr", 1, 1, function(ar){ return ar[0].cdr.car.cdr; });
1006
+ define_libfunc("cddar", 1, 1, function(ar){ return ar[0].car.cdr.cdr; });
1007
+ define_libfunc("cdddr", 1, 1, function(ar){ return ar[0].cdr.cdr.cdr; });
1008
+ define_libfunc("caaaar", 1, 1, function(ar){ return ar[0].car.car.car.car; });
1009
+ define_libfunc("caaadr", 1, 1, function(ar){ return ar[0].cdr.car.car.car; });
1010
+ define_libfunc("caadar", 1, 1, function(ar){ return ar[0].car.cdr.car.car; });
1011
+ define_libfunc("caaddr", 1, 1, function(ar){ return ar[0].cdr.cdr.car.car; });
1012
+ define_libfunc("cadaar", 1, 1, function(ar){ return ar[0].car.car.cdr.car; });
1013
+ define_libfunc("cadadr", 1, 1, function(ar){ return ar[0].cdr.car.cdr.car; });
1014
+ define_libfunc("caddar", 1, 1, function(ar){ return ar[0].car.cdr.cdr.car; });
1015
+ define_libfunc("cadddr", 1, 1, function(ar){ return ar[0].cdr.cdr.cdr.car; });
1016
+ define_libfunc("cdaaar", 1, 1, function(ar){ return ar[0].car.car.car.cdr; });
1017
+ define_libfunc("cdaadr", 1, 1, function(ar){ return ar[0].cdr.car.car.cdr; });
1018
+ define_libfunc("cdadar", 1, 1, function(ar){ return ar[0].car.cdr.car.cdr; });
1019
+ define_libfunc("cdaddr", 1, 1, function(ar){ return ar[0].cdr.cdr.car.cdr; });
1020
+ define_libfunc("cddaar", 1, 1, function(ar){ return ar[0].car.car.cdr.cdr; });
1021
+ define_libfunc("cddadr", 1, 1, function(ar){ return ar[0].cdr.car.cdr.cdr; });
1022
+ define_libfunc("cdddar", 1, 1, function(ar){ return ar[0].car.cdr.cdr.cdr; });
1023
+ define_libfunc("cddddr", 1, 1, function(ar){ return ar[0].cdr.cdr.cdr.cdr; });
1024
+
1025
+ define_libfunc("null?", 1, 1, function(ar){
1026
+ return (ar[0] === nil);
1027
+ });
1028
+ define_libfunc("list?", 1, 1, function(ar){
1029
+ var contents = [];
1030
+ for(var o=ar[0]; o != nil; o=o.cdr){
1031
+ if(!(o instanceof Pair)) return false;
1032
+ if(contents.find(function(item){ return item === o.car}))
1033
+ return false; //cyclic
1034
+ contents.push(o.car);
1035
+ }
1036
+ return true;
1037
+ });
1038
+ define_libfunc("list", 0, null, function(ar){
1039
+ var l = nil;
1040
+ for(var i=ar.length-1; i>=0; i--)
1041
+ l = new Pair(ar[i], l);
1042
+ return l;
1043
+ });
1044
+ define_libfunc("length", 1, 1, function(ar){
1045
+ assert_pair(ar[0]);
1046
+
1047
+ var n = 0;
1048
+ for(var o=ar[0]; o!=nil; o=o.cdr)
1049
+ n++;
1050
+ return n;
1051
+ });
1052
+ define_libfunc("append", 2, null, function(ar){
1053
+ var k = ar.length
1054
+ var ret = ar[--k];
1055
+ while(k--){
1056
+ ar[k].to_array().reverse().each(function(item){
1057
+ ret = new Pair(item, ret);
1058
+ });
1059
+ }
1060
+ return ret;
1061
+ });
1062
+ define_libfunc("reverse", 1, 1, function(ar){
1063
+ if(!ar[0] instanceof Pair) throw new Error("reverse needs pair but got " + ar[0]);
1064
+
1065
+ var l = nil;
1066
+ for(var o=ar[0]; o!=nil; o=o.cdr)
1067
+ l = new Pair(o.car, l);
1068
+ return l;
1069
+ });
1070
+ define_libfunc("list-tail", 2, 2, function(ar){
1071
+ if(!ar[0] instanceof Pair) throw new Error("list-tail needs pair but got " + ar[0]);
1072
+
1073
+ var o = ar[0];
1074
+ for(var i=0; i<ar[1]; i++){
1075
+ if(!o instanceof Pair) throw new Error("list-tail: the list is shorter than " + ar[1]);
1076
+ o = o.cdr;
1077
+ }
1078
+ return o;
1079
+ });
1080
+ define_libfunc("list-ref", 2, 2, function(ar){
1081
+ if(!ar[0] instanceof Pair) throw new Error("list-ref needs pair but got " + ar[0]);
1082
+
1083
+ var o = ar[0];
1084
+ for(var i=0; i<ar[1]; i++){
1085
+ if(!o instanceof Pair) throw new Error("list-ref: the list is shorter than " + ar[1]);
1086
+ o = o.cdr;
1087
+ }
1088
+ return o.car;
1089
+ });
1090
+ define_libfunc("map", 2, null, function(ar){
1091
+ var proc = ar.shift(), lists = ar;
1092
+ lists.each(function(ls){ assert_pair(ls) });
1093
+
1094
+ var a = [];
1095
+ return Call.multi_foreach(lists, {
1096
+ // Called for each element
1097
+ // input: the element (or the elements, if more than one list is given)
1098
+ // output: a Call request of proc and args
1099
+ call: function(xs){
1100
+ return new Call(proc, xs.map(function(x){ return x.car }));
1101
+ },
1102
+
1103
+ // Called when each Call request is finished
1104
+ // input: the result of Call request,
1105
+ // the element(s) of the Call request (which is not used here)
1106
+ // output: `undefined' to continue,
1107
+ // some value to terminate (the value will be the result)
1108
+ result: function(res){ a.push(res); },
1109
+
1110
+ // Called when reached to the end of the list(s)
1111
+ // input: none
1112
+ // output: the resultant value
1113
+ finish: function(){ return a.to_list(); }
1114
+ })
1115
+ })
1116
+ define_libfunc("for-each", 2, null, function(ar){
1117
+ var proc = ar.shift(), lists = ar;
1118
+ lists.each(function(ls){ assert_pair(ls) });
1119
+
1120
+ return Call.multi_foreach(lists, {
1121
+ call: function(xs){
1122
+ return new Call(proc, xs.map(function(x){ return x.car }));
1123
+ },
1124
+ finish: function(){ return BiwaScheme.undef; }
1125
+ })
1126
+ })
1127
+
1128
+ // 11.10 Symbols
1129
+
1130
+ define_libfunc("symbol?", 1, 1, function(ar){
1131
+ return (ar[0] instanceof Symbol) ? true : false;
1132
+ });
1133
+ define_libfunc("symbol->string", 1, 1, function(ar){
1134
+ assert_symbol(ar[0]);
1135
+ return ar[0].name;
1136
+ });
1137
+ define_libfunc("symbol=?", 2, null, function(ar){
1138
+ assert_symbol(ar[0]);
1139
+ for(var i=1; i<ar.length; i++){
1140
+ assert_symbol(ar[i]);
1141
+ if(ar[i] != ar[0]) return false;
1142
+ }
1143
+ return true;
1144
+ });
1145
+ define_libfunc("string->symbol", 1, 1, function(ar){
1146
+ assert_string(ar[0]);
1147
+ return Sym(ar[0]);
1148
+ });
1149
+
1150
+ //
1151
+ // 11.11 Characters
1152
+ //
1153
+ define_libfunc('char?', 1, 1, function(ar){
1154
+ return (ar[0] instanceof Char);
1155
+ });
1156
+ define_libfunc('char->integer', 1, 1, function(ar){
1157
+ assert_char(ar[0]);
1158
+ return ar[0].value.charCodeAt(0);
1159
+ })
1160
+ define_libfunc('integer->char', 1, 1, function(ar){
1161
+ assert_integer(ar[0]);
1162
+ return Char.get(String.fromCharCode(ar[0]));
1163
+ })
1164
+
1165
+ var make_char_compare_func = function(test){
1166
+ return function(ar){
1167
+ assert_char(ar[0]);
1168
+ for(var i=1; i<ar.length; i++){
1169
+ assert_char(ar[i]);
1170
+ if(!test(ar[i-1].value, ar[i].value))
1171
+ return false;
1172
+ }
1173
+ return true;
1174
+ }
1175
+ }
1176
+ define_libfunc('char=?', 2, null,
1177
+ make_char_compare_func(function(a, b){ return a == b }))
1178
+ define_libfunc('char<?', 2, null,
1179
+ make_char_compare_func(function(a, b){ return a < b }))
1180
+ define_libfunc('char>?', 2, null,
1181
+ make_char_compare_func(function(a, b){ return a > b }))
1182
+ define_libfunc('char<=?', 2, null,
1183
+ make_char_compare_func(function(a, b){ return a <= b }))
1184
+ define_libfunc('char>=?', 2, null,
1185
+ make_char_compare_func(function(a, b){ return a >= b }))
1186
+
1187
+ //
1188
+ // 11.12 Strings
1189
+ //
1190
+ define_libfunc("string?", 1, 1, function(ar){
1191
+ return (typeof(ar[0]) == "string");
1192
+ })
1193
+ define_libfunc("make-string", 1, 2, function(ar){
1194
+ assert_integer(ar[0]);
1195
+ var c = " ";
1196
+ if(ar[1]){
1197
+ assert_char(ar[1]);
1198
+ c = ar[1].value;
1199
+ }
1200
+ return c.times(ar[0]);
1201
+ })
1202
+ define_libfunc("string", 1, null, function(ar){
1203
+ for(var i=0; i<ar.length; i++)
1204
+ assert_char(ar[i]);
1205
+ return ar.map(function(c){ return c.value }).join("");
1206
+ })
1207
+ define_libfunc("string-length", 1, 1, function(ar){
1208
+ assert_string(ar[0]);
1209
+ return ar[0].length;
1210
+ })
1211
+ define_libfunc("string-ref", 2, 2, function(ar){
1212
+ assert_string(ar[0]);
1213
+ assert_between(ar[1], 0, ar[0].length-1);
1214
+ return Char.get(ar[0].charAt([ar[1]]));
1215
+ })
1216
+ define_libfunc("string=?", 2, null, function(ar){
1217
+ assert_string(ar[0]);
1218
+ for(var i=1; i<ar.length; i++){
1219
+ assert_string(ar[i]);
1220
+ if(ar[0] != ar[i]) return false;
1221
+ }
1222
+ return true;
1223
+ })
1224
+ define_libfunc("string<?", 2, null, function(ar){
1225
+ assert_string(ar[0]);
1226
+ for(var i=1; i<ar.length; i++){
1227
+ assert_string(ar[i]);
1228
+ if(!(ar[i-1] < ar[i])) return false;
1229
+ }
1230
+ return true;
1231
+ })
1232
+ define_libfunc("string>?", 2, null, function(ar){
1233
+ assert_string(ar[0]);
1234
+ for(var i=1; i<ar.length; i++){
1235
+ assert_string(ar[i]);
1236
+ if(!(ar[i-1] > ar[i])) return false;
1237
+ }
1238
+ return true;
1239
+ })
1240
+ define_libfunc("string<=?", 2, null, function(ar){
1241
+ assert_string(ar[0]);
1242
+ for(var i=1; i<ar.length; i++){
1243
+ assert_string(ar[i]);
1244
+ if(!(ar[i-1] <= ar[i])) return false;
1245
+ }
1246
+ return true;
1247
+ })
1248
+ define_libfunc("string>=?", 2, null, function(ar){
1249
+ assert_string(ar[0]);
1250
+ for(var i=1; i<ar.length; i++){
1251
+ assert_string(ar[i]);
1252
+ if(!(ar[i-1] >= ar[i])) return false;
1253
+ }
1254
+ return true;
1255
+ })
1256
+
1257
+ define_libfunc("substring", 3, 3, function(ar){
1258
+ assert_string(ar[0]);
1259
+ assert_integer(ar[1]);
1260
+ assert_integer(ar[2]);
1261
+
1262
+ if(ar[1] < 0) throw new Error("substring: start too small: "+ar[1]);
1263
+ if(ar[2] < 0) throw new Error("substring: end too small: "+ar[2]);
1264
+ if(ar[0].length+1 <= ar[1]) throw new Error("substring: start too big: "+ar[1]);
1265
+ if(ar[0].length+1 <= ar[2]) throw new Error("substring: end too big: "+ar[2]);
1266
+ if(!(ar[1] <= ar[2])) throw new Error("substring: not start <= end: "+ar[1]+", "+ar[2]);
1267
+
1268
+ return ar[0].substring(ar[1], ar[2]);
1269
+ })
1270
+
1271
+ define_libfunc("string-append", 0, null, function(ar){
1272
+ for(var i=0; i<ar.length; i++)
1273
+ assert_string(ar[i]);
1274
+
1275
+ return ar.join("");
1276
+ })
1277
+ define_libfunc("string->list", 1, 1, function(ar){
1278
+ assert_string(ar[0]);
1279
+ var chars = [];
1280
+ ar[0].scan(/./, function(s){ chars.push(Char.get(s[0])) });
1281
+ return chars.to_list();
1282
+ })
1283
+ define_libfunc("list->string", 1, 1, function(ar){
1284
+ assert_pair(ar[0]);
1285
+ return ar[0].to_array().map(function(c){ return c.value; }).join("");
1286
+ })
1287
+ define_libfunc("string-for-each", 2, null, function(ar){
1288
+ var proc = ar.shift(), strs = ar;
1289
+ strs.each(function(str){ assert_string(str) });
1290
+
1291
+ return Call.multi_foreach(strs, {
1292
+ call: function(chars){ return new Call(proc, chars); },
1293
+ finish: function(){ return BiwaScheme.undef; }
1294
+ })
1295
+ })
1296
+ define_libfunc("string-copy", 1, 1, function(ar){
1297
+ // note: this is useless, because javascript strings are immutable
1298
+ assert_string(ar[0]);
1299
+ return ar[0];
1300
+ })
1301
+
1302
+
1303
+ //
1304
+ // 11.13 Vectors
1305
+ //
1306
+ define_libfunc("vector?", 1, 1, function(ar){
1307
+ return (ar[0] instanceof Array) && (ar[0].closure_p !== true)
1308
+ })
1309
+ define_libfunc("make-vector", 1, 2, function(ar){
1310
+ assert_integer(ar[0]);
1311
+ var vec = new Array(ar[0]);
1312
+
1313
+ if(ar.length == 2){
1314
+ for(var i=0; i<ar[0]; i++)
1315
+ vec[i] = ar[1];
1316
+ }
1317
+ return vec;
1318
+ })
1319
+ define_libfunc("vector", 1, null, function(ar){
1320
+ return ar;
1321
+ })
1322
+ define_libfunc("vector-length", 1, 1, function(ar){
1323
+ assert_vector(ar[0]);
1324
+ return ar[0].length;
1325
+ })
1326
+ define_libfunc("vector-ref", 2, 2, function(ar){
1327
+ assert_vector(ar[0]);
1328
+ assert_integer(ar[1]);
1329
+
1330
+ return ar[0][ar[1]];
1331
+ })
1332
+ define_libfunc("vector-set!", 3, 3, function(ar){
1333
+ assert_vector(ar[0]);
1334
+ assert_integer(ar[1]);
1335
+
1336
+ ar[0][ar[1]] = ar[2];
1337
+ return BiwaScheme.undef;
1338
+ })
1339
+ define_libfunc("vector->list", 1, 1, function(ar){
1340
+ assert_vector(ar[0]);
1341
+ return ar[0].to_list();
1342
+ })
1343
+ define_libfunc("list->vector", 1, 1, function(ar){
1344
+ assert_pair(ar[0]);
1345
+ return ar[0].to_array();
1346
+ })
1347
+ define_libfunc("vector-fill!", 2, 2, function(ar){
1348
+ assert_vector(ar[0]);
1349
+ var vec = ar[0], obj = ar[1];
1350
+
1351
+ for(var i=0; i<vec.length; i++)
1352
+ vec[i] = obj;
1353
+ return vec;
1354
+ })
1355
+ define_libfunc("vector-map", 2, null, function(ar){
1356
+ var proc = ar.shift(), vecs = ar;
1357
+ vecs.each(function(vec){ assert_vector(vec) });
1358
+
1359
+ var a = [];
1360
+ return Call.multi_foreach(vecs, {
1361
+ call: function(objs){ return new Call(proc, objs); },
1362
+ result: function(res){ a.push(res); },
1363
+ finish: function(){ return a; }
1364
+ })
1365
+ })
1366
+ define_libfunc("vector-for-each", 2, null, function(ar){
1367
+ var proc = ar.shift(), vecs = ar;
1368
+ vecs.each(function(vec){ assert_vector(vec) });
1369
+
1370
+ return Call.multi_foreach(vecs, {
1371
+ call: function(objs){ return new Call(proc, objs); },
1372
+ finish: function(){ return BiwaScheme.undef; }
1373
+ })
1374
+ })
1375
+
1376
+ //
1377
+ // 11.14 Errors and violations
1378
+ //
1379
+ //(error who message irritant1 ...) procedure
1380
+ //(assertion-violation who message irritant1 ...) procedure
1381
+ //(assert <expression>) syntax
1382
+
1383
+ //
1384
+ // 11.15 Control features
1385
+ //
1386
+ define_libfunc("apply", 2, null, function(ar){
1387
+ var proc = ar.shift(), rest_args = ar.pop(), args = ar;
1388
+ args = args.concat(rest_args.to_array());
1389
+
1390
+ return new Call(proc, args);
1391
+ })
1392
+ define_syntax("call-with-current-continuation", function(x){
1393
+ return new Pair(Sym("call/cc"),
1394
+ x.cdr);
1395
+ })
1396
+ define_libfunc("values", 0, null, function(ar){
1397
+ return new Values(ar);
1398
+ })
1399
+ define_libfunc("call-with-values", 2, 2, function(ar){
1400
+ var producer = ar[0], consumer = ar[1];
1401
+ return new Call(producer, [], function(ar){
1402
+ var values = ar[0];
1403
+ if(!(values instanceof Values))
1404
+ throw new Error("values expected, but got "+to_write(values));
1405
+
1406
+ return new Call(consumer, values.content);
1407
+ })
1408
+ })
1409
+
1410
+ //
1411
+ //dynamic-wind
1412
+
1413
+ // 11.16 Iteration
1414
+ //named let
1415
+
1416
+ // 11.17 Quasiquotation
1417
+ //quasiquote
1418
+ var expand_qq = function(f, lv){
1419
+ if(f instanceof Symbol || f === nil){
1420
+ return [Sym("quote"), f].to_list();
1421
+ }
1422
+ else if(f instanceof Pair){
1423
+ var car = f.car;
1424
+ if(car instanceof Pair && car.car === Sym("unquote-splicing")){
1425
+ var lv = lv-1;
1426
+ if(lv == 0)
1427
+ return [ Sym("append"),
1428
+ f.car.cdr.car,
1429
+ expand_qq(f.cdr, lv+1)
1430
+ ].to_list();
1431
+ else
1432
+ return [ Sym("cons"),
1433
+ [Sym("list"), Sym("unquote-splicing"), expand_qq(f.car.cdr.car, lv)].to_list(),
1434
+ expand_qq(f.cdr, lv+1)
1435
+ ].to_list();
1436
+ }
1437
+ else if(car === Sym("unquote")){
1438
+ var lv = lv-1;
1439
+ if(lv == 0)
1440
+ return f.cdr.car;
1441
+ else
1442
+ return [ Sym("list"),
1443
+ [Sym("quote"), Sym("unquote")].to_list(),
1444
+ expand_qq(f.cdr.car, lv)
1445
+ ].to_list();
1446
+ }
1447
+ else if(car === Sym("quasiquote"))
1448
+ return [
1449
+ Sym("list"),
1450
+ Sym("quasiquote"),
1451
+ expand_qq(f.cdr.car, lv+1)
1452
+ ].to_list();
1453
+ else
1454
+ return [
1455
+ Sym("cons"),
1456
+ expand_qq(f.car, lv),
1457
+ expand_qq(f.cdr, lv)
1458
+ ].to_list();
1459
+ }
1460
+ else if(f instanceof Array){
1461
+ throw new Bug("vector quasiquotation is not implemented yet");
1462
+ }
1463
+ // // `#(1 2 (unquote f))
1464
+ // // (vector 1 2 f)
1465
+ // // `#(1 2 (unquote-splicing f) 3)
1466
+ // // (vector-append
1467
+ // // (vector 1 2)
1468
+ // // f
1469
+ // // (vector 3))
1470
+ // // `#(1 2 `#(3 ,,f) 4)
1471
+ // // (vector 1 2 `#(3 ,g) 4)
1472
+ // var len = f.length;
1473
+ // if(len == 0) return f;
1474
+ //
1475
+ // var vecs = [[]];
1476
+ // for(var i=0; i<len; i++){
1477
+ // if(f[i] instanceof Pair){
1478
+ // if(f[i].car === Sym("unquote")){
1479
+ // var lv = lv - 1;
1480
+ // if(lv == 0)
1481
+ // vecs.last().push(f[i]);
1482
+ // else
1483
+ // vecs.push()
1484
+ // }
1485
+ // }
1486
+ //
1487
+ // var car = f[0];
1488
+ // if(car === Sym("unquote")){
1489
+ // var lv = lv - 1;
1490
+ // if(lv == 0)
1491
+ // return f.cdr.car;
1492
+ // else
1493
+ // return [ Sym("vector"),
1494
+ // [Sym("quote"), Sym("unquote")].to_list(),
1495
+ // expand_qq(f.cdr.car, lv)
1496
+ // ].to_list();
1497
+ // }
1498
+ // else{
1499
+ //// return [ Sym("vector"),
1500
+ //// expand_qq(
1501
+ // }
1502
+ // }
1503
+ // }
1504
+ else
1505
+ return f;
1506
+ }
1507
+ define_syntax("quasiquote", function(x){
1508
+ return expand_qq(x.cdr.car, 1);
1509
+ })
1510
+ //unquote
1511
+ define_syntax("unquote", function(x){
1512
+ throw new Error("unquote(,) must be inside quasiquote(`)");
1513
+ })
1514
+ //unquote-splicing
1515
+ define_syntax("unquote-splicing", function(x){
1516
+ throw new Error("unquote-splicing(,@) must be inside quasiquote(`)");
1517
+ })
1518
+
1519
+ // 11.18 Binding constructs for syntactic keywords
1520
+ //let-syntax
1521
+ //letrec-syntax
1522
+
1523
+ // 11.19 Macro transformers
1524
+ //syntax-rules
1525
+ //identifier-syntax
1526
+ //
1527
+
1528
+ // 11.20 Tail calls and tail contexts
1529
+ //(no library function introduced)
1530
+
1531
+
1532
+ ///
1533
+ /// R6RS Standard Libraries
1534
+ ///
1535
+
1536
+ //
1537
+ // Chapter 1 Unicode
1538
+ //
1539
+ //(char-upcase char) procedure
1540
+ //(char-downcase char) procedure
1541
+ //(char-titlecase char) procedure
1542
+ //(char-foldcase char) procedure
1543
+ //
1544
+ //(char-ci=? char1 char2 char3 ...) procedure
1545
+ //(char-ci<? char1 char2 char3 ...) procedure
1546
+ //(char-ci>? char1 char2 char3 ...) procedure
1547
+ //(char-ci<=? char1 char2 char3 ...) procedure
1548
+ //(char-ci>=? char1 char2 char3 ...) procedure
1549
+ //
1550
+ //(char-alphabetic? char) procedure
1551
+ //(char-numeric? char) procedure
1552
+ //(char-whitespace? char) procedure
1553
+ //(char-upper-case? char) procedure
1554
+ //(char-lower-case? char) procedure
1555
+ //(char-title-case? char) procedure
1556
+ //
1557
+ //(char-general-category char) procedure
1558
+
1559
+ //(string-upcase string) procedure
1560
+ //(string-downcase string) procedure
1561
+ //(string-titlecase string) procedure
1562
+ //(string-foldcase string) procedure
1563
+ //
1564
+ //(string-ci=? string1 string2 string3 ...) procedure
1565
+ //(string-ci<? string1 string2 string3 ...) procedure
1566
+ //(string-ci>? string1 string2 string3 ...) procedure
1567
+ //(string-ci<=? string1 string2 string3 ...) procedure
1568
+ //(string-ci>=? string1 string2 string3 ...) procedure
1569
+ //
1570
+ //(string-normalize-nfd string) procedure
1571
+ //(string-normalize-nfkd string) procedure
1572
+ //(string-normalize-nfc string) procedure
1573
+ //(string-normalize-nfkc string) procedure
1574
+
1575
+ //
1576
+ // Chapter 2 Bytevectors
1577
+ //
1578
+
1579
+ //
1580
+ // Chapter 3 List utilities
1581
+ //
1582
+ define_libfunc("find", 2, 2, function(ar){
1583
+ var proc = ar[0], ls = ar[1];
1584
+ assert_pair(ls);
1585
+ return Call.foreach(ls, {
1586
+ call: function(x){ return new Call(proc, [x.car]) },
1587
+ result: function(res, x){ if(res) return x.car; },
1588
+ finish: function(){ return false }
1589
+ })
1590
+ })
1591
+ define_libfunc("for-all", 2, null, function(ar){
1592
+ var proc = ar.shift();
1593
+ var lists = ar;
1594
+ lists.each(function(ls){ assert_pair(ls) });
1595
+
1596
+ var last = true; //holds last result which proc returns
1597
+ return Call.multi_foreach(lists, {
1598
+ call: function(pairs){
1599
+ return new Call(proc, pairs.map(function(x){ return x.car }));
1600
+ },
1601
+ result: function(res, pairs){
1602
+ if(res === false) return false;
1603
+ last = res;
1604
+ },
1605
+ finish: function(){ return last; }
1606
+ })
1607
+ })
1608
+ define_libfunc("exists", 2, null, function(ar){
1609
+ var proc = ar.shift();
1610
+ var lists = ar;
1611
+ lists.each(function(ls){ assert_pair(ls) });
1612
+
1613
+ return Call.multi_foreach(lists, {
1614
+ call: function(pairs){
1615
+ return new Call(proc, pairs.map(function(x){ return x.car }));
1616
+ },
1617
+ result: function(res, pairs){
1618
+ if(res !== false) return res;
1619
+ },
1620
+ finish: function(){ return false; }
1621
+ })
1622
+ })
1623
+ define_libfunc("filter", 2, 2, function(ar){
1624
+ var proc = ar[0], ls = ar[1];
1625
+ assert_pair(ls);
1626
+
1627
+ var a = [];
1628
+ return Call.foreach(ls, {
1629
+ call: function(x){ return new Call(proc, [x.car]) },
1630
+ result: function(res, x){ if(res) a.push(x.car); },
1631
+ finish: function(){ return a.to_list() }
1632
+ })
1633
+ })
1634
+ // define_scmfunc("partition+", 2, 2,
1635
+ // "(lambda (proc ls) \
1636
+ // (define (partition2 proc ls t f) \
1637
+ // (if (null? ls) \
1638
+ // (values (reverse t) (reverse f)) \
1639
+ // (if (proc (car ls)) \
1640
+ // (partition2 proc (cdr ls) (cons (car ls) t) f) \
1641
+ // (partition2 proc (cdr ls) t (cons (car ls) f))))) \
1642
+ // (partition2 proc ls '() '()))");
1643
+
1644
+ define_libfunc("partition", 2, 2, function(ar){
1645
+ var proc = ar[0], ls = ar[1];
1646
+ assert_pair(ls);
1647
+
1648
+ var t = [], f = [];
1649
+ return Call.foreach(ls, {
1650
+ call: function(x){ return new Call(proc, [x.car]) },
1651
+ result: function(res, x){
1652
+ if(res) t.push(x.car);
1653
+ else f.push(x.car);
1654
+ },
1655
+ finish: function(){
1656
+ return new Values([t.to_list(), f.to_list()]);
1657
+ }
1658
+ })
1659
+ })
1660
+ define_libfunc("fold-left", 3, null, function(ar){
1661
+ var proc = ar.shift(), accum = ar.shift(), lists = ar;
1662
+ lists.each(function(ls){ assert_pair(ls) });
1663
+
1664
+ return Call.multi_foreach(lists, {
1665
+ call: function(pairs){
1666
+ var args = pairs.map(function(x){ return x.car });
1667
+ args.unshift(accum);
1668
+ return new Call(proc, args);
1669
+ },
1670
+ result: function(res, pairs){ accum = res; },
1671
+ finish: function(){ return accum; }
1672
+ })
1673
+ })
1674
+ define_libfunc("fold-right", 3, null, function(ar){
1675
+ var proc = ar.shift(), accum = ar.shift();
1676
+ var lists = ar.map(function(ls){
1677
+ // reverse each list
1678
+ assert_pair(ls);
1679
+ return ls.to_array().reverse().to_list();
1680
+ })
1681
+
1682
+ return Call.multi_foreach(lists, {
1683
+ call: function(pairs){
1684
+ var args = pairs.map(function(x){ return x.car });
1685
+ args.push(accum);
1686
+ return new Call(proc, args);
1687
+ },
1688
+ result: function(res, pairs){ accum = res; },
1689
+ finish: function(){ return accum; }
1690
+ })
1691
+ })
1692
+ define_libfunc("remp", 2, 2, function(ar){
1693
+ var proc = ar[0], ls = ar[1];
1694
+ assert_pair(ls);
1695
+
1696
+ var ret = [];
1697
+ return Call.foreach(ls, {
1698
+ call: function(x){ return new Call(proc, [x.car]) },
1699
+ result: function(res, x){ if(!res) ret.push(x.car); },
1700
+ finish: function(){ return ret.to_list(); }
1701
+ })
1702
+ })
1703
+ var make_remover = function(key){
1704
+ return function(ar){
1705
+ var obj = ar[0], ls = ar[1];
1706
+ assert_pair(ls);
1707
+
1708
+ var ret = [];
1709
+ return Call.foreach(ls, {
1710
+ call: function(x){
1711
+ return new Call(TopEnv[key] || CoreEnv[key], [obj, x.car])
1712
+ },
1713
+ result: function(res, x){ if(!res) ret.push(x.car); },
1714
+ finish: function(){ return ret.to_list(); }
1715
+ })
1716
+ }
1717
+ }
1718
+ define_libfunc("remove", 2, 2, make_remover("equal?"));
1719
+ define_libfunc("remv", 2, 2, make_remover("eqv?"));
1720
+ define_libfunc("remq", 2, 2, make_remover("eq?"));
1721
+
1722
+ define_libfunc("memp", 2, 2, function(ar){
1723
+ var proc = ar[0], ls = ar[1];
1724
+ assert_pair(ls);
1725
+
1726
+ var ret = [];
1727
+ return Call.foreach(ls, {
1728
+ call: function(x){ return new Call(proc, [x.car]) },
1729
+ result: function(res, x){ if(res) return x; },
1730
+ finish: function(){ return false; }
1731
+ })
1732
+ })
1733
+ var make_finder = function(key){
1734
+ return function(ar){
1735
+ var obj = ar[0], ls = ar[1];
1736
+ assert_pair(ls);
1737
+
1738
+ var ret = [];
1739
+ return Call.foreach(ls, {
1740
+ call: function(x){
1741
+ return new Call(TopEnv[key] || CoreEnv[key], [obj, x.car])
1742
+ },
1743
+ result: function(res, x){ if(res) return x; },
1744
+ finish: function(){ return false; }
1745
+ })
1746
+ }
1747
+ }
1748
+ define_libfunc("member", 2, 2, make_finder("equal?"));
1749
+ define_libfunc("memv", 2, 2, make_finder("eqv?"));
1750
+ define_libfunc("memq", 2, 2, make_finder("eq?"));
1751
+
1752
+ define_libfunc("assp", 2, 2, function(ar){
1753
+ var proc = ar[0], als = ar[1];
1754
+ assert_pair(als);
1755
+
1756
+ var ret = [];
1757
+ return Call.foreach(als, {
1758
+ call: function(x){
1759
+ if(x.car.car)
1760
+ return new Call(proc, [x.car.car]);
1761
+ else
1762
+ throw new Error("ass*: pair required but got "+to_write(x.car));
1763
+ },
1764
+ result: function(res, x){ if(res) return x.car; },
1765
+ finish: function(){ return false; }
1766
+ })
1767
+ })
1768
+ var make_assoc = function(key){
1769
+ return function(ar){
1770
+ var obj = ar[0], ls = ar[1];
1771
+ assert_pair(ls);
1772
+
1773
+ var ret = [];
1774
+ return Call.foreach(ls, {
1775
+ call: function(x){
1776
+ if(x.car.car)
1777
+ return new Call(TopEnv[key] || CoreEnv[key], [obj, x.car.car])
1778
+ else
1779
+ throw new Error("ass*: pair required but got "+to_write(x.car));
1780
+ },
1781
+ result: function(res, x){ if(res) return x.car; },
1782
+ finish: function(){ return false; }
1783
+ })
1784
+ }
1785
+ }
1786
+ define_libfunc("assoc", 2, 2, make_assoc("equal?"));
1787
+ define_libfunc("assv", 2, 2, make_assoc("eqv?"));
1788
+ define_libfunc("assq", 2, 2, make_assoc("eq?"));
1789
+
1790
+ define_libfunc("cons*", 1, null, function(ar){
1791
+ if(ar.length == 1)
1792
+ return ar[0];
1793
+ else{
1794
+ var ret = null;
1795
+ ar.reverse().each(function(x){
1796
+ if(ret){
1797
+ ret = new Pair(x, ret);
1798
+ }
1799
+ else
1800
+ ret = x;
1801
+ })
1802
+ return ret;
1803
+ }
1804
+ })
1805
+
1806
+ //
1807
+ // Chapter 4 Sorting
1808
+ //
1809
+ //(list-sort proc list) procedure
1810
+ //(vector-sort proc vector) procedure
1811
+ //(vector-sort! proc vector) procedure
1812
+
1813
+ //
1814
+ // Chapter 5 Control Structures
1815
+ //
1816
+ define_syntax("when", function(x){
1817
+ //(when test body ...)
1818
+ //=> (if test (begin body ...) #<undef>)
1819
+ var test = x.cdr.car, body = x.cdr.cdr;
1820
+
1821
+ return new Pair(Sym("if"),
1822
+ new Pair(test,
1823
+ new Pair(new Pair(Sym("begin"), body),
1824
+ new Pair(BiwaScheme.undef, nil))));
1825
+ })
1826
+ define_syntax("unless", function(x){
1827
+ //(unless test body ...)
1828
+ //=> (if (not test) (begin body ...) #<undef>)
1829
+ var test = x.cdr.car, body = x.cdr.cdr;
1830
+
1831
+ return new Pair(Sym("if"),
1832
+ new Pair(new Pair(Sym("not"), new Pair(test, nil)),
1833
+ new Pair(new Pair(Sym("begin"), body),
1834
+ new Pair(BiwaScheme.undef, nil))));
1835
+ })
1836
+ //(do ((<variable1> <init1> <step1>) syntax
1837
+ //(case-lambda <case-lambda clause> ...) syntax
1838
+
1839
+ //
1840
+ // Chapter 6 Records
1841
+ //
1842
+ //eqv, eq
1843
+ //(define-record-type <name spec> <record clause>*) syntax
1844
+ //fields auxiliary syntax
1845
+ //mutable auxiliary syntax
1846
+ //immutable auxiliary syntax
1847
+ //parent auxiliary syntax
1848
+ //protocol auxiliary syntax
1849
+ //sealed auxiliary syntax
1850
+ //opaque auxiliary syntax
1851
+ //nongenerative auxiliary syntax
1852
+ //parent-rtd auxiliary syntax
1853
+ //
1854
+ //(make-record-type-descriptor name procedure
1855
+ //(record-type-descriptor? obj) procedure
1856
+ //(make-record-constructor-descriptor rtd procedure
1857
+ //(record-constructor constructor-descriptor) procedure
1858
+ //(record-predicate rtd) procedure
1859
+ //(record-accessor rtd k) procedure
1860
+ //(record-mutator rtd k) procedure
1861
+ //
1862
+ //(record? obj) procedure
1863
+ //(record-rtd record) procedure
1864
+ //(record-type-name rtd) procedure
1865
+ //(record-type-parent rtd) procedure
1866
+ //(record-type-uid rtd) procedure
1867
+ //(record-type-generative? rtd) procedure
1868
+ //(record-type-sealed? rtd) procedure
1869
+ //(record-type-opaque? rtd) procedure
1870
+ //(record-type-field-names rtd) procedure
1871
+ //(record-field-mutable? rtd k) procedure
1872
+
1873
+ //
1874
+ // Chapter 7 Exceptions and conditions
1875
+ //
1876
+ //(with-exception-handler handler thunk) procedure
1877
+ //(guard (<variable> syntax
1878
+ //(raise obj) procedure
1879
+ //(raise-continuable obj) procedure
1880
+ //
1881
+ //&condition condition type
1882
+ //(condition condition1 ...) procedure
1883
+ //(simple-conditions condition) procedure
1884
+ //(condition? obj) procedure
1885
+ //(condition-predicate rtd) procedure
1886
+ //(condition-accessor rtd proc) procedure
1887
+ //
1888
+ //&message condition type
1889
+ //&warning condition type
1890
+ //&serious condition type
1891
+ //&error condition type
1892
+ //&violation condition type
1893
+ //&assertion condition type
1894
+ //&irritants condition type
1895
+ //&who condition type
1896
+ //&non-continuable condition type
1897
+ //&implementation-restriction condition type
1898
+ //&lexical condition type
1899
+ //&syntax condition type
1900
+ //&undefined condition type
1901
+
1902
+ //
1903
+ // Chapter 8 I/O
1904
+ //
1905
+ // // 8 I/O
1906
+ // // 8.1 Condition types
1907
+ //&i/o condition type
1908
+ //&i/o-read condition type
1909
+ //&i/o-write condition type
1910
+ //&i/o-invalid-position condition type
1911
+ //&i/o-filename condition type
1912
+ //&i/o-file-protection condition type
1913
+ //&i/o-file-is-read-only condition type
1914
+ //&i/o-file-already-exists condition type
1915
+ //&i/o-file-does-not-exist condition type
1916
+ //&i/o-port condition type
1917
+ //
1918
+ // // 8.2 Port I/O
1919
+ // // 8.2.1 File names
1920
+ // //(no function introduced)
1921
+ //
1922
+ // // 8.2.2 File options
1923
+ //(file-options <file-options symbol> ...) syntax
1924
+ //
1925
+ // // 8.2.3 Buffer modes
1926
+ //(buffer-mode <buffer-mode symbol>) syntax
1927
+ //(buffer-mode? obj) procedure
1928
+ //
1929
+ // // 8.2.4 Transcoders
1930
+ //(latin-1-codec) procedure
1931
+ //(utf-8-codec) procedure
1932
+ //(utf-16-codec) procedure
1933
+ //(eol-style <eol-style symbol>) syntax
1934
+ //(native-eol-style) procedure
1935
+ //&i/o-decoding condition type
1936
+ //&i/o-encoding condition type
1937
+ //(error-handling-mode <error-handling-mode symbol>) syntax
1938
+ //(make-transcoder codec) procedure
1939
+ //(make-transcoder codec eol-style) procedure
1940
+ //(make-transcoder codec eol-style handling-mode) procedure
1941
+ //(native-transcoder) procedure
1942
+ //(transcoder-codec transcoder) procedure
1943
+ //(transcoder-eol-style transcoder) procedure
1944
+ //(transcoder-error-handling-mode transcoder) procedure
1945
+ //(bytevector->string bytevector transcoder) procedure
1946
+ //(string->bytevector string transcoder) procedure
1947
+ //
1948
+ // 8.2.5 End-of-file object
1949
+ //8.3 (eof-object) procedure
1950
+ //8.3 (eof-object? obj) procedure
1951
+
1952
+ // 8.2.6 Input and output ports
1953
+ define_libfunc("port?", 1, 1, function(ar){
1954
+ return (ar[0] instanceof Port);
1955
+ })
1956
+ //(port-transcoder port) procedure
1957
+ define_libfunc("textual-port?", 1, 1, function(ar){
1958
+ assert_port(ar[0]);
1959
+ return !ar[0].is_binary;
1960
+ })
1961
+ define_libfunc("binary-port?", 1, 1, function(ar){
1962
+ assert_port(ar[0]);
1963
+ return ar[0].is_binary;
1964
+ })
1965
+ //(transcoded-port binary-port transcoder) procedure
1966
+ //(port-has-port-position? port) procedure
1967
+ //(port-position port) procedure
1968
+ //(port-has-set-port-position!? port) procedure
1969
+ //(set-port-position! port pos) procedure
1970
+ define_libfunc("close-port", 1, 1, function(ar){
1971
+ assert_port(ar[0]);
1972
+ ar[0].close();
1973
+ return BiwaScheme.undef;
1974
+ })
1975
+ //(call-with-port port proc) procedure
1976
+
1977
+ // 8.2.7 Input ports
1978
+ //8.3 (input-port? obj) procedure
1979
+ //(port-eof? input-port) procedure
1980
+ //(open-file-input-port filename) procedure
1981
+ //(open-bytevector-input-port bytevector) procedure
1982
+ //(open-string-input-port string) procedure
1983
+ //(standard-input-port) procedure
1984
+ //8.3 (current-input-port) procedure
1985
+ //(make-custom-binary-input-port id read! procedure
1986
+ //(make-custom-textual-input-port id read! procedure
1987
+ //
1988
+ // // 8.2.8 Binary input
1989
+ //(get-u8 binary-input-port) procedure
1990
+ //(lookahead-u8 binary-input-port) procedure
1991
+ //(get-bytevector-n binary-input-port count) procedure
1992
+ //(get-bytevector-n! binary-input-port procedure
1993
+ //(get-bytevector-some binary-input-port) procedure
1994
+ //(get-bytevector-all binary-input-port) procedure
1995
+ //
1996
+ // // 8.2.9 Textual input
1997
+ //(get-char textual-input-port) procedure
1998
+ //(lookahead-char textual-input-port) procedure
1999
+ //(get-string-n textual-input-port count) procedure
2000
+ //(get-string-n! textual-input-port string start count) procedure
2001
+ //(get-string-all textual-input-port) procedure
2002
+ //(get-line textual-input-port) procedure
2003
+ //(get-datum textual-input-port) procedure
2004
+ //
2005
+ // 8.2.10 Output ports
2006
+ //8.3 (output-port? obj) procedure
2007
+ //(flush-output-port output-port) procedure
2008
+ //(output-port-buffer-mode output-port) procedure
2009
+ //(open-file-output-port filename) procedure
2010
+ //(open-bytevector-output-port) procedure
2011
+ //(call-with-bytevector-output-port proc) procedure
2012
+ //(open-string-output-port) procedure
2013
+ //(call-with-string-output-port proc) procedure
2014
+ //(standard-output-port) procedure
2015
+ //(standard-error-port) procedure
2016
+ //8.3 (current-output-port) procedure
2017
+ //8.3 (current-error-port) procedure
2018
+ //(make-custom-binary-output-port id procedure
2019
+ //(make-custom-textual-output-port id write! get-position set-position! close)
2020
+ // define_libfunc("make-custom-textual-output-port", 5, 5, function(ar){
2021
+ // assert_string(ar[0]);
2022
+ // assert_closure(ar[1]);
2023
+ // assert_closure(ar[2]);
2024
+ // assert_closure(ar[3]);
2025
+ // assert_closure(ar[4]);
2026
+ // return new Port(ar[0], ar[1], ar[2], ar[3], ar[4]);
2027
+ // })
2028
+ //
2029
+ // // 8.2.11 Binary output
2030
+ //(put-u8 binary-output-port octet) procedure
2031
+ //(put-bytevector binary-output-port bytevector) procedure
2032
+ //
2033
+ // 8.2.12 Textual output
2034
+ define_libfunc("put-char", 2, 2, function(ar){
2035
+ assert_port(ar[0]);
2036
+ assert_char(ar[1]);
2037
+ ar[0].put_string(ar[1].value);
2038
+ return BiwaScheme.undef;
2039
+ })
2040
+ define_libfunc("put-string", 2, 2, function(ar){
2041
+ assert_port(ar[0]);
2042
+ assert_string(ar[1]);
2043
+ ar[0].put_string(ar[1]);
2044
+ return BiwaScheme.undef;
2045
+ })
2046
+ define_libfunc("put-datum", 2, 2, function(ar){
2047
+ assert_port(ar[0]);
2048
+ ar[0].put_string(to_write(ar[1]));
2049
+ return BiwaScheme.undef;
2050
+ })
2051
+ //
2052
+ // // 8.2.13 Input/output ports
2053
+ //(open-file-input/output-port filename) procedure
2054
+ //(make-custom-binary-input/output-port procedure
2055
+ //(make-custom-textual-input/output-port procedure
2056
+ //
2057
+ // // 8.3 Simple I/O
2058
+ define_libfunc("eof-object", 0, 0, function(ar){
2059
+ return eof;
2060
+ })
2061
+ define_libfunc("eof-object?", 1, 1, function(ar){
2062
+ return ar[0] === eof;
2063
+ })
2064
+ //(call-with-input-file filename proc) procedure
2065
+ //(call-with-output-file filename proc) procedure
2066
+ define_libfunc("input-port?", 1, 1, function(ar){
2067
+ assert_port(ar[0]);
2068
+ return ar[0].is_input;
2069
+ })
2070
+ define_libfunc("output-port?", 1, 1, function(ar){
2071
+ assert_port(ar[0]);
2072
+ return ar[0].is_output;
2073
+ })
2074
+ define_libfunc("current-input-port", 0, 0, function(ar){
2075
+ return Port.current_input;
2076
+ })
2077
+ define_libfunc("current-output-port", 0, 0, function(ar){
2078
+ return Port.current_output;
2079
+ })
2080
+ define_libfunc("current-error-port", 0, 0, function(ar){
2081
+ return Port.current_error;
2082
+ })
2083
+ //(with-input-from-file filename thunk) procedure
2084
+ //(with-output-to-file filename thunk) procedure
2085
+ //(open-input-file filename) procedure
2086
+ //(open-output-file filename) procedure
2087
+ define_libfunc("close-input-port", 1, 1, function(ar){
2088
+ assert_port(ar[0]);
2089
+ if(!ar[0].is_input)
2090
+ throw new Error("close-input-port: port is not input port");
2091
+ ar[0].close();
2092
+ return BiwaScheme.undef;
2093
+ });
2094
+ define_libfunc("close-output-port", 1, 1, function(ar){
2095
+ assert_port(ar[0]);
2096
+ if(!ar[0].is_output)
2097
+ throw new Error("close-output-port: port is not output port");
2098
+ ar[0].close();
2099
+ return BiwaScheme.undef;
2100
+ });
2101
+ //(read-char) procedure
2102
+ //(peek-char) procedure
2103
+ define_libfunc("read", 0, 0, function(ar){
2104
+ return Port.current_input.get_string(function(str){
2105
+ return Interpreter.read(str);
2106
+ })
2107
+ })
2108
+
2109
+ // write-char [1,2]
2110
+ define_libfunc("newline", 0, 1, function(ar){
2111
+ var port = ar[0] || Port.current_output;
2112
+ port.put_string("\n");
2113
+ return BiwaScheme.undef;
2114
+ });
2115
+ define_libfunc("display", 1, 2, function(ar){
2116
+ var port = ar[1] || Port.current_output;
2117
+ port.put_string(to_display(ar[0]));
2118
+ return BiwaScheme.undef;
2119
+ });
2120
+ define_libfunc("write", 1, 2, function(ar){
2121
+ var port = ar[1] || Port.current_output;
2122
+ port.put_string(to_write(ar[0]));
2123
+ return BiwaScheme.undef;
2124
+ });
2125
+
2126
+ //
2127
+ // Chapter 9 File System
2128
+ //
2129
+ //(file-exists? filename) procedure
2130
+ define_libfunc("file-exists?", 1, 1, function(ar){
2131
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); //TODO: extract to a function
2132
+ assert_string(ar[0]);
2133
+ var fileIn = FileIO.open(ar[0]);
2134
+ return fileIn.exists();
2135
+ });
2136
+ //(delete-file filename) procedure
2137
+ define_libfunc("delete-file", 1, 1, function(ar){
2138
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); //TODO: extract to a function
2139
+ assert_string(ar[0]);
2140
+ var deleted = FileIO.unlink(FileIO.open(ar[0]));
2141
+ if(!deleted){
2142
+ //TODO: raise %i/o-filename if not found or not deletable
2143
+ puts("delete-file: cannot delete " + ar[0]);
2144
+ }
2145
+ return BiwaScheme.undef;
2146
+ });
2147
+
2148
+ //
2149
+ // Chapter 10 Command-line access and exit values
2150
+ //
2151
+ //(command-line) procedure
2152
+ //(exit) procedure
2153
+ //(exit obj) procedure
2154
+
2155
+ //
2156
+ // Chapter 11 Arithmetic
2157
+ //
2158
+ //// 11.1 Bitwise operations
2159
+ //// 11.2 Fixnums
2160
+ //(fixnum? obj) procedure
2161
+ //(fixnum-width) procedure
2162
+ //(least-fixnum) procedure
2163
+ //(greatest-fixnum) procedure
2164
+ //(fx=? fx1 fx2 fx3 ...) procedure
2165
+ //(fx>? fx1 fx2 fx3 ...) procedure
2166
+ //(fx<? fx1 fx2 fx3 ...) procedure
2167
+ //(fx>=? fx1 fx2 fx3 ...) procedure
2168
+ //(fx<=? fx1 fx2 fx3 ...) procedure
2169
+ //(fxzero? fx) procedure
2170
+ //(fxpositive? fx) procedure
2171
+ //(fxnegative? fx) procedure
2172
+ //(fxodd? fx) procedure
2173
+ //(fxeven? fx) procedure
2174
+ //(fxmax fx1 fx2 ...) procedure
2175
+ //(fxmin fx1 fx2 ...) procedure
2176
+ //(fx+ fx1 fx2) procedure
2177
+ //(fx* fx1 fx2) procedure
2178
+ //(fx- fx1 fx2) procedure
2179
+ //(fxdiv-and-mod fx1 fx2) procedure
2180
+ //(fxdiv fx1 fx2) procedure
2181
+ //(fxmod fx1 fx2) procedure
2182
+ //(fxdiv0-and-mod0 fx1 fx2) procedure
2183
+ //(fxdiv0 fx1 fx2) procedure
2184
+ //(fxmod0 fx1 fx2) procedure
2185
+ //(fx+/carry fx1 fx2 fx3) procedure
2186
+ //(fx-/carry fx1 fx2 fx3) procedure
2187
+ //(fx*/carry fx1 fx2 fx3) procedure
2188
+ //(fxnot fx) procedure
2189
+ //(fxand fx1 ...) procedure
2190
+ //(fxior fx1 ...) procedure
2191
+ //(fxxor fx1 ...) procedure
2192
+ //(fxif fx1 fx2 fx3) procedure
2193
+ //(fxbit-count fx) procedure
2194
+ //(fxlength fx) procedure
2195
+ //(fxfirst-bit-set fx) procedure
2196
+ //(fxbit-set? fx1 fx2) procedure
2197
+ //(fxcopy-bit fx1 fx2 fx3) procedure
2198
+ //(fxbit-field fx1 fx2 fx3) procedure
2199
+ //(fxcopy-bit-field fx1 fx2 fx3 fx4) procedure
2200
+ //(fxarithmetic-shift fx1 fx2) procedure
2201
+ //(fxarithmetic-shift-left fx1 fx2) procedure
2202
+ //(fxarithmetic-shift-right fx1 fx2) procedure
2203
+ //(fxrotate-bit-field fx1 fx2 fx3 fx4) procedure
2204
+ //(fxreverse-bit-field fx1 fx2 fx3) procedure
2205
+ //
2206
+ //// 11.3 Flonums
2207
+ //(flonum? obj) procedure
2208
+ //(real->flonum x) procedure
2209
+ //(fl=? fl1 fl2 fl3 ...) procedure
2210
+ //(fl<? fl1 fl2 fl3 ...) procedure
2211
+ //(fl<=? fl1 fl2 fl3 ...) procedure
2212
+ //(fl>? fl1 fl2 fl3 ...) procedure
2213
+ //(fl>=? fl1 fl2 fl3 ...) procedure
2214
+ //(flinteger? fl) procedure
2215
+ //(flzero? fl) procedure
2216
+ //(flpositive? fl) procedure
2217
+ //(flnegative? fl) procedure
2218
+ //(flodd? ifl) procedure
2219
+ //(fleven? ifl) procedure
2220
+ //(flfinite? fl) procedure
2221
+ //(flinfinite? fl) procedure
2222
+ //(flnan? fl) procedure
2223
+ //(flmax fl1 fl2 ...) procedure
2224
+ //(flmin fl1 fl2 ...) procedure
2225
+ //(fl+ fl1 ...) procedure
2226
+ //(fl* fl1 ...) procedure
2227
+ //(fl- fl1 fl2 ...) procedure
2228
+ //(fl- fl) procedure
2229
+ //(fl/ fl1 fl2 ...) procedure
2230
+ //(fl/ fl) procedure
2231
+ //(flabs fl) procedure
2232
+ //(fldiv-and-mod fl1 fl2) procedure
2233
+ //(fldiv fl1 fl2) procedure
2234
+ //(flmod fl1 fl2) procedure
2235
+ //(fldiv0-and-mod0 fl1 fl2) procedure
2236
+ //(fldiv0 fl1 fl2) procedure
2237
+ //(flmod0 fl1 fl2) procedure
2238
+ //(flnumerator fl) procedure
2239
+ //(fldenominator fl) procedure
2240
+ //(flfloor fl) procedure
2241
+ //(flceiling fl) procedure
2242
+ //(fltruncate fl) procedure
2243
+ //(flround fl) procedure
2244
+ //(flexp fl) procedure
2245
+ //(fllog fl) procedure
2246
+ //(fllog fl1 fl2) procedure
2247
+ //(flsin fl) procedure
2248
+ //(flcos fl) procedure
2249
+ //(fltan fl) procedure
2250
+ //(flasin fl) procedure
2251
+ //(flacos fl) procedure
2252
+ //(flatan fl) procedure
2253
+ //(flatan fl1 fl2) procedure
2254
+ //(flsqrt fl) procedure
2255
+ //(flexpt fl1 fl2) procedure
2256
+ //&no-infinities condition type
2257
+ //&no-nans condition type
2258
+ //(fixnum->flonum fx) procedure
2259
+ //
2260
+ //// 11.4 Exact bitwise arithmetic
2261
+ //(bitwise-not ei) procedure
2262
+ //(bitwise-and ei1 ...) procedure
2263
+ //(bitwise-ior ei1 ...) procedure
2264
+ //(bitwise-xor ei1 ...) procedure
2265
+ //(bitwise-if ei1 ei2 ei3) procedure
2266
+ //(bitwise-bit-count ei) procedure
2267
+ //(bitwise-length ei) procedure
2268
+ //(bitwise-first-bit-set ei) procedure
2269
+ //(bitwise-bit-set? ei1 ei2) procedure
2270
+ //(bitwise-copy-bit ei1 ei2 ei3) procedure
2271
+ //(bitwise-bit-field ei1 ei2 ei3) procedure
2272
+ //(bitwise-copy-bit-field ei1 ei2 ei3 ei4) procedure
2273
+ //(bitwise-arithmetic-shift ei1 ei2) procedure
2274
+ //(bitwise-arithmetic-shift-left ei1 ei2) procedure
2275
+ //(bitwise-arithmetic-shift-right ei1 ei2) procedure
2276
+ //(bitwise-arithmetic-shift-right ei1 ei2)
2277
+ //(bitwise-rotate-bit-field ei1 ei2 ei3 ei4) procedure
2278
+ //(bitwise-reverse-bit-field ei1 ei2 ei3) procedure
2279
+
2280
+
2281
+ //
2282
+ // Chapter 12 syntax-case
2283
+ //
2284
+
2285
+ //
2286
+ // Chapter 13 Hashtables
2287
+ //
2288
+ Hash.prototype.to_write = function(){
2289
+ return "#<Hashtable:size=" + this.keys().length + ">";
2290
+ };
2291
+ //13.1 Constructors
2292
+ //(define h (make-eq-hashtale)
2293
+ //(define h (make-eq-hashtable 1000))
2294
+ define_libfunc("make-eq-hashtable", 0, 1, function(ar){
2295
+ // ar[1] (hashtable size) is just ignored
2296
+ return $H({});
2297
+ });
2298
+ //(make-eqv-hashtable) procedure
2299
+ //(make-eqv-hashtable k) procedure
2300
+ //(make-hashtable hash-function equiv) procedure
2301
+ //(make-hashtable hash-function equiv k) procedure
2302
+
2303
+ //13.2 Procedures
2304
+ // (hashtable? hash)
2305
+ define_libfunc("hashtable?", 1, 1, function(ar){
2306
+ return ar[0] instanceof Hash;
2307
+ });
2308
+ //(hashtable-size hash)
2309
+ define_libfunc("hashtable-size", 1, 1, function(ar){
2310
+ assert_hashtable(ar[0]);
2311
+ return ar[0].keys().length;
2312
+ });
2313
+ //(hashtable-ref hash "foo" #f)
2314
+ define_libfunc("hashtable-ref", 3, 3, function(ar){
2315
+ assert_hashtable(ar[0]);
2316
+ var found = ar[0].get(ar[1]);
2317
+
2318
+ if (found === undefined)
2319
+ return ar[2];
2320
+ else
2321
+ return found;
2322
+ });
2323
+ //(hashtable-set! hash "foo" '(1 2))
2324
+ define_libfunc("hashtable-set!", 3, 3, function(ar){
2325
+ assert_hashtable(ar[0]);
2326
+ ar[0].set(ar[1], ar[2]);
2327
+ return BiwaScheme.undef;
2328
+ });
2329
+ //(hashtable-delete! hash "foo")
2330
+ define_libfunc("hashtable-delete!", 2, 2, function(ar){
2331
+ assert_hashtable(ar[0]);
2332
+ ar[0].unset(ar[1]);
2333
+ return BiwaScheme.undef;
2334
+ });
2335
+ //(hashtable-contains? hash "foo")
2336
+ define_libfunc("hashtable-contains?", 2, 2, function(ar){
2337
+ assert_hashtable(ar[0]);
2338
+ return ar[0].get(ar[1]) !== undefined;
2339
+ });
2340
+ //(hashtable-update! hashtable key proc default) procedure
2341
+ //(hashtable-copy hashtable) procedure
2342
+ //(hashtable-copy hashtable mutable) procedure
2343
+ //(hashtable-clear! hashtable) procedure
2344
+ //(hashtable-clear! hashtable k) procedure
2345
+ //(hashtable-keys hash) ; => vector
2346
+ define_libfunc("hashtable-keys", 1, 1, function(ar){
2347
+ assert_hashtable(ar[0]);
2348
+ return ar[0].keys();
2349
+ });
2350
+ //(hashtable-entries hash) ; => two vectors (keys, values)
2351
+ define_libfunc("hashtable-entries", 1, 1, function(ar){
2352
+ assert_hashtable(ar[0]);
2353
+ return new Values([ar[0].keys(), ar[0].values()]);
2354
+ //Note: Values of two vectors shall correspond to each other.
2355
+ // This code assumes Hash#each to always iterate
2356
+ // hash entries in the same order (is this true?)
2357
+ });
2358
+
2359
+ //13.3 Inspection
2360
+ //(hashtable-equivalence-function hashtable) procedure
2361
+ //(hashtable-hash-function hashtable) procedure
2362
+ //(hashtable-mutable? hashtable) procedure
2363
+ //13.4 Hash functions
2364
+ //(equal-hash obj) procedure
2365
+ //(string-hash string) procedure
2366
+ //(string-ci-hash string) procedure
2367
+ //(symbol-hash symbol) procedure
2368
+
2369
+ //
2370
+ // Chapter 14 Enumerators
2371
+ //
2372
+ //(make-enumeration symbol-list) procedure
2373
+ //(enum-set-universe enum-set) procedure
2374
+ //(enum-set-indexer enum-set) procedure
2375
+ //(enum-set-constructor enum-set) procedure
2376
+ //(enum-set->list enum-set) procedure
2377
+ //(enum-set-member? symbol enum-set) procedure
2378
+ //(enum-set-subset? enum-set1 enum-set2) procedure
2379
+ //(enum-set=? enum-set1 enum-set2) procedure
2380
+ //(enum-set-union enum-set1 enum-set2) procedure
2381
+ //(enum-set-intersection enum-set1 enum-set2) procedure
2382
+ //(enum-set-difference enum-set1 enum-set2) procedure
2383
+ //(enum-set-complement enum-set) procedure
2384
+ //(enum-set-projection enum-set1 enum-set2) procedure
2385
+ //(define-enumeration <type-name> syntax
2386
+ //(<symbol> ...)
2387
+ //<constructor-syntax>)
2388
+
2389
+ //
2390
+ // Chapter 15 Composite library
2391
+ //
2392
+ //(rnrs 6) = all - eval - mutable pairs - mutable strings - r5rs compatibility
2393
+
2394
+ //
2395
+ // Chapter 16 eval
2396
+ //
2397
+ //(eval expression environment) procedure
2398
+ define_libfunc("eval", 1, 1, function(ar, intp){
2399
+ //TODO: environment
2400
+ //TODO: this implementation has a bug that
2401
+ // expressions which contains #<undef>, etc. cannot be evaluated.
2402
+ var expr = ar[0];
2403
+ var intp = new BiwaScheme.Interpreter(intp.on_error);
2404
+
2405
+ return intp.evaluate(expr.to_write());
2406
+ });
2407
+ //(environment import-spec ...) procedure
2408
+
2409
+ //
2410
+ // Chapter 17 Mutable pairs
2411
+ //
2412
+ //(set-car! pair obj) procedure
2413
+ //(set-cdr! pair obj) procedure
2414
+
2415
+ //
2416
+ // Chapter 18 Mutable strings
2417
+ //
2418
+ //(string-set! string k char) procedure
2419
+ // (string-fill! string char) procedure
2420
+
2421
+ //
2422
+ // Chapter 19 R5RS compatibility
2423
+ //
2424
+ //(exact->inexact z) procedure
2425
+ //(inexact->exact z) procedure
2426
+ //
2427
+ //(quotient n1 n2) procedure
2428
+ //(remainder n1 n2) procedure
2429
+ //(modulo n1 n2) procedure
2430
+ //
2431
+ //(delay <expression>) syntax
2432
+ //(force promise) procedure
2433
+ //(make-promise (lambda () <expression>))
2434
+ //
2435
+ //(null-environment n) procedure
2436
+ //(scheme-report-environment n) procedure
2437
+
2438
+ /* --------------------------------------- namespace webscheme */
2439
+ }