-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPLS.bas
More file actions
2039 lines (2039 loc) · 95.5 KB
/
PLS.bas
File metadata and controls
2039 lines (2039 loc) · 95.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
REM 0001 <!DOCTYPE html>
REM 0002 <html>
REM 0003 <head>
REM 0004 " <meta charset=""utf-8"" />"
REM 0005 " <title>EmuLisp Console</title>"
REM 0006 " <meta name=""generator"" content=""BBEdit 9.6"" />"
REM 0007 " <style type=""text/css"" title=""text/css"">"
REM 0008 body {
REM 0009 " margin: 12px 16px 0 16px;"
REM 0010 " background-color: #f0ecd0;"
REM 0011 }
REM 0012 div#head {
REM 0013 " white-space: nowrap;"
REM 0014 }
REM 0015 span#presentation {
REM 0016 " border: 1px solid gray;"
REM 0017 " border-radius: 4px;"
REM 0018 " padding: 4px 12px 4px 12px;"
REM 0019 " font: 15px Optima;"
REM 0020 " background-color: white;"
REM 0021 }
REM 0022 span#presentation em {
REM 0023 " font-size: 18px;"
REM 0024 }
REM 0025 img#infosymbol {
REM 0026 " position: relative;"
REM 0027 " top: 5px;"
REM 0028 " margin: 0 0 0 8px;"
REM 0029 " cursor: pointer;"
REM 0030 }
REM 0031 div#main {
REM 0032 " position: relative;"
REM 0033 " top: 7px;"
REM 0034 }
REM 0035 div#dcons {
REM 0036 " width: 520px;"
REM 0037 }
REM 0038 div#log {
REM 0039 " margin: 0;"
REM 0040 " width: 101.3%;"
REM 0041 " border: 1px solid gray;"
REM 0042 " border-bottom: none;"
REM 0043 " overflow: auto;"
REM 0044 " background-color: white;"
REM 0045 }
REM 0046 div#log pre {
REM 0047 " margin: 0 1px 0 1px;"
REM 0048 " padding: 2px 2px 2px 4px;"
REM 0049 }
REM 0050 pre.oldcode {
REM 0051 " background-color: #f0f5f7;"
REM 0052 " cursor: pointer;"
REM 0053 }
REM 0054 pre.filedrop {
REM 0055 " border-left: 4px solid #c0c5c7;"
REM 0056 " background-color: #f0f5f7;"
REM 0057 }
REM 0058 pre.print {
REM 0059 " background-color: #def;"
REM 0060 }
REM 0061 pre.println {
REM 0062 " background-color: #def;"
REM 0063 " border-bottom: 1px solid #bcf;"
REM 0064 }
REM 0065 pre.result {
REM 0066 " background-color: #dfd;"
REM 0067 " border-bottom: 1px solid #9b9;"
REM 0068 }
REM 0069 pre.warning {
REM 0070 " border-left: 4px solid #db3;"
REM 0071 " background-color: #ffa;"
REM 0072 }
REM 0073 pre.error {
REM 0074 " border-left: 4px solid #f33;"
REM 0075 " background-color: #fdd;"
REM 0076 }
REM 0077 textarea#newcode {
REM 0078 " margin: 0 0 4px 0;"
REM 0079 " width: inherit;"
REM 0080 " border: 1px solid gray;"
REM 0081 " padding: 2px 0 0 6px;"
REM 0082 " font: inherit;"
REM 0083 }
REM 0084 span#version {
REM 0085 " margin-left: 8px;"
REM 0086 " font: italic 11px Arial, sans-serif;"
REM 0087 }
REM 0088 div#dcons span#controls {
REM 0089 " float: right;"
REM 0090 }
REM 0091 div#dcons span#controls span {
REM 0092 " margin: 0;"
REM 0093 " border: 1px solid gray;"
REM 0094 " padding: 2px 4px 2px 4px;"
REM 0095 " font: 14px monospace;"
REM 0096 " background-color: white;"
REM 0097 }
REM 0098 div#dcons span#controls .nosymbol {
REM 0099 " color: black;"
REM 0100 " cursor: text;"
REM 0101 }
REM 0102 div#dcons span#controls .builtin {
REM 0103 " color: #00e;"
REM 0104 " cursor: pointer;"
REM 0105 }
REM 0106 div#dcons span#controls .othersymbol {
REM 0107 " color: #00e;"
REM 0108 " cursor: pointer;"
REM 0109 " background-color: #def;"
REM 0110 }
REM 0111 div#dcons input[type='button'] {
REM 0112 }
REM 0113 div#monitor {
REM 0114 " position: absolute;"
REM 0115 " top: 0;"
REM 0116 " left: 534px;"
REM 0117 " font: 15px Optima;"
REM 0118 }
REM 0119 div#monitor input[type='text'] {
REM 0120 " margin: 0 0 4px 0;"
REM 0121 " width: 300px;"
REM 0122 " font: 15px monospace;"
REM 0123 }
REM 0124 canvas#monView {
REM 0125 " border: 1px solid gray;"
REM 0126 " background-color: white;"
REM 0127 }
REM 0128 div#prefs {
REM 0129 " visibility: hidden;"
REM 0130 " position: absolute;"
REM 0131 " top: 46px;"
REM 0132 " left: 160px;"
REM 0133 " border: 2px ridge #999;"
REM 0134 " background-color: white;"
REM 0135 " -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.3);"
REM 0136 " -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.3);"
REM 0137 " box-shadow: 4px 4px 8px rgba(0,0,0,0.3);"
REM 0138 " padding: 0 0 2px 0;"
REM 0139 " font: 14px Optima;"
REM 0140 }
REM 0141 p.paneHead {
REM 0142 " margin: 0 0 8px 0;"
REM 0143 " border-bottom: 1px solid #bbb;"
REM 0144 " background-color: #ddd;"
REM 0145 " padding: 0 0 1px 0;"
REM 0146 }
REM 0147 span.closebox {
REM 0148 " position: relative;"
REM 0149 " margin: 0;"
REM 0150 " left: 92%;"
REM 0151 " border: 1px solid #999;"
REM 0152 " background-color: #f9f9f9;"
REM 0153 " padding: 0 3px 0 3px;"
REM 0154 " text-align: center;"
REM 0155 " font: 10px Arial, sans-serif;"
REM 0156 " cursor: default;"
REM 0157 }
REM 0158 span.closebox:hover {
REM 0159 " color: #d22;"
REM 0160 }
REM 0161 p.pref {
REM 0162 " margin: 0 16px 8px 14px;"
REM 0163 }
REM 0164 div#prefs input[type='checkbox'] {
REM 0165 " margin: 0 6px 0 0;"
REM 0166 }
REM 0167 div#prefs input[type='text'] {
REM 0168 " background-color: #ffd;"
REM 0169 " padding-left: 2px;"
REM 0170 }
REM 0171
REM 0172 "/* below are the following script sections (in one script tag)"
REM 0173 " <script src=""http://folk.uio.no/jkleiser/pico/emuLisp/src/core.js"" type=""text/javascript""></script>"
REM 0174 <script src="http://folk.uio.no/jkleiser/pico/emuLisp/src/js.js" type="text/javascript"></script>
REM 0175 */
REM 0176
REM 0177
REM 0178 " </style>"
REM 0179
REM 0180 " <script src=""http://folk.uio.no/jkleiser/pico/emuLisp/src/js.js"" type=""text/javascript""></script>"
REM 0181
REM 0182 <script type="text/javascript">
REM 0183 /* 26nov10jk
REM 0184 * (c) Jon Kleiser
REM 0185 * http://folk.uio.no/jkleiser/pico/emuLisp/src/core.js
REM 0186 */
REM 0187 var BOXNAT_EXP = "Boxed native object expected",
REM 0188 " BOOL_EXP = ""Boolean expected"", CELL_EXP = ""Cell expected"", LIST_EXP = ""List expected"","
REM 0189 " NUM_EXP = ""Number expected"", SYM_EXP = ""Symbol expected"", VAR_EXP = ""Variable expected"","
REM 0190 " EXEC_OR_NUM_EXP = ""Executable or Number expected"","
REM 0191 " BAD_ARG = ""Bad argument"", BAD_DOT = ""Bad dotted pair"", BAD_INPUT = ""Bad input"", DIV_0 = ""Div/0"","
REM 0192 " NOT_MAK = ""Not making"", PROT_SYM = ""Protected symbol"", UNDEF = ""Undefined"","
REM 0193 " JS_CTORNAME_EXP = ""Constructor name expected"", JS_RESERVED = ""Reserved word"";"
REM 0194
REM 0195 function getFileSync(fileUrl) {
REM 0196 " var req = new XMLHttpRequest();"
REM 0197 " req.open(""GET"", fileUrl, false); // synchronous"
REM 0198 " req.overrideMimeType(""text/plain; charset=utf-8"");"
REM 0199 " req.send(null);"
REM 0200 " if (req.status == 0) {"
REM 0201 " return req.responseText;"
REM 0202 " }"
REM 0203 " throw new Error(""XMLHttpRequest status: "" + req.status);"
REM 0204 }
REM 0205
REM 0206 var NILTYPE = 0, NUMBERTYPE = 1, SYMBOLTYPE = 2, CELLTYPE = 3, TRUETYPE = 4;
REM 0207
REM 0208 Number.prototype.TYPEVAL = NUMBERTYPE;
REM 0209
REM 0210 function lispToStr(x) {
REM 0211 " //if (!confirm(""lispToStr: "" + x.toString() + "", "" + x.TYPEVAL)) throw new Error(""lispToStr aborted"");"
REM 0212 " return x.toString();"
REM 0213 }
REM 0214
REM 0215 function unknown(x) {
REM 0216 " if (!confirm(""Unknown Lisp type: "" + x)) throw new Error(""unknown aborted"");"
REM 0217 " return ""???"";"
REM 0218 }
REM 0219
REM 0220 function valueToStr(x) {
REM 0221 " //if (!confirm(""valueToStr "" + lispToStr(x))) throw new Error(""valueToStr aborted"");"
REM 0222 " return (x instanceof Number) ? x.toString() :"
REM 0223 " (x instanceof Symbol) ? x.toValueString() :"
REM 0224 " (x instanceof Cell) ? x.toValueString() : unknown(x);"
REM 0225 }
REM 0226
REM 0227 function Cell(car, cdr) {
REM 0228 " this.car = car;"
REM 0229 " this.cdr = cdr;"
REM 0230 }
REM 0231
REM 0232 Cell.prototype.TYPEVAL = CELLTYPE;
REM 0233
REM 0234 Cell.prototype.getVal = function() {
REM 0235 " return this.car;"
REM 0236 }
REM 0237
REM 0238 Cell.prototype.setVal = function(val) {
REM 0239 " this.car = val;"
REM 0240 }
REM 0241
REM 0242 Cell.prototype.toString = function() {
REM 0243 " if (this.car === QUOTE) return ""'"" + lispToStr(this.cdr);"
REM 0244 " var arr = [], c = this;"
REM 0245 " do {"
REM 0246 " arr.push(lispToStr(c.car));"
REM 0247 " c = c.cdr;"
REM 0248 " //if (!confirm(""Cell.toString: "" + lispToStr(c.car))) throw new Error(""Cell.toString aborted"");"
REM 0249 " if (c === this) { arr.push("".""); c = NIL; } // why didn't break work here?"
REM 0250 " } while (c instanceof Cell);"
REM 0251 " if (c !== NIL) {"
REM 0252 " arr.push(""."", lispToStr(c)); // last Cell was dotted"
REM 0253 " }"
REM 0254 " return ""("" + arr.join("" "") + "")"";"
REM 0255 }
REM 0256
REM 0257 Cell.prototype.toValueString = function() {
REM 0258 " var str = """", c = this;"
REM 0259 " do {"
REM 0260 " str += valueToStr(c.car);"
REM 0261 " c = c.cdr;"
REM 0262 " } while (c instanceof Cell);"
REM 0263 " if (c !== NIL) {"
REM 0264 " str += valueToStr(c); // last Cell was dotted"
REM 0265 " }"
REM 0266 " return str;"
REM 0267 }
REM 0268
REM 0269 function Symbol(name, val) {
REM 0270 " this.name = name;"
REM 0271 " this.trans = false;"
REM 0272 " this.cdr = (val === undefined) ? NIL : val;"
REM 0273 " this.props = NIL;"
REM 0274 }
REM 0275
REM 0276 function newTransSymbol(name) {
REM 0277 " var ts = new Symbol(name);"
REM 0278 " ts.trans = true;"
REM 0279 " ts.cdr = ts;"
REM 0280 " return ts;"
REM 0281 }
REM 0282
REM 0283 // Creates and returns a new anonymous symbol
REM 0284 function box(val) {
REM 0285 " var ts = new Symbol(null, val);"
REM 0286 " ts.trans = true;"
REM 0287 " return ts;"
REM 0288 }
REM 0289
REM 0290 function boxNativeObject(obj) {
REM 0291 " var ts = newTransSymbol(null);"
REM 0292 " ts.obj = obj;"
REM 0293 " return ts;"
REM 0294 }
REM 0295
REM 0296 Symbol.prototype.TYPEVAL = SYMBOLTYPE;
REM 0297
REM 0298 Symbol.prototype.getVal = function() {
REM 0299 " return this.cdr;"
REM 0300 }
REM 0301
REM 0302 Symbol.prototype.valueOf = function() {
REM 0303 " return this.name;"
REM 0304 }
REM 0305
REM 0306 Symbol.prototype.setVal = function(val) {
REM 0307 " if (this.lock) throw new Error(newErrMsg(PROT_SYM, this));"
REM 0308 " this.cdr = val;"
REM 0309 }
REM 0310
REM 0311 // Internal symbol names can consist of any printable (non-whitespace) character,
REM 0312 "// except for the following meta characters: "" ' ( ) , [ ] ` ~ { }"
REM 0313 // It is possible, though, to include these special characters into symbol names
REM 0314 // by escaping them with a backslash '\'.
REM 0315 Symbol.prototype.escName = function() {
REM 0316 " var eName = this.name.replace(/\\/g, ""\\\\"");"
REM 0317 " eName = eName.replace(/\^/g, ""Error! Hyperlink reference not valid."");"
REM 0318 " eName = eName.replace(/\t/g, ""^I"");"
REM 0319 " eName = eName.replace(/\r/g, ""^M"");"
REM 0320 " eName = eName.replace(/\n/g, ""^J"");"
REM 0321 " //if (eName != this.name) alert(""Symbol.escName: "" + this.name + "" -> "" + eName);"
REM 0322 " return eName;"
REM 0323 }
REM 0324
REM 0325 Symbol.prototype.noName = function() {
REM 0326 " return (this.obj !== undefined) ? ""$"" + typeof this.obj : ""$*"";"
REM 0327 }
REM 0328
REM 0329 Symbol.prototype.toString = function() {
REM 0330 " return this.trans ? (this.name != null) ? ('""' + this.escName() + '""') : this.noName() : this.name;"
REM 0331 }
REM 0332
REM 0333 Symbol.prototype.toValueString = function() {
REM 0334 " return (this === NIL) ? """" : (this.name != null) ? this.name : this.noName();"
REM 0335 }
REM 0336
REM 0337 Symbol.prototype.pushValue = function(val) {
REM 0338 " if (this.stack === undefined) this.stack = [];"
REM 0339 " this.stack.push(this.cdr);"
REM 0340 " this.cdr = val;"
REM 0341 }
REM 0342
REM 0343 Symbol.prototype.popValue = function() {
REM 0344 " var pv = this.cdr;"
REM 0345 " this.cdr = this.stack.pop();"
REM 0346 " //if (this.stack.length === 0) delete this.stack;"
REM 0347 " return pv;"
REM 0348 }
REM 0349
REM 0350 function getSymbol(name, editMode) {
REM 0351 " if (name in gEmptyObj) throw new Error(newErrMsg(JS_RESERVED, name));"
REM 0352 " var s = gSym[name];"
REM 0353 " if (s === undefined) {"
REM 0354 " s = new Symbol(name, NIL);"
REM 0355 " if (! editMode) gSym[name] = s;"
REM 0356 " }"
REM 0357 " return s;"
REM 0358 }
REM 0359
REM 0360 function setSymbolValue(s, val) {
REM 0361 " if (!(s instanceof Symbol)) throw new Error(newErrMsg(VAR_EXP, s));"
REM 0362 " s.setVal(val);"
REM 0363 }
REM 0364
REM 0365 function Source(text, chars) {
REM 0366 " this.src = text;"
REM 0367 " // character limitation for symbols"
REM 0368 " if (chars instanceof Symbol) {"
REM 0369 " this.charset = chars.valueOf();"
REM 0370 " } else if (typeof chars == ""string"") {"
REM 0371 " //alert(""Source2: "" + chars);"
REM 0372 " this.charset = chars;"
REM 0373 " }"
REM 0374 " this.pos = 0;"
REM 0375 " this.trace = null;"
REM 0376 }
REM 0377
REM 0378 Source.prototype.CLOSEPAREN = -1;
REM 0379 Source.prototype.CLOSESYM = -2;
REM 0380 Source.prototype.QUOTE2 = -3;
REM 0381 Source.prototype.EOF = null;
REM 0382
REM 0383 Source.prototype.unescMap = {I: "\t", i: "\t", J: "\n", j: "\n", M: "\r", m: "\r"};
REM 0384
REM 0385 Source.prototype.getNextSignificantChar = function() {
REM 0386 " while (this.pos < this.src.length) {"
REM 0387 " while (this.src.charAt(this.pos) == ""#"") {"
REM 0388 " var ch;"
REM 0389 " do { ch = this.src.charAt(this.pos++); } while ((ch != ""\n"") && (this.pos < this.src.length));"
REM 0390 " }"
REM 0391 " if (this.src.charAt(this.pos) == ""\\"") this.pos++;"
REM 0392 " if ("" \t\r\n"".indexOf(this.src.charAt(this.pos)) == -1) return this.src.charAt(this.pos++);"
REM 0393 " this.pos++;"
REM 0394 " }"
REM 0395 " return this.EOF;"
REM 0396 }
REM 0397
REM 0398 Source.prototype.getNextStringChar = function() {
REM 0399 " while (this.pos < this.src.length) {"
REM 0400 " var ch = this.src.charAt(this.pos++);"
REM 0401 " if (ch == ""\"""") return this.QUOTE2;"
REM 0402 " if (ch == ""\\"") return this.src.charAt(this.pos++);"
REM 0403 " if (ch != ""^"") return ch;"
REM 0404 " ch = this.unescMap[this.src.charAt(this.pos++)];"
REM 0405 " if (ch != null) return ch;"
REM 0406 " }"
REM 0407 " return this.EOF;"
REM 0408 }
REM 0409
REM 0410 Source.prototype.getNextSymbolChar = function() {
REM 0411 " if ("" \t\r\n('\"""".indexOf(this.src.charAt(this.pos)) >= 0) return this.CLOSESYM;"
REM 0412 " var ch = this.src.charAt(this.pos++);"
REM 0413 " if (ch == "")"") return this.CLOSEPAREN;"
REM 0414 " if (ch == ""\\"") return this.src.charAt(this.pos++);"
REM 0415 " return ch;"
REM 0416 }
REM 0417
REM 0418 Source.prototype.withTrace = function() {
REM 0419 " this.trace = [];"
REM 0420 " return this;"
REM 0421 }
REM 0422
REM 0423 Source.prototype.traceItemEnd = function(item) {
REM 0424 " if (this.trace) this.trace.push({item: item, endPos: this.pos});"
REM 0425 }
REM 0426
REM 0427 Source.prototype.getItemBeforePos = function(endPos) {
REM 0428 " for (var i=this.trace.length-1; i>=0; i--) {"
REM 0429 " var t = this.trace[i];"
REM 0430 " if ((t.endPos - t.item.toString().length) <= endPos) return {item: t.item, tInd: i};"
REM 0431 " }"
REM 0432 " return null;"
REM 0433 }
REM 0434
REM 0435 Source.prototype.getSymbolBeforePos = function(endPos) {
REM 0436 " for (var i=this.trace.length-1; i>=0; i--) {"
REM 0437 " var t = this.trace[i];"
REM 0438 " if (((t.endPos - t.item.toString().length) <= endPos) &&"
REM 0439 " (t.item instanceof Symbol) && gSym[t.item.name]) return {item: t.item, tInd: i};"
REM 0440 " }"
REM 0441 " return null;"
REM 0442 }
REM 0443
REM 0444 "var NIL = new Symbol(""NIL""); NIL.car = NIL; NIL.cdr = NIL; NIL.props = NIL;"
REM 0445 " NIL.lock = true; NIL.TYPEVAL = NILTYPE; NIL.bool = false;"
REM 0446 "var T = new Symbol(""T""); T.cdr = T; T.lock = true; T.TYPEVAL = TRUETYPE; T.bool = true;"
REM 0447 var A1 = new Symbol("@", NIL), A2 = new Symbol("@@", NIL), A3 = new Symbol("@@@", NIL);
REM 0448 var ZERO = new Number(0), ONE = new Number(1);
REM 0449 "var gSym = {NIL: NIL, T: T, ""@"": A1, ""@@"": A2, ""@@@"": A3}; // dictionary/index for internal symbols"
REM 0450 "var gTrans = {}; // dictionary/index for transient symbols (strings)"
REM 0451 var gEmptyObj = {};
REM 0452 var gParseCache = {};
REM 0453 "var mk = []; // 'make' stack"
REM 0454 var evFrames = NIL;
REM 0455 var gTrcIndent = "";
REM 0456 var startupMillis = (new Date()).getTime();
REM 0457
REM 0458 function mkNew() { mk.unshift({h: NIL, t: NIL}); }
REM 0459 function linkc(c) {
REM 0460 " if (mk.length === 0) throw new Error(newErrMsg(NOT_MAK));"
REM 0461 " c = (c !== NIL) ? evalArgs(c) : new Cell(NIL, NIL);"
REM 0462 " if (mk[0].h === NIL) { mk[0].h = c; } else { mk[0].t.cdr = c; }"
REM 0463 " while (c.cdr !== NIL) { c = c.cdr; }; mk[0].t = c; return c.car;"
REM 0464 }
REM 0465 function link(x) {
REM 0466 " if (mk.length === 0) throw new Error(newErrMsg(NOT_MAK));"
REM 0467 " var c = new Cell(x, NIL);"
REM 0468 " if (mk[0].h === NIL) { mk[0].h = c; } else { mk[0].t.cdr = c; }"
REM 0469 " mk[0].t = c; return x;"
REM 0470 }
REM 0471 function mkResult() { return mk.shift().h; }
REM 0472
REM 0473 function getString(str, editMode) {
REM 0474 " var s = (str in gEmptyObj) ? undefined : gTrans[str];"
REM 0475 " if (s === undefined) {"
REM 0476 " s = newTransSymbol(str);"
REM 0477 " if (! (editMode || (str in gEmptyObj))) gTrans[str] = s;"
REM 0478 " }"
REM 0479 " return s;"
REM 0480 }
REM 0481
REM 0482 function newErrMsg(msg, badValue) {
REM 0483 " getSymbol(""*Msg"").setVal(newTransSymbol(msg));"
REM 0484 " return (badValue === undefined) ? msg : lispToStr(badValue) + "" -- "" + msg;"
REM 0485 }
REM 0486
REM 0487 function deFn(name, jsFn) {
REM 0488 " if (name in gEmptyObj) throw new Error(newErrMsg(JS_RESERVED, name));"
REM 0489 " var sym = new Symbol(name, jsFn);"
REM 0490 " gSym[name] = sym;"
REM 0491 }
REM 0492
REM 0493 function aTrue(val) { if (val !== NIL) { A1.pushValue(val); return true; } else return false; }
REM 0494
REM 0495 function aPop(val) { A1.popValue(); return val; }
REM 0496
REM 0497 function car(c) { if (c.car) return c.car; else throw new Error(newErrMsg(LIST_EXP)); }
REM 0498 function cdr(c) { if ((c instanceof Cell) || (c === NIL)) return c.cdr;
REM 0499 " else throw new Error(newErrMsg(LIST_EXP)); }"
REM 0500
REM 0501 function numeric(val) {
REM 0502 " if (val instanceof Number) return val;"
REM 0503 " throw new Error(newErrMsg(NUM_EXP, val));"
REM 0504 }
REM 0505
REM 0506 function nth(lst, n) {
REM 0507 " if (lst instanceof Cell) {"
REM 0508 " if (n <= 0) return NIL;"
REM 0509 " while ((lst !== NIL) && (--n > 0)) { lst = lst.cdr; }"
REM 0510 " }"
REM 0511 " return lst;"
REM 0512 }
REM 0513
REM 0514 function getAlg(c) {
REM 0515 " //alert(""getAlg: "" + lispToStr(c));"
REM 0516 " var s = c.car; c = c.cdr;"
REM 0517 " while (c instanceof Cell) {"
REM 0518 " var k = c.car;"
REM 0519 " if (s instanceof Symbol) {"
REM 0520 " if (eqVal(k, ZERO)) {"
REM 0521 " s = s.getVal();"
REM 0522 " } else {"
REM 0523 " var pLst = s.props, p = NIL, pk, pv;"
REM 0524 " while (pLst !== NIL) {"
REM 0525 " var pc = pLst.car;"
REM 0526 " if (pc instanceof Cell) { pk = pc.cdr; pv = pc.car; } else { pk = pc; pv = T; }"
REM 0527 //if (!confirm("getAlg: " + lispToStr(pc) + ", " + lispToStr(pk) + ", " + lispToStr(pv))) throw new Error("getAlg aborted");
REM 0528 " if (pk === k) { p = pv; break; }"
REM 0529 " pLst = pLst.cdr;"
REM 0530 " }"
REM 0531 " s = p; // the symbol or list to use in the next step"
REM 0532 " }"
REM 0533 " } else if (s instanceof Cell) {"
REM 0534 " if (k instanceof Number) {"
REM 0535 " if (k >= 0) {"
REM 0536 " s = nth(s, k).car;"
REM 0537 " } else {"
REM 0538 " do { s = s.cdr; } while ((s !== NIL) && (++k < 0));"
REM 0539 " }"
REM 0540 " }"
REM 0541 " } else throw new Error(newErrMsg(SYM_EXP));"
REM 0542 " c = c.cdr;"
REM 0543 " }"
REM 0544 " return s;"
REM 0545 }
REM 0546
REM 0547 function prog(c) {
REM 0548 " var v = NIL; while (c instanceof Cell) { v = evalLisp(c.car); c = c.cdr; }; return v;"
REM 0549 }
REM 0550
REM 0551 function iter(c) {
REM 0552 " var v = NIL;"
REM 0553 " while (c instanceof Cell) {"
REM 0554 " var cv = c.car, cond = false, cMatch = false;"
REM 0555 " if (cv instanceof Cell) {"
REM 0556 " if (cond = (cv.car === NIL)) {"
REM 0557 " cMatch = (evalLisp(cv.cdr.car) === NIL);"
REM 0558 " } else if (cond = (cv.car === T)) {"
REM 0559 " cMatch = aTrue(evalLisp(cv.cdr.car));"
REM 0560 " }"
REM 0561 " }"
REM 0562 " if (cond) {"
REM 0563 " if (cMatch) {"
REM 0564 " v = prog(cv.cdr.cdr);"
REM 0565 " if (cv.car === T) aPop(v);"
REM 0566 " return {v: v, m: true};"
REM 0567 " }"
REM 0568 " } else v = evalLisp(cv);"
REM 0569 " c = c.cdr;"
REM 0570 " }"
REM 0571 " return {v: v, m: false};"
REM 0572 }
REM 0573
REM 0574 function div(c, divFn) {
REM 0575 " var t = evalLisp(c.car);"
REM 0576 " if (t === NIL) return NIL;"
REM 0577 " t = numeric(t);"
REM 0578 " while (c.cdr !== NIL) {"
REM 0579 " c = c.cdr;"
REM 0580 " var v = evalLisp(c.car); if (v === NIL) return NIL;"
REM 0581 " if (numeric(v) == 0) throw new Error(newErrMsg(DIV_0));"
REM 0582 " t = divFn(t, v);"
REM 0583 " }"
REM 0584 " return new Number(t);"
REM 0585 }
REM 0586
REM 0587 function eqVal(a, b) {
REM 0588 " //alert(""eqVal() "" + a + "", "" + b);"
REM 0589 " if (a.TYPEVAL === b.TYPEVAL) {"
REM 0590 " if (a === b) return true;"
REM 0591 " if (a.TYPEVAL === CELLTYPE) {"
REM 0592 " return eqVal(a.car, b.car) ? eqVal(a.cdr, b.cdr) : false;"
REM 0593 " }"
REM 0594 " return (a.valueOf() == b.valueOf()); // Number or Symbol"
REM 0595 " }"
REM 0596 " return false;"
REM 0597 }
REM 0598
REM 0599 function ltVal(a, b) {
REM 0600 " if (a.TYPEVAL === b.TYPEVAL) {"
REM 0601 " if (a === b) return false;"
REM 0602 " if (a.TYPEVAL === CELLTYPE) {"
REM 0603 " return eqVal(a.car, b.car) ? ltVal(a.cdr, b.cdr) : ltVal(a.car, b.car);"
REM 0604 " }"
REM 0605 " return a.valueOf() < b.valueOf(); // Number or Symbol"
REM 0606 " }"
REM 0607 " return a.TYPEVAL < b.TYPEVAL;"
REM 0608 }
REM 0609
REM 0610 function idxLookup(owner, v) {
REM 0611 " var tree = owner.getVal();"
REM 0612 " if (tree === NIL) return NIL;"
REM 0613 " while (!eqVal(v, tree.car)) {"
REM 0614 " if (tree.cdr === NIL) return NIL;"
REM 0615 " if (ltVal(v, tree.car)) return idxLookup(tree.cdr, v);"
REM 0616 " tree = tree.cdr;"
REM 0617 " if (tree.cdr === NIL) return NIL;"
REM 0618 " tree = tree.cdr;"
REM 0619 " }"
REM 0620 " return tree;"
REM 0621 }
REM 0622
REM 0623 function idxInsert(owner, v) {
REM 0624 " var tree = owner.getVal();"
REM 0625 " if (tree === NIL) { owner.setVal(new Cell(v, NIL)); return NIL; }"
REM 0626 " while (!eqVal(v, tree.car)) {"
REM 0627 " if (tree.cdr === NIL) tree.cdr = new Cell(NIL, NIL);"
REM 0628 " if (ltVal(v, tree.car)) return idxInsert(tree.cdr, v);"
REM 0629 " tree = tree.cdr;"
REM 0630 " if (tree.cdr === NIL) { tree.cdr = new Cell(v, NIL); return NIL; }"
REM 0631 " tree = tree.cdr;"
REM 0632 " //if (!confirm(""idxInsert: "" + lispToStr(tree))) throw new Error(""idxInsert aborted"");"
REM 0633 " }"
REM 0634 " return tree;"
REM 0635 }
REM 0636
REM 0637 function idxDelete(owner, v) {
REM 0638 " var tree = owner.getVal(), pre = NIL;"
REM 0639 " if (tree === NIL) return NIL;"
REM 0640 " while (!eqVal(v, tree.car)) {"
REM 0641 " if (tree.cdr === NIL) return NIL;"
REM 0642 " if (ltVal(v, tree.car)) return idxDelete(tree.cdr, v);"
REM 0643 " pre = tree; tree = tree.cdr;"
REM 0644 " if (tree.cdr === NIL) return NIL;"
REM 0645 " pre = tree; tree = tree.cdr;"
REM 0646 " //if (!confirm(""idxDelete: "" + lispToStr(tree))) throw new Error(""idxDelete aborted"");"
REM 0647 " }"
REM 0648 " // tree.car is the value to delete"
REM 0649 " //var bbc = null; // cell with ""big brother"" to replace tree.car, if needed"
REM 0650 " if (tree.cdr.car !== NIL) {"
REM 0651 " // There are lesser values that need a new ""big brother""."
REM 0652 " if (tree.cdr.cdr !== NIL) {"
REM 0653 " var pbc = tree.cdr, bbc = pbc.cdr;"
REM 0654 " if (bbc.cdr.car !== NIL) {"
REM 0655 " // There are several ""big brother"" candidates, get the smallest ..."
REM 0656 " do { pbc = bbc; bbc = bbc.cdr.car; } while (bbc.cdr.car !== NIL);"
REM 0657 " pbc.cdr.car = NIL; // brother's old cell replaced by NIL"
REM 0658 " } else {"
REM 0659 " // Only one candidate. Cut it and following NIL from list ..."
REM 0660 " pbc.cdr = pbc.cdr.cdr.cdr;"
REM 0661 " }"
REM 0662 " //alert(""idxDelete: "" + lispToStr(bbc));"
REM 0663 " tree.car = bbc.car; // value to delete replaced by ""big brother"""
REM 0664 " } else {"
REM 0665 " // Must promote lesser values"
REM 0666 " if (pre === NIL) {"
REM 0667 " owner.setVal(tree.cdr.car);"
REM 0668 " } else {"
REM 0669 " pre.cdr = tree.cdr.car;"
REM 0670 " }"
REM 0671 " }"
REM 0672 " } else {"
REM 0673 " // No lesser values following value to delete"
REM 0674 " if (pre === NIL) {"
REM 0675 " owner.setVal(tree.cdr.cdr);"
REM 0676 " } else {"
REM 0677 " pre.cdr = tree.cdr.cdr;"
REM 0678 " }"
REM 0679 " }"
REM 0680 " return tree;"
REM 0681 }
REM 0682
REM 0683 function idxLinkSorted(tree) {
REM 0684 " while (tree !== NIL)"
REM 0685 " { idxLinkSorted(tree.cdr.car); link(tree.car); tree = tree.cdr.cdr; }"
REM 0686 }
REM 0687
REM 0688 /*
REM 0689 * If 'evaluate' is true, each top level expression will be evaluated, and the result
REM 0690 * of the last evaluation ('evRes') will be returned. A top level NIL or equivalent
REM 0691 * will terminate further parsing.
REM 0692 * If 'evaluate' is false/undefined, the source at the current level will be parsed,
REM 0693 * and a corresponding tree of cells will be returned (through the 'cdr' at the bottom).
REM 0694 * If 'editMode' is true, parsed symbols will not be inserted into the dictionaries.
REM 0695 */
REM 0696 function parseList(src, evaluate, editMode) {
REM 0697 " var ch, s, dotPos = 0, quotes = 0, items = [], cdr = NIL, evRes = NIL, circEnd = null;"
REM 0698 " do {"
REM 0699 " ch = src.getNextSignificantChar();"
REM 0700 " if (ch == ""'"") {"
REM 0701 " quotes++;"
REM 0702 " } else if (ch == "")"") {"
REM 0703 " break;"
REM 0704 " } else if ((ch == ""."") && (items.length > 0)) {"
REM 0705 " if (dotPos > 0) throw new Error(newErrMsg(BAD_DOT,"
REM 0706 " ""("" + lispToStr(items[items.length-1]) + "" . \\.)""));"
REM 0707 " dotPos = items.length;"
REM 0708 " } else if (ch !== src.EOF) {"
REM 0709 " var item;"
REM 0710 " if (ch == ""("") {"
REM 0711 " var tmp = parseList(src, false, editMode);"
REM 0712 " if (evaluate && (tmp !== NIL)) evRes = evalLisp(tmp);"
REM 0713 " item = tmp;"
REM 0714 " } else if (ch == ""\"""") {"
REM 0715 " s = """";"
REM 0716 " while (typeof (ch = src.getNextStringChar()) == ""string"") s += ch;"
REM 0717 " item = (s == """") ? NIL : getString(s, editMode);"
REM 0718 " src.traceItemEnd(item); // in case we would like to know item's position"
REM 0719 " } else {"
REM 0720 " s = ch;"
REM 0721 " while (typeof (ch = src.getNextSymbolChar()) == ""string"") s += ch;"
REM 0722 " item = isNaN(s) ? getSymbol(s, editMode) : new Number(s);"
REM 0723 " src.traceItemEnd(item); // in case we would like to know item's position"
REM 0724 " }"
REM 0725 " if (evaluate && (item === NIL)) return evRes;"
REM 0726 " if ((dotPos > 0) && (items.length > dotPos)) throw new Error(newErrMsg(BAD_DOT));"
REM 0727 " // TODO: provide a 'badValue' param for newErrMsg(BAD_DOT) above. Case: (1 (2 3) . 4 5)"
REM 0728 " while (quotes > 0) { item = new Cell(QUOTE, item); quotes--; }"
REM 0729 " items.push(item);"
REM 0730 " }"
REM 0731 " } while ((ch !== src.CLOSEPAREN) && (ch !== src.EOF));"
REM 0732 " if (evaluate) return evRes;"
REM 0733 " if (dotPos > 0) {"
REM 0734 " if (dotPos == items.length) {"
REM 0735 " cdr = new Cell(items.pop(), cdr);"
REM 0736 " circEnd = cdr; // last cell in circular (x y z .) notation"
REM 0737 " } else { cdr = items.pop(); } // normal dot notation"
REM 0738 " }"
REM 0739 " while (items.length > 0) cdr = new Cell(items.pop(), cdr);"
REM 0740 " if (circEnd != null) circEnd.cdr = cdr;"
REM 0741 " return cdr;"
REM 0742 }
REM 0743
REM 0744 function cachedTextParse(str) {
REM 0745 " var lst = gParseCache[str];"
REM 0746 " if (lst === undefined) {"
REM 0747 " lst = parseList(new Source(str));"
REM 0748 " gParseCache[str] = lst;"
REM 0749 " }"
REM 0750 " return lst;"
REM 0751 }
REM 0752
REM 0753 function unevalArgs(lst) {
REM 0754 " // Putting elements of lst into anonymous symbols"
REM 0755 " mkNew(); while (lst !== NIL) { link(box(lst.car)); lst = lst.cdr; }"
REM 0756 " return mkResult();"
REM 0757 }
REM 0758
REM 0759 function applyFn(rawFn, lst, more) {
REM 0760 " if (more !== NIL) {"
REM 0761 " mkNew(); do { link(evalLisp(more.car)); more = more.cdr; } while (more !== NIL);"
REM 0762 " mk[0].t.cdr = lst; lst = mkResult();"
REM 0763 " }"
REM 0764 " var fn = evalLisp(rawFn); if (! (fn instanceof Symbol)) fn = box(fn);"
REM 0765 " return evalLisp(new Cell(fn, unevalArgs(lst)));"
REM 0766 }
REM 0767
REM 0768 deFn("apply", function(c) { return applyFn(c.car, evalLisp(c.cdr.car), c.cdr.cdr); });
REM 0769 deFn("arg", function(c) { var n = 0, f = evFrames.car;
REM 0770 " if (c !== NIL) {"
REM 0771 " n = Math.round(numeric(evalLisp(c.car))); if (n < 1) return NIL;"
REM 0772 " }"
REM 0773 " while (n-- > 0) f = f.cdr;"
REM 0774 " return f.car;"
REM 0775 });
REM 0776 deFn("args", function(c) { return (evFrames.car.cdr === NIL) ? NIL : T; });
REM 0777 deFn("bench", function(c) { var t0 = (new Date()).getTime(), r = prog(c);
REM 0778 " _stdPrint(((new Date()).getTime() - t0) / 1000 + "" sec\n""); return r;"
REM 0779 });
REM 0780 deFn("box", function(c) { return box(evalLisp(c.car)); });
REM 0781 deFn("caar", function(c) { return car(car(evalLisp(c.car))); });
REM 0782 deFn("caddr", function(c) { return car(cdr(cdr(evalLisp(c.car)))); });
REM 0783 deFn("cadr", function(c) { return car(cdr(evalLisp(c.car))); });
REM 0784 deFn("car", function(c) { return car(evalLisp(c.car)); });
REM 0785 deFn("cdar", function(c) { return cdr(car(evalLisp(c.car))); });
REM 0786 deFn("cddr", function(c) { return cdr(cdr(evalLisp(c.car))); });
REM 0787 deFn("cdr", function(c) { return cdr(evalLisp(c.car)); });
REM 0788 deFn("chop", function(c) { var cv = evalLisp(c.car);
REM 0789 " if ((cv === NIL) || (cv instanceof Cell)) return cv;"
REM 0790 " var s = (cv instanceof Symbol) ? cv.valueOf() : cv.toString();"
REM 0791 " if (s === null) return NIL;"
REM 0792 " var arr = s.split(""""), v = NIL;"
REM 0793 " while (arr.length > 0) v = new Cell(newTransSymbol(arr.pop()), v);"
REM 0794 " return v;"
REM 0795 });
REM 0796 deFn("cond", function(c) {
REM 0797 " while (c.car instanceof Cell) {"
REM 0798 " if (aTrue(evalLisp(c.car.car))) return aPop(prog(c.car.cdr));"
REM 0799 " c = c.cdr;"
REM 0800 " }"
REM 0801 " return NIL;"
REM 0802 });
REM 0803 deFn("cons", function(c) { var r = new Cell(evalLisp(c.car), evalLisp(c.cdr.car)), t = r;
REM 0804 " c = c.cdr.cdr;"
REM 0805 " while (c !== NIL) { var d = new Cell(t.cdr, evalLisp(c.car)); t.cdr = d; t = d; c = c.cdr; }"
REM 0806 " return r;"
REM 0807 });
REM 0808 deFn("de", function(c) { var old = c.car.getVal();
REM 0809 " setSymbolValue(c.car, c.cdr);"
REM 0810 " if ((old !== NIL) && !eqVal(c.cdr, old)) _warn(""# "" + c.car.valueOf() + "" redefined"");"
REM 0811 " return c.car;"
REM 0812 });
REM 0813 deFn("dec", function(c) {
REM 0814 " if (c === NIL) return NIL;"
REM 0815 " var ns = evalLisp(c.car);"
REM 0816 " if (ns instanceof Number) return new Number(ns - 1);"
REM 0817 " var v = new Number(ns.getVal() - ((c.cdr !== NIL) ? numeric(evalLisp(c.cdr.car)) : 1));"
REM 0818 " ns.setVal(v); return v;"
REM 0819 });
REM 0820 deFn("delete", function(c) { var a = evalLisp(c.car), lst = evalLisp(c.cdr.car);
REM 0821 " if (!(lst instanceof Cell)) return lst;"
REM 0822 " if (eqVal(a, lst.car)) return lst.cdr;"
REM 0823 " mkNew(); link(lst.car); lst = lst.cdr;"
REM 0824 " while (lst instanceof Cell) {"
REM 0825 " if (eqVal(a, lst.car)) { mk[0].t.cdr = lst.cdr; return mkResult(); }"
REM 0826 " link(lst.car); lst = lst.cdr;"
REM 0827 " }"
REM 0828 " mk[0].t.cdr = lst; // taking care of dotted tail"
REM 0829 " return mkResult();"
REM 0830 });
REM 0831 deFn("do", function(c) {
REM 0832 " var n = evalLisp(c.car);"
REM 0833 " if (n === NIL) return NIL;"
REM 0834 " var step = 1, b = c.cdr, v = NIL;"
REM 0835 " if (n === T) { n = 1; step = 0; }"
REM 0836 " for (var i=1; i<=n; i+=step) {"
REM 0837 " var r = iter(b); v = r.v; if (r.m) break;"
REM 0838 " }"
REM 0839 " return v;"
REM 0840 });
REM 0841 "deFn(""eval"", function(c) { return evalLisp(evalLisp(c.car)); }); // TODO: binding env. offset cnt"
REM 0842 deFn("fin", function(c) { c = evalLisp(c.car); while (c instanceof Cell) { c = c.cdr; }; return c; });
REM 0843 deFn("for", function(c) {
REM 0844 " var s = null, s2 = null, v = NIL;"
REM 0845 " if (c.car instanceof Symbol) {"
REM 0846 " s = c.car;"
REM 0847 " } else if (c.car.cdr instanceof Symbol) {"
REM 0848 " s2 = c.car.car; s = c.car.cdr;"
REM 0849 " }"
REM 0850 " if (s != null) {"
REM 0851 " s.pushValue(NIL); if (s2 != null) s2.pushValue(ZERO);"
REM 0852 " var nl = evalLisp(c.cdr.car), b = c.cdr.cdr, i = 0;"
REM 0853 " if (nl instanceof Number) {"
REM 0854 " //alert(""for: 1st form""); // (for I 3 (js:confirm I))"
REM 0855 " while (++i <= nl) {"
REM 0856 " s.setVal(new Number(i));"
REM 0857 " var r = iter(b); v = r.v; if (r.m) break;"
REM 0858 " }"
REM 0859 " } else {"
REM 0860 " //alert(""for: 2nd form""); // (for (I . X) (22 33 44) (js:confirm (+ I X)) (+ I X))"
REM 0861 " while (nl instanceof Cell) {"
REM 0862 " s.setVal(nl.car); if (s2 != null) s2.setVal(new Number(++i));"
REM 0863 " var r = iter(b); v = r.v; if (r.m) break;"
REM 0864 " nl = nl.cdr;"
REM 0865 " }"
REM 0866 " }"
REM 0867 " } else {"
REM 0868 " //alert(""for: 3rd form"");"
REM 0869 " if (c.car.car instanceof Symbol) {"
REM 0870 " s = c.car.car;"
REM 0871 " } else {"
REM 0872 " s2 = c.car.car.car; s = c.car.car.cdr;"
REM 0873 " }"
REM 0874 " s.pushValue(evalLisp(c.car.cdr.car)); if (s2 != null) s2.pushValue(ZERO);"
REM 0875 " var a2p = c.car.cdr.cdr, a2 = a2p.car, b = c.cdr, i = 0;"
REM 0876 " var p = (a2p.cdr instanceof Cell) ? a2p.cdr.car : null;"
REM 0877 " while (evalLisp(a2) !== NIL) {"
REM 0878 " if (s2 != null) s2.setVal(new Number(++i));"
REM 0879 " var r = iter(b); v = r.v; if (r.m) break;"
REM 0880 " if (p != null) s.setVal(evalLisp(p));"
REM 0881 " }"
REM 0882 " }"
REM 0883 " s.popValue(); if (s2 != null) s2.popValue();"
REM 0884 " return v;"
REM 0885 });
REM 0886 deFn("get", function(c) { return getAlg(evalArgs(c)); });
REM 0887 deFn("getl", function(c) { var s = getAlg(evalArgs(c));
REM 0888 " if (s instanceof Symbol) return s.props;"
REM 0889 " throw new Error(newErrMsg(SYM_EXP, s));"
REM 0890 });
REM 0891 deFn("idx", function(c) { var s = evalLisp(c.car);
REM 0892 " if (!(s instanceof Symbol)) return NIL;"
REM 0893 " if (c.cdr === NIL) { mkNew(); idxLinkSorted(s.getVal()); return mkResult(); }"
REM 0894 " var a = evalLisp(c.cdr.car);"
REM 0895 " if (c.cdr.cdr === NIL) return idxLookup(s, a);"
REM 0896 " return (evalLisp(c.cdr.cdr.car) === NIL) ? idxDelete(s, a) : idxInsert(s, a);"
REM 0897 });
REM 0898 deFn("if", function(c) { return aTrue(evalLisp(c.car)) ? aPop(evalLisp(c.cdr.car)) : prog(c.cdr.cdr); });
REM 0899 deFn("ifn", function(c) { return aTrue(evalLisp(c.car)) ? aPop(prog(c.cdr.cdr)) : evalLisp(c.cdr.car); });
REM 0900 deFn("inc", function(c) {
REM 0901 " if (c === NIL) return NIL;"
REM 0902 " var ns = evalLisp(c.car);"
REM 0903 " if (ns instanceof Number) return new Number(ns + 1);"
REM 0904 " var v = new Number(ns.getVal() + ((c.cdr !== NIL) ? numeric(evalLisp(c.cdr.car)) : 1));"
REM 0905 " ns.setVal(v); return v;"
REM 0906 });
REM 0907 deFn("length", function(c) { var cv = evalLisp(c.car), v = 0;
REM 0908 " if (cv instanceof Number) { v = cv.toString().length; }"
REM 0909 " else if (cv instanceof Symbol) { v = cv.lock ? cv.toValueString().length :"
REM 0910 " (cv.name === null) ? 0 : cv.name.length; }"
REM 0911 " else if (cv instanceof Cell) { var cs = cv;"
REM 0912 " while (cs !== NIL) { v++; cs = cs.cdr; if (cs === cv) return T; }}"
REM 0913 " return new Number(v);"
REM 0914 });
REM 0915 deFn("let", function(c) {
REM 0916 " var symArr = [], p = c.cdr;"
REM 0917 " if (c.car instanceof Symbol) {"
REM 0918 " if (c.car !== NIL) {"
REM 0919 " c.car.pushValue(evalLisp(c.cdr.car)); symArr.push(c.car); p = c.cdr.cdr;"
REM 0920 " }"
REM 0921 " } else if (c.car instanceof Cell) {"
REM 0922 " var sv = c.car;"
REM 0923 " while (sv !== NIL) {"
REM 0924 " sv.car.pushValue(evalLisp(sv.cdr.car)); symArr.push(sv.car); sv = sv.cdr.cdr;"
REM 0925 " }"
REM 0926 " }"
REM 0927 " var v = prog(p);"
REM 0928 " while (symArr.length > 0) { symArr.pop().popValue(); }"
REM 0929 " return v;"
REM 0930 });
REM 0931 deFn("link", linkc);
REM 0932 deFn("list", function(c) { return (c !== NIL) ? evalArgs(c) : new Cell(NIL, NIL); });
REM 0933 deFn("load", function(c) { var r = NIL;
REM 0934 " while (c instanceof Cell) {"
REM 0935 " var cv = evalLisp(c.car);"
REM 0936 " if (cv instanceof Symbol) {"
REM 0937 " var f = cv.toValueString();"
REM 0938 " if (f.charAt(0) == ""-"") {"
REM 0939 " r = parseList(new Source(""("" + f.substring(1) + "")""), true);"
REM 0940 " } else {"
REM 0941 " r = (f.match(/\.js$/)) ? loadJavaScript(f) : loadLisp(f);"
REM 0942 " }"
REM 0943 " }"
REM 0944 " c = c.cdr;"
REM 0945 " }"
REM 0946 " return r;"
REM 0947 });
REM 0948 deFn("loop", function(c) {
REM 0949 " var v = NIL; while (true) { var r = iter(c); v = r.v; if (r.m) break; }; return v;"
REM 0950 });
REM 0951 deFn("make", function(c) { mkNew(); prog(c); return mkResult(); });
REM 0952 deFn("mapc", function(c) { var r = NIL, fn = evalLisp(c.car), ci = evalArgs(c.cdr);
REM 0953 " if (! (fn instanceof Symbol)) fn = box(fn);"
REM 0954 " while (ci.car !== NIL) { var cj = ci; mkNew();"
REM 0955 " while (cj !== NIL) { link(cj.car.car); cj.car = cj.car.cdr; cj = cj.cdr; }"
REM 0956 " r = evalLisp(new Cell(fn, unevalArgs(mkResult())));"
REM 0957 " }"
REM 0958 " return r;"
REM 0959 });
REM 0960 deFn("mapcar", function(c) { var fn = evalLisp(c.car), ci = evalArgs(c.cdr);
REM 0961 " if (! (fn instanceof Symbol)) fn = box(fn);"
REM 0962 " mkNew();"
REM 0963 " while (ci.car !== NIL) { var cj = ci; mkNew();"
REM 0964 " //if (!confirm(lispToStr(cj))) throw new Error(""mapcar aborted"");"
REM 0965 " while (cj !== NIL) { link(cj.car.car); cj.car = cj.car.cdr; cj = cj.cdr; }"
REM 0966 " link(evalLisp(new Cell(fn, unevalArgs(mkResult()))));"
REM 0967 " }"
REM 0968 " return mkResult();"
REM 0969 });
REM 0970 deFn("next", function(c) { evFrames.car = evFrames.car.cdr; return evFrames.car.car; });
REM 0971 deFn("not", function(c) { return (evalLisp(c.car) === NIL) ? T : NIL; });
REM 0972 deFn("nth", function(c) { var lst = evalArgs(c); c = lst.cdr;
REM 0973 " do { lst = nth(lst.car, numeric(c.car)); c = c.cdr; } while(c !== NIL); return lst; });"
REM 0974 // pack has no support for circular lists, same as in PicoLisp
REM 0975 deFn("pack", function(c) { return (c !== NIL) ? newTransSymbol(valueToStr(evalArgs(c))) : NIL; });
REM 0976 deFn("pass", function(c) { return applyFn(c.car, evFrames.car.cdr, c.cdr); });
REM 0977 deFn("pop", function(c) { var cv = evalLisp(c.car);
REM 0978 " if (cv.getVal) {"
REM 0979 " var v = cv.getVal();"
REM 0980 " if (v instanceof Cell) { cv.setVal(v.cdr); return v.car; }"
REM 0981 " if (v === NIL) return NIL;"
REM 0982 " if (cv instanceof Cell) return cv.car;"
REM 0983 " }"
REM 0984 " throw new Error(newErrMsg(VAR_EXP, cv));"
REM 0985 });
REM 0986 deFn("prin", function(c) {
REM 0987 " c = evalArgs(c); _stdPrint(c.toValueString());"
REM 0988 " while (c.cdr !== NIL) { c = c.cdr; }; return c.car;"
REM 0989 });
REM 0990 deFn("prinl", function(c) {
REM 0991 " c = evalArgs(c); _stdPrint(c.toValueString() + ""\n"");"
REM 0992 " while (c.cdr !== NIL) { c = c.cdr; }; return c.car;"
REM 0993 });
REM 0994
REM 0995 function printx(c, x) { var arr = [];
REM 0996 " c = evalArgs(c); arr.push(lispToStr(c.car));"
REM 0997 " while (c.cdr !== NIL) { c = c.cdr; arr.push(lispToStr(c.car)); }"
REM 0998 " _stdPrint(arr.join("" "") + x); return c.car;"
REM 0999 }
REM 1000