-
Notifications
You must be signed in to change notification settings - Fork 5
/
0.txt
4729 lines (4484 loc) · 146 KB
/
0.txt
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
;mode800,value4000
;;;;;;;;;;
;;; Variables and Stack:
;;; There are some variables and the single stack.
;;; The values in them are protected from GC.
;;; Variables tmp, tmp1, tmp2, ... have a temporary value.
;;; Variables arg0, arg1, ... are used for argument passing.
;;; Primary subroutines set_gc, get_gc, set_tag, get_tag, set_data, and
;;; get_data keep the value of argN, but they may change the value of tmpN.
;;;
;;; Lisp objects:
;;; [MSB] [LSB]
;;; 0DDDDDDDDDDDDDDDDDDDDDDDDDTTTTTG
;;; D: Data (25 bits)
;;; T: Tag (5 bits)
;;; G: GC Mark (1 bit)
;;; (MSB must be 0 because we use arithmetic ops instead of binary ops.)
;;; CAR of cons cells occupies the low 13 bits of Data part.
;;; CDR of cons cells occupies the remaining bits of Data part.
;;; Symbols are also partitioned into CAR and CDR.
;;; CAR part of symbols points to the string which is the symbol name.
;;; All symbols are chained by their CDR part.
;;; EXPR is represented with lists such as (env arg . body).
;;; Errors are represented with lists such as (message . location).
;;;
;;; ATTENTION:
;;; Do not allocate new cons cell in for-loop.
;;;
;;; Memo:
;;; ";value" must be written at the first line.
;;; "Global variables" in NScripter are 0 if we do not call "globalon".
;;; We should call "mem_init" after load (?)
;;;;;;;;;;
*define
nsa
textgosub *text_cw
; Effect
numalias E_FAST, 10
numalias E_NORMAL, 11
numalias E_SLOW, 12
numalias E_RWIPE_SLOW, 13
numalias E_VFAST, 14
numalias E_RAIN, 15
numalias E_BUBBLE, 16
numalias E_WIPE2, 17
numalias E_LWIPE_FAST, 18
numalias E_CURCLE, 19
effect E_VFAST, 10, 100
effect E_FAST, 10, 200
effect E_NORMAL, 10, 500
effect E_SLOW, 10, 1000
effect E_RWIPE_SLOW, 15, 1000, "img/wipe_r.bmp"
effect E_LWIPE_FAST, 15, 200, "img/wipe_l.bmp"
effect E_RAIN, 15, 200, "img/25e.bmp"
effect E_BUBBLE, 15, 200, "img/17e.bmp"
effect E_WIPE2, 15, 600, "img/wipe2.bmp"
effect E_CURCLE, 15, 2000, "img/curcle.bmp"
; Sprites
numalias SP_FILL, 0
numalias SP_CLICK, 1
numalias SP_CLICK_MINI, 2
; Temporary
numalias SP_TMP, 10
numalias SP_TMP1, 11
numalias SP_TMP2, 12
numalias SP_TMP3, 13
; Opening
numalias SP_LOGO0, 20
numalias SP_LOGO1, 21
numalias SP_LOGO_LAMBDA, 23
numalias SP_LOGO_KUMI, 24
numalias SP_LOGO_SAKURA, 25
numalias SP_LOGO_KARASU, 26
numalias SP_TITLE_SEN, 30
numalias SP_TITLE, 31
numalias SP_TITLE_HOSHI, 32
; Ending
numalias SP_SAME_HEAD, 40
numalias SP_SAME_BODY, 41
numalias SP_SAME_FOOT, 42
numalias SP_INU01, 43
numalias SP_INU02, 44
numalias SP_INU01_R, 45
numalias SP_INU02_R, 46
numalias SP_FLOWER, 47
numalias SP_S, 48
numalias SP_ST, 49
numalias SP_EFRAME, 50
; Baseball
numalias SP_BALL, 100
numalias SP_REIN01, 101
numalias SP_REIN02, 102
numalias SP_REIN03, 103
numalias SP_VITA01, 111
numalias SP_VITA02, 112
numalias SP_ARROW, 119
;Right click
numalias SP_RC_BACK, 210
numalias SP_RC_1, 201
numalias SP_RC_2, 202
numalias SP_RC_3, 203
numalias SP_RC_4, 204
numalias SP_RC_5, 205
; Noroi-sama
numalias SP_NOROI_HALF, 800
numalias SP_NOROI, 801
numalias SP_NOROI_D1, 802
numalias SP_NOROI_D2, 803
numalias SP_NOROI_HD2, 804
numalias SP_NOROI_HD1, 805
; Character
numalias SP_CRC, 809
numalias SP_L, 810
numalias SP_R, 811
numalias SP_C, 812
; Stuffed rabbit
numalias SP_USAGI, 816
numalias SP_USAGI_R, 817
; Figure
numalias SP_DGM0, 850
numalias SP_DGM1, 851
numalias SP_DGM2, 852
numalias SP_DGM3, 853
; Other settings for pictures
numalias SP_BACKGROUND, 900
numalias SP_DUMMY, 999
humanz 800 ; Sprites whose numbers <= 800 are drawn on front.
windowback ; Window is the same as above.
usewheel
; Constants
;; Heap is used for any lisp objects (100 <= heap < 3000)
numalias HEAP, 100
numalias HEAP_LAST, 2999
numalias HEAP_LIMIT, 3000
;; Stack is used for any lisp objects and integers (3000 <= stack < 4000)
numalias STACK, 3000
numalias STACK_SAFE_LIMIT, 3990
numalias STACK_LIMIT, 4000
;; Symbol-set is used for symbol strings (100 <= from < 500 <= to < 900)
numalias SYMBOL_SET, 100
numalias SYMBOL_SET_HALF_SIZE, 400
;; SStack is used for any string (900 <= sstack < 1000)
numalias SSTACK, 900
numalias SSTACK_LIMIT, 1000
numalias TAG_CONS, 0
numalias TAG_SYMBOL, 1
numalias TAG_NUM, 2
numalias TAG_SUBR, 3
numalias TAG_EXPR, 4
numalias TAG_FREE, 5
numalias TAG_ERROR, 6
numalias TAG_VAR, 7
numalias TAG_GVAR, 8
numalias TAG_BOOL, 9
numalias MAX_NUMBER, 16777215 ; 2^24 - 1
numalias MIN_NUMBER, -16777216 ; - 2^24
numalias UNSIGNED_MAX_PLUS1, 33554432 ; 2^25
numalias MIN_INT32, -2147483648 ; - 2^31
numalias NON_VALUE, -1 ; Every lisp object is different from this value.
numalias DEFAULT_EVAL_LIMIT, 20000
numalias UNBOUND, 4095
;;;
;;; Next variable number: 95
;;;
; Aliases for numerical variables
;; General variables
numalias tmp, 50
numalias ret, 51
numalias arg0, 52
numalias arg1, 53
numalias arg2, 54
numalias arg3, 55
numalias tmp1, 56
numalias tmp2, 57
numalias tmp3, 58
;; Special variables
numalias sp, 59
numalias free_lst, 60
numalias i, 61
numalias gc_tmp ,62
numalias eval_count, 63
numalias symbol_used, 64
numalias ssp, 65
;; Lisp object
numalias nil, 66
numalias quote, 67
numalias global_env, 68
numalias sharp_t, 69
numalias sharp_f, 70
numalias toplevel_env, 71
;; Garbage collection
numalias gc_count, 72
numalias symbol_lst, 73
numalias symbol_offset, 74
numalias gc_run, 75
numalias eval_limit, 76
numalias gc_silent, 77
numalias gc_mark_color, 94
;; Debug
;; NOTE: current_proc and current_env are not protected from GC so far.
;; We should protect them if GC moves objects.
numalias current_proc, 78
numalias current_env, 79
numalias in_ex_test, 80
;; Syntax keyword symbol
numalias sym_begin, 81
numalias sym_cond, 82
numalias sym_lambda, 83
numalias sym_define, 84
numalias sym_let, 85
numalias sym_if, 86
numalias sym_and, 87
numalias sym_or, 88
numalias sym_set, 89
numalias sym_letrec, 90
numalias sym_letstar, 91
numalias sym_time, 92
numalias sym_else, 93
;; Error messages
stralias str_too_few_arguments, "Too-few-arguments"
stralias str_too_many_arguments, "Too-many-arguments"
stralias str_invalid_syntax, "Invalid-syntax"
stralias str_stack_overflow, "Stack-overflow"
; Variables for the game
numalias save_flag, 0
numalias adv_tmp, 1
numalias adv_tmp1, 2
numalias adv_tmp2, 3
numalias adv_tmp3, 4
numalias adv_clear, 5
numalias adv_additional, 6
numalias adv_bgm, 7
numalias adv_char, 8
numalias adv_noroi, 9
numalias adv_noroi_frame, 10
numalias adv_noroi_my, 11
numalias adv_noroi_mx, 12
numalias adv_talkmode, 13
numalias adv_noroi_kill, 14
numalias adv_noroi_off, 15
numalias adv_miss, 16
numalias adv_same_level, 17
numalias adv_hp, 18
numalias adv_ehp, 19
numalias adv_maxhp, 20
numalias adv_sx, 21
numalias adv_sy, 22
numalias adv_sr, 23
numalias adv_ix, 24
numalias adv_id, 25
numalias adv_ball_x, 26
numalias adv_ball_y, 27
numalias adv_ball_vx, 28
numalias adv_vol, 29
numalias adv_rmode, 30
numalias adv_num_loss, 31
numalias adv_error, 32
; Aliases for string variables
numalias sarg0, 10
numalias sarg1, 11
numalias sarg2, 12
numalias sarg3, 13
numalias stmp, 14
numalias stmp1, 15
numalias stmp2, 16
numalias stmp3, 17
numalias sret, 18
numalias sTAB, 20
numalias sCR, 21
numalias sLF, 22
numalias problem_label, 23
numalias tab_label, 24
numalias ret_label, 25
numalias suc_label, 26
numalias sadv_label, 50
numalias sadv_vol, 51
; Paths for image files
stralias ari_n, ":l;img/arisa-01.bmp"
stralias ari_tun, ":l;img/arisa-02.bmp"
stralias ari_qes, ":l;img/arisa-03.bmp"
stralias ari_exc, ":l;img/arisa-04.bmp"
stralias ari_hrt, ":l;img/arisa-05.bmp"
stralias ari_dere, ":l;img/arisa-06.bmp"
stralias ari_die, ":l;img/arisa-07.bmp"
stralias ari_ase, ":l;img/arisa-08.bmp"
stralias ari_muka, ":l;img/arisa-09.bmp"
stralias ari_do, ":l;img/arisa-0404.bmp"
stralias suzu_n, ":l;img/suzuka-01.bmp"
stralias suzu_nc, ":l;img/suzuka-02.bmp"
stralias suzu_qes, ":l;img/suzuka-03.bmp"
stralias suzu_exc, ":l;img/suzuka-04.bmp"
stralias suzu_excc, ":l;img/suzuka-05.bmp"
stralias suzu_hrt, ":l;img/suzuka-06.bmp"
stralias suzu_dere, ":l;img/suzuka-07.bmp"
stralias suzu_ase, ":l;img/suzuka-08.bmp"
stralias suzu_T_T, ":l;img/suzuka-09.bmp"
stralias suzu_dotc, ":l;img/suzuka-10.bmp"
stralias suzu_dot, ":l;img/suzuka-11.bmp"
stralias suzur_n, ":l;img/suzuka-01r.bmp"
stralias suzur_nc, ":l;img/suzuka-02r.bmp"
stralias suzur_qes, ":l;img/suzuka-03r.bmp"
stralias suzur_exc, ":l;img/suzuka-04r.bmp"
stralias suzur_excc, ":l;img/suzuka-05r.bmp"
stralias suzur_hrt, ":l;img/suzuka-06r.bmp"
stralias suzur_dere, ":l;img/suzuka-07r.bmp"
stralias suzur_ase, ":l;img/suzuka-08r.bmp"
stralias suzur_T_T, ":l;img/suzuka-09r.bmp"
stralias suzur_dotc, ":l;img/suzuka-10r.bmp"
stralias suzur_dot, ":l;img/suzuka-11r.bmp"
; Paths for sound files
stralias ms_ex, "bgm/ex.mp3"
stralias ms_narumi, "bgm/narumi.mp3"
stralias ms_kyoto, "bgm/kyoto.mp3"
stralias ms_setsume, "bgm/setsume.mp3"
stralias ms_after, "bgm/after.mp3"
stralias ms_jiku, "bgm/jiku.mp3"
stralias ms_battle, "bgm/battle.mp3"
stralias ms_battle2, "bgm/battle2.mp3"
stralias ms_battlen, "bgm/battlen.mp3"
stralias ms_nano, "bgm/nano.mp3"
stralias ms_epilogue1, "bgm/epilogue1.mp3"
stralias ms_epilogue2, "bgm/epilogue2.mp3"
stralias ms_ending, "bgm/ending.mp3"
stralias ms_ab2, "bgm/ab2.mp3"
stralias ms_yakyu, "bgm/yakyu.mp3"
stralias ms_omake, "bgm/omake.mp3"
stralias ms_title, "bgm/title.mp3"
; SUBR
numalias lf_car, 0
numalias lf_cdr, 1
numalias lf_cons, 2
numalias lf_eq, 3
numalias lf_atom, 4
numalias lf_add, 5
numalias lf_sub, 6
numalias lf_mul, 7
numalias lf_div, 8
numalias lf_mod, 9
numalias lf_gt, 10
numalias lf_ge, 11
numalias lf_ls, 12
numalias lf_le, 13
numalias lf_set_car, 14
numalias lf_set_cdr, 15
numalias lf_eval, 16
numalias lf_apply, 17
numalias lf_booleanp, 18
numalias lf_pairp, 19
numalias lf_symbolp, 20
numalias lf_numberp, 21
numalias lf_procedurep, 22
numalias lf_null, 23
numalias lf_read, 24
numalias lf_write, 25
numalias lf_error, 26
defaultspeed 50,15,5
caption "Magical Language Lyrical Lisp"
versionstr "Magical Language Lyrical Lisp", "Open Source"
resetmenu
insertmenu "終了", END
insertmenu "バージョン情報", VERSION
insertmenu "選択肢まで進む", SKIP
insertmenu "文字速度", SUB
insertmenu "低速", TEXTSLOW, 1
insertmenu "普通", TEXTMIDDLE, 1
insertmenu "高速", TEXTFAST, 1
insertmenu "フォント", FONT
insertmenu "画面", SUB
insertmenu "フルスクリーン", FULL, 1
insertmenu "ウインドウ", WINDOW, 1
; Define subroutines for the game
defsub r_in
defsub r_out
defsub l_in
defsub l_out
defsub l_rout
defsub r_show
defsub l_show
defsub c_show
defsub r_load
defsub l_load
defsub c_load
defsub talk_mode
defsub speak_mode
defsub show_dgm
defsub load_dgm
defsub wait_dgm
game
;;;;;;;;;;
;;;*push(val)
;;; modifies: %sp
;;;;;;;;;;
*push
if %sp >= STACK_LIMIT mesbox "スタックオーバフロー", "Error" : end
mov %%sp, %arg0
inc %sp
return
;;;;;;;;;;
;;;*pop()
;;; modifies: %ret, %sp
;;;;;;;;;;
*pop
if %sp <= STACK mesbox "Popできません", "Error" : end
dec %sp
mov %ret, %%sp
return
;;;;;;;;;;
;;;*spush(val)
;;; modifies: %ssp
;;;;;;;;;;
*spush
if %ssp >= STACK_LIMIT mesbox "スタックオーバフロー", "Error" : end
mov $%ssp, $sarg0
inc %ssp
return
;;;;;;;;;;
;;;*spop()
;;; modifies: $sret, %ssp
;;;;;;;;;;
*spop
if %ssp <= SSTACK mesbox "Popできません" "Error" : end
dec %ssp
mov $sret, $%ssp
return
;;;;;;;;;;
;;;*get_gc(obj)
;;; modifies: %ret
;;;;;;;;;;
*get_gc
mov %ret, %%arg0 mod 2
return
;;;;;;;;;;
;;;*set_gc(obj, flag)
;;; modifies: %tmp
;;;;;;;;;;
*set_gc
mov %tmp, %%arg0
div %tmp, 2
mul %tmp, 2
mov %%arg0, %tmp + %arg1
return
;;;;;;;;;;
;;;*get_tag(obj)
;;; modifies: %tmp, %ret
;;;;;;;;;;
*get_tag
mov %tmp, %%arg0
mod %tmp, 64
mov %ret, %tmp
div %ret, 2
return
;;;;;;;;;;
;;;*set_tag(obj, tag)
;;; modifies: %tmp, %tmp1, %tmp2, %tmp3
;;;;;;;;;;
*set_tag
mov %tmp, %%arg0
mov %tmp1, %tmp
div %tmp1, 64
mul %tmp1, 64 ; DATA
mov %tmp2, %tmp mod 2 ; GC
mov %tmp3, %arg1 * 2 ; TAG
mov %%arg0, %tmp1 + %tmp2 + %tmp3
return
;;;;;;;;;;
;;;*get_data(obj)
;;; modifies: %ret
;;;;;;;;;;
*get_data
mov %ret, %%arg0
div %ret, 64
return
;;;;;;;;;;
;;;*get_num_data(num)
;;; modifies: %ret
;;;;;;;;;;
*get_num_data
gosub *get_data
if %ret <= MAX_NUMBER return
mul %ret, 64
add %ret, MIN_INT32
div %ret, 64
return
;;;;;;;;;;
;;;*set_data(obj, data)
;;; modifies: %tmp, %tmp1, %tmp2
;;;;;;;;;;
*set_data
mov %tmp, %%arg0
mov %tmp1, %tmp mod 64
mov %tmp2, %arg1 * 64
mov %%arg0, %tmp1 + %tmp2
return
;;;;;;;;;;
;;;*car(obj)
;;; modifies: %ret
;;; raw_car is used for extracting a content of symbol (maybe "nil").
;;;;;;;;;;
*car
if %arg0 == %nil mov %ret, %nil : return
*raw_car
gosub *get_data
mov %ret, %ret mod 8192 ; 2^13
return
;;;;;;;;;;
;;;*cdr(obj)
;;; modifies: %ret
;;; raw_cdr is used for extracting a content of symbol (maybe "nil").
;;;;;;;;;;
*cdr
if %arg0 == %nil mov %ret, %nil : return
*raw_cdr
gosub *get_data
div %ret, 8192 ; 2^13
return
;;;;;;;;;;
;;;*set_car(obj0, obj1)
;;; You should check the type of argument before calling this subroutine.
;;; This subroutine modifies some variables but the value of %arg0 is kept.
;;;;;;;;;;
*set_car
gosub *push ; S(obj0)
mov %tmp, %arg0
mov %arg0, %arg1
gosub *push ; S(obj1, obj0)
mov %arg0, %tmp
gosub *get_data
mov %tmp1, %ret
div %tmp1, 8192
mul %tmp1, 8192 ; %tmp1 = cdr
gosub *pop ; obj1 < S(obj0)
add %tmp1, %ret ; car + cdr (data)
gosub *pop ; obj0 < S()
mov %arg0, %ret
mov %arg1, %tmp1 ; car + cdr (data)
gosub *set_data
return
;;;;;;;;;;
;;;*set_cdr(obj0, obj1)
;;; See *set_car.
;;;;;;;;;;
*set_cdr
gosub *push ; S(obj0)
mov %tmp, %arg0
mov %arg0, %arg1
gosub *push ; S(obj1, obj0)
mov %arg0, %tmp
gosub *get_data
mov %tmp1, %ret mod 8192 ; %tmp1 = car
gosub *pop ; obj1 < S(obj0)
mul %ret, 8192 ; %ret = cdr
mov %tmp1, %tmp1 + %ret ; %tmp1 = car + cdr (data)
gosub *pop ; obj0 < S()
mov %arg0, %ret
mov %arg1, %tmp1 ; car + cdr (data)
gosub *set_data
return
;;;;;;;;;;
;;;*mem_init()
;;;;;;;;;;
*mem_init
; Read special characters
readfile $stmp, "same.jim"
mid $sTAB, $stmp, 0, 1
mid $sCR, $stmp, 1, 1
mid $sLF, $stmp, 2, 1
mov %gc_run, 0
mov %gc_mark_color, 1
mov %eval_limit, DEFAULT_EVAL_LIMIT
mov %symbol_offset, 0
mov %symbol_used, SYMBOL_SET
mov %sp, STACK
mov %ssp, SSTACK
mov %free_lst, HEAP
for %i=HEAP to HEAP_LAST ; Create the free-list
mov %arg0, %i
mov %arg1, TAG_FREE
gosub *set_tag
mov %arg0, %i
mov %arg1, %i + 1
gosub *set_data
next
mov %arg0, 0
gosub *create_bool
mov %sharp_f, %ret
mov %arg0, 1
gosub *create_bool
mov %sharp_t, %ret
mov %symbol_lst, HEAP_LIMIT
mov $sarg0, "nil"
gosub *create_symbol
mov %nil, %ret
mov $sarg0, "quote"
gosub *create_symbol
mov %quote, %ret
gosub *set_global_env
mov %current_proc, %nil
mov %current_env, %global_env
return
;;;;;;;;;;
;;;*next_cell()
;;;;;;;;;;
*next_cell
; If there is no cell, then do GC.
if %free_lst == HEAP_LIMIT gosub *gc
; If there is no cell after GC, then quit.
if %free_lst == HEAP_LIMIT mesbox "メモリ不足", "Error" : end
mov %arg0, %free_lst ; %arg0 = current cell
gosub *get_data ; %ret = next cell
mov %free_lst, %ret
mov %arg1, 1 - %gc_mark_color
gosub *set_gc ; set_gc(current cell, unmarked color)
mov %ret, %arg0
return
;;;;;;;;;;
;;;*reuse_cell(obj, i)
;;;;;;;;;;
*reuse_cell
gosub *set_data
mov %arg1, TAG_FREE
gosub *set_tag
return
;;;;;;;;;;
;;;*gc()
;;; This subroutine does not keep %ret because GC occurs in consing.
;;; This subroutine does not keep %i because GC does not occurs in for-loop.
;;;;;;;;;;
*gc
inc %gc_run
gosub *push_registers
mov %gc_count, 0
textclear
if %gc_silent >= 1 goto *gc_sl1
!s0GCing・・・!sd
*gc_sl1
gosub *gc_mark
gosub *gc_sweep
if %gc_silent >= 1 goto *gc_sl2
!s0Used:%gc_count!sd
mov %gc_count, HEAP_LIMIT - %gc_count
mov %gc_count, %gc_count - HEAP
!s0Available:%gc_count!sd
*gc_sl2
gosub *pop_registers
mov %gc_mark_color, 1 - %gc_mark_color ; Flip the mark color.
return
;;;;;;;;;;
;;;*gc_mark_lobject(obj)
;;;;;;;;;;
*gc_mark_lobject
gosub *get_gc
if %ret == %gc_mark_color return ; Already marked
mov %arg1, %gc_mark_color
gosub *set_gc ; Mark the object
inc %gc_count
gosub *get_tag
if %ret == TAG_CONS goto *gc_mark_lobject_cons
if %ret == TAG_EXPR goto *gc_mark_lobject_cons
if %ret == TAG_ERROR goto *gc_mark_lobject_cons
if %ret == TAG_VAR goto *gc_mark_lobject_var
if %ret == TAG_GVAR goto *gc_mark_lobject_cons
return
*gc_mark_lobject_cons
gosub *push ; S(obj)
gosub *car ; CAR(obj)
mov %arg0, %ret
gosub *gc_mark_lobject
gosub *pop ; obj < S()
mov %arg0, %ret
gosub *cdr ; CDR(obj)
mov %arg0, %ret
goto *gc_mark_lobject
*gc_mark_lobject_var
gosub *cdr ; CDR(obj)
mov %arg0, %ret
goto *gc_mark_lobject
;;;;;;;;;;
;;;*gc_mark_syntax_keyword()
;;;;;;;;;;
*gc_mark_syntax_keyword
mov %arg0, %quote
gosub *gc_mark_lobject
mov %arg0, %sym_begin
gosub *gc_mark_lobject
mov %arg0, %sym_cond
gosub *gc_mark_lobject
mov %arg0, %sym_lambda
gosub *gc_mark_lobject
mov %arg0, %sym_define
gosub *gc_mark_lobject
mov %arg0, %sym_let
gosub *gc_mark_lobject
mov %arg0, %sym_if
gosub *gc_mark_lobject
mov %arg0, %sym_and
gosub *gc_mark_lobject
mov %arg0, %sym_or
gosub *gc_mark_lobject
mov %arg0, %sym_set
gosub *gc_mark_lobject
mov %arg0, %sym_letrec
gosub *gc_mark_lobject
mov %arg0, %sym_letstar
gosub *gc_mark_lobject
mov %arg0, %sym_time
gosub *gc_mark_lobject
mov %arg0, %sym_else
gosub *gc_mark_lobject
return
;;;;;;;;;;
;;;*gc_mark()
;;;;;;;;;;
*gc_mark
mov %arg0, %global_env
gosub *gc_mark_lobject
gosub *gc_mark_syntax_keyword
if %sp == STACK return ; Stack is empty.
for %i = STACK to %sp-1
; Stack may contain non-pointer values.
; Do conservative GC.
if %%i < HEAP goto *gc_mark_l1
if %%i > HEAP_LAST goto *gc_mark_l1
mov %arg0, %%i
gosub *gc_mark_lobject
*gc_mark_l1
next
return
;;;;;;;;;;
;;;*gc_sweep()
;;;;;;;;;;
*gc_sweep
mov %free_lst, HEAP_LIMIT
mov %symbol_lst, HEAP_LIMIT
for %i=HEAP to HEAP_LAST ; Find the first unused cell.
mov %arg0, %i
gosub *get_gc
if %ret != %gc_mark_color mov %free_lst, %i : break
gosub *get_tag
if %ret != TAG_SYMBOL goto *gc_sweep_next0
mov %arg1, %symbol_lst
gosub *set_cdr
mov %symbol_lst, %i
*gc_sweep_next0
next
if %free_lst == HEAP_LIMIT return ; There is no unused cell.
mov %gc_tmp, %free_lst ; Keep the first unusd cell.
for %i=%i+1 to HEAP_LAST
mov %arg0, %i
gosub *get_gc
if %ret == %gc_mark_color goto *gc_sweep_marked
; Append the new unused cell to the free-list if GC-bit is unmarked.
mov %arg0, %gc_tmp
mov %arg1, %i
gosub *reuse_cell
mov %gc_tmp, %i
goto *gc_sweep_next1
*gc_sweep_marked
mov %arg0, %i
gosub *get_tag
if %ret != TAG_SYMBOL goto *gc_sweep_next1
mov %arg1, %symbol_lst
gosub *set_cdr
mov %symbol_lst, %i
*gc_sweep_next1
next
mov %arg0, %gc_tmp
mov %arg1, HEAP_LIMIT ; The end of the free-list.
gosub *reuse_cell
return
*push_registers
gosub *push ; S(arg0)
mov %arg0, %arg1
gosub *push ; S(arg1, arg0)
mov %arg0, %arg2
gosub *push ; S(arg2, arg1, arg0)
mov %arg0, %arg3
gosub *push ; S(arg3, arg2, arg1, arg0)
mov %arg0, %tmp
gosub *push ; S(tmp, arg3, arg2, arg1, arg0)
mov %arg0, %tmp1
gosub *push ; S(tmp1, tmp, arg3, arg2, arg1, arg0)
mov %arg0, %tmp2
gosub *push ; S(tmp2, tmp1, tmp, arg3, arg2, arg1, arg0)
mov %arg0, %tmp3
gosub *push ; S(tmp3, tmp2, tmp1, tmp, arg3, arg2, arg1, arg0)
return
*pop_registers
gosub *pop ; tmp3 < S(tmp2, tmp1, tmp, arg3, arg2, arg1, arg0)
mov %tmp3, %ret
gosub *pop ; tmp2 < S(tmp1, tmp, arg3, arg2, arg1, arg0)
mov %tmp2, %ret
gosub *pop ; tmp1 < S(tmp, arg3, arg2, arg1, arg0)
mov %tmp1, %ret
gosub *pop ; tmp < S(arg3, arg2, arg1, arg0)
mov %tmp, %ret
gosub *pop ; arg3 < S(arg2, arg1, arg0)
mov %arg3, %ret
gosub *pop ; arg2 < S(arg1, arg0)
mov %arg2, %ret
gosub *pop ; arg1 < S(arg0)
mov %arg1, %ret
gosub *pop ; arg0 < S()
mov %arg0, %ret
return
;;;;;;;;;;
;;;*symbol_gc()
;;; This subroutine does not keep %ret.
;;; This subroutine does not keep %i.
;;;;;;;;;;
*symbol_gc
gosub *push_registers
mov %gc_count, 0
textclear
if %gc_silent >= 1 goto *symbol_gc_sl1
Symbol GCing・・・
*symbol_gc_sl1
mov %tmp, SYMBOL_SET_HALF_SIZE
add %symbol_offset, %tmp
mul %tmp, 2
mov %symbol_offset, %symbol_offset mod %tmp
mov %symbol_used, SYMBOL_SET + %symbol_offset
mov %i, %symbol_lst
*symbol_gc_l1
if %i == HEAP_LIMIT goto *symbol_gc_l2
mov %arg0, %i
gosub *raw_car
mov $%symbol_used, $%ret
mov %arg0, %i
mov %arg1, %symbol_used
gosub *set_car
inc %symbol_used
mov %tmp, %symbol_used - SYMBOL_SET
sub %tmp, %symbol_offset
if %tmp >= SYMBOL_SET_HALF_SIZE mesbox "メモリ不足", "Error" : end
mov %arg0, %i
gosub *raw_cdr
mov %i, %ret
inc %gc_count
goto *symbol_gc_l1
*symbol_gc_l2
if %gc_silent >= 1 goto *symbol_gc_sl2
mov %tmp, SYMBOL_SET_HALF_SIZE
Used:%gc_count
mov %gc_count, %tmp - %gc_count
Available:%gc_count
*symbol_gc_sl2
gosub *pop_registers
return
;;;;;;;;;;
;;;*create_cons()
;;;;;;;;;;
*create_cons
gosub *next_cell
mov %arg0, %ret
mov %arg1, TAG_CONS
gosub *set_tag
mov %ret, %arg0
return
;;;;;;;;;;
;;;*create_num(n)
;;;;;;;;;;
*create_num
if %arg0 < MIN_NUMBER mov %arg0, %arg0 + MIN_INT32
if %arg0 > MAX_NUMBER mov %arg0, %arg0 mod UNSIGNED_MAX_PLUS1
if %arg0 < 0 mov %arg0, %arg0 + UNSIGNED_MAX_PLUS1
gosub *push ; S(n)
gosub *next_cell
mov %arg0, %ret ; new cell
mov %arg1, TAG_NUM
gosub *set_tag
gosub *pop ; n < S()
mov %arg1, %ret
gosub *set_data
mov %ret, %arg0
return
;;;;;;;;;;
;;;*create_symbol(str)
;;;;;;;;;;
*create_symbol
mov %i, %symbol_lst
*create_symbol_l1
if %i == HEAP_LIMIT goto *create_symbol_l2
mov %arg0, %i
gosub *raw_car
if $sarg0 == $%ret mov %ret, %i : return
mov %arg0, %i
gosub *raw_cdr
mov %i, %ret
goto *create_symbol_l1
*create_symbol_l2
mov $%symbol_used, $sarg0
gosub *next_cell
mov %arg0, %ret
gosub *push
mov %arg1, TAG_SYMBOL
gosub *set_tag
mov %arg1, %symbol_used
gosub *set_car
mov %tmp, %sp - 1
mov %arg0, %%tmp
mov %arg1, %symbol_lst
gosub *set_cdr
gosub *pop
inc %symbol_used
mov %symbol_lst, %ret
mov %tmp, %symbol_used - SYMBOL_SET
sub %tmp, %symbol_offset