-
Notifications
You must be signed in to change notification settings - Fork 1
/
transpiler.bas
192 lines (166 loc) · 5.82 KB
/
transpiler.bas
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
' PROJECT SMILE++
' Smile++ Transpiler 2017.1
option strict
acls
prgEdit 1
' 文字列に含まれる小文字アルファベットを大文字に変換する
def upcase$(string$)
var i
var charCode
for i = 0 to len(string$) - 1
charCode = asc(mid$(string$, i, 1))
if charCode >= asc("a") && charCode <= asc("z") then
string$ = substr$(string$, i, 1, chr$(charCode - 32))
endif
next
return string$
end
' 配列の要素を検索する
def indexOf$(array$[], string$)
var i
for i = 0 to len(array$) - 1
if array$[i] == string$ then return i
next
return -1
end
' 配列を生成する
def array(list$)
dim arr[0]
var tmp = ""
var i
var c$ = ""
for i = 0 to len(list$) - 1
c$ = mid$(list$, i, 1)
if c$ == " " && tmp$ != "" then
push arr, val(tmp$)
tmp$ = ""
endif
tmp$ = tmp$ + c$
next
if tmp$ != "" && tmp$ != " " then push arr, val(tmp$)
return arr
end
def array$(list$)
dim arr$[0]
var tmp$ = ""
var i
var c$ = ""
for i = 0 to len(list$) - 1
c$ = mid$(list$, i, 1)
if c$ == " " && tmp$ != "" then
push arr$, tmp$
tmp$ = ""
else
tmp$ = tmp$ + c$
endif
next
if tmp$ != "" && tmp$ != " " then push arr$, tmp$
return arr$
end
' 配列の内容を出力する
def arrayDump arr[]
var i
for i = 0 to len(arr) - 1
? str$(arr[i]) + " ";
next
? ""
end
def arrayDump arr$[]
var i
for i = 0 to len(arr$) - 1
? arr$[i] + " ";
next
? ""
end
' 定数
var NONE = -1, UNKNOWN = 1, DIRECTION = 2, RESERVED = 3
var OPERATOR = 4, CONSTANT = 5, STRING = 6
' 演算子
dim operators$[0]
operators$ = array$("+ - * / DIV MOD << >> NOT ( ) == != < <= > >= && || AND OR XOR !")
' 予約語
dim reservedWords$[0]
reservedWords$ = array$("IF THEN ELSE ELSEIF ENDIF GOTO GOSUB RETURN ON FOR NEXT WHILE WEND REPEAT UNTIL BREAK CONTINUE DEF END VAR DIM DATA READ RESTORE PRINT INPUT LINPUT CALL SWAP OUT COMMON USE EXEC FILES SAVE RENAME DELETE CHKFILE PRGEDIT PRGGET$ PRGSET PRGINS PRGDEL PRGSIZE PRGNAME$ XSCREEN DISPLAY VISIBLE BACKCOLOR ACLS FADE CLS COLOR LOCATE PRINT ? ATTR SCROLL FONTDEF WIDTH SPPAGE SPCLIP SPDEF SPSET SPCLR SPSHOW SPHIDE SPHOME SPOFS SPROT SPSCALE SPCOLOR SPCHR SPLINK SPUNLINK SPANIM SPSTOP SPSTART SPCHK SPVAR SPCOL SPCOLVEC SPHITINFO SPFUNC BGPAGE BGSCREEN BGCLR BGSHOW BGHIDE BGCLIP BGHOME BGOFS BGROT BGSCALE BGPUT BGFILL BGSET BGANIM BGSTOP BGSTART BGCHK BGVAR BGLOAD BGSAVE BGCOORD BGCOLOR BGFUNC GPAGE GCOLOR RGBREAD GCLIP GPRIO GCLS GPSET GLINE GCIRCLE GBOX GFILL GPAINT GCOPY GSAVE GLOAD GTRI GPUTCHR GOFS GPUTCHR16 XON XOFF BUTTON BREPEAT STICK STICKX ACCEL GYROA GYROV GYROSYNC TOUCH MICSTART MICSTOP MICDATA MICSAVE CONTROLLER VIBLATE BEEP BGMCHK BGMCLEAR BGMPLAY BGMSET BGMSETD BGMVAR BGMSTOP BGMVOL WAVSET WAVSETA EFCOFF EFCON EFCSET EFCWET TALK TALKCHK TALKSTOP BGMPAUSE BGMCONT SNDSTOP BIQUAD BQPARAM FFT IFFT FFTWFN PCMCONT PCMSTOP PCMSTREAM PCMVOL RINGCOPY ARYOP MPSTART MPSEND MPRECV MPSTAT MPNAME$ MPGET MPSET INC DEC COPY SORT RSORT PUSH UNSHIFT FILL RANDOMIZE STOP OPTION WAIT VSYNC REM KEY DTREAD TMREAD DIALOG CLIPBOARD DLCOPEN")
' 組み込み定数
dim constants$[0]
constants$ = array$("ON OFF YES NO TRUE FALSE BLACK NAVY BLUE GREEN TEAL LIME AQUA CYAN MAROON PURPLE OLIVE GRAY SILVER RED FUCHSIA MAGENTA YELLOW WHITE TBLACK TMAROON TRED TGREEN TLIME TOLIVE TYELLOW TNAVY TBLUE TPURPLE TMAGENTA TTREAL TCYAN TGRAY TWHITE UP DOWN LEFT RIGHT A B X Y L R ZR ZL TROT0 TROT90 TROT180 TROT270 TREVH TREVV SPSHOW SPROT0 SPROT90 SPROT180 SPROT180 SPROT270 SPREVH SPREVV SPADD BGROT0 BGROT90 BGROT180 BGROT270 BGREVH BGREVV CHKXY CHKZ CHKUV CHKI CHKR CHKS CHKC CHKV BQAPF BQLPF BQHPF BQBPF BQBSF BQLSF BQHSF BQPEQ WFRECT WFHAMM WFHANN WFBLKM AOPADD AOPSUB AOPMUL AOPDIV AOPMAD AOPLIP AOPCLP")
' 字句解析
def lex string$, tk$[], type[]
var record$ = ""
var phase = NONE
var index = 0
var isRecorded = false
while true
var c$ = mid$(string$, index, 1)
if c$ == chr$(34) && phase != NONE then
phase = STRING
isRecorded = true
inc index
elseif c$ == chr$(34) && phase == STRING then
push type, phase : phase = NONE
push tk$, record$ + chr$(34)
record$ = ""
isRecorded = false
inc index
elseif phase == STRING && index != len(string$) - 1 then
inc index
elseif c$ == chr$(34) && phase != STRING then
if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
if indexOf$(operators$, upcase(record$)) != -1 then phase = OPERATOR
if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
push type, phase : phase = NONE
push tk$, record$
record$ = ""
phase = STRING
inc index
elseif c$ == "#" then
phase = DIRECTION
isRecorded = true
inc index
elseif c$ == " " || index == len(string$) - 1 then
if phase == UNKNOWN then
if indexOf$(reservedWords$, upcase$(record$)) != -1 then phase = RESERVED
if indexOf$(operators$, upcase$(record$)) != -1 then phase = OPERATOR
endif
if phase == DIRECTION && indexOf$(constants$, upcase$(record$)) != -1 then phase = CONSTANT
if phase == STRING then ? "Error: 文字列定数がダブルクォートによって正しく閉じられていません" : break
if phase != NONE then
push type, phase : phase = NONE
push tk$, record$
record$ = ""
isRecorded = false
endif
inc index
elseif c$ != " " && !isRecorded then
phase = UNKNOWN
isRecorded = true
inc index
else
inc index
endif
if isRecorded then record$ = record$ + c$
if index >= len(string$) then break
wend
end
var i, n
for n = 0 to prgSize(1) - 1
dim tk$[0]
dim type[0]
lex prgGet$(), tk$, type
for i = 0 to len(tk$)
? tk$[i] + " -> ";
if type[i] == UNKNOWN then
? "Unknown"
elseif type[i] == DIRECTION then
? "Direction"
elseif type[i] == RESERVED then
? "Reserved"
elseif type[i] == OPERATOR then
? "Operator"
elseif type[i] == CONSTANT then
? "Constant"
elseif type[i] == STRING then
? "String"
endif
next
next