This repository has been archived by the owner on Aug 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathm2stp.monkey2
348 lines (286 loc) · 7.08 KB
/
m2stp.monkey2
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
' Monkey2 Simple text processing
' By @Hezkore 2018
' https://github.com/Hezkore/m2stp
Namespace m2stp
#Import "<std>"
Using std..
#Import "inc/base_functions"
Class StpString
'Symbols all have a max length of 1
Field _escSymbol:String="'"
Field _conLeftSymbol:String="["
Field _conRightSymbol:String="]"
Field _varSymbol:String="%"
Field _funcSymbol:String="$"
Field _funcParamSepSymbol:String=","
Field _funcParamLeftSymbol:String="("
Field _funcParamRightSymbol:String=")"
'Previous result
Field _result:String
'Stored functions and variables
Field _funcs:=New Map<String,Func>
Field _vars:=New Map<String,String>
'Format related
Field _f_string:String
Method New( loadBase:Bool=True )
If loadBase Then LoadBase()
End
Method Format:String( str:String )
_f_string=FormatVar( str )
If ContainsFunc( _f_string ) Then
_result=FormatFunc( _f_string )
Else
_result=_f_string
Endif
'Clean up escape symbols
_result=CleanEsc( _result )
Return _result
End
Method CleanEsc:String( str:String )
Local result:String
Local chr:String
Local nextChr:String
Local thirdChr:String
For Local i:=0 Until str.Length
chr=String.FromChar( str[i] )
nextChr=Null
If i<str.Length-1 nextChr=String.FromChar( str[i+1] )
thirdChr=Null
If i<str.Length-2 thirdChr=String.FromChar( str[i+2] )
'Skip escape symbol unless there's 3 of them
If chr=_escSymbol Then
If chr=_escSymbol And nextChr=_escSymbol And thirdChr=_escSymbol Then
result+=chr
Endif
Continue
Endif
result+=chr
Next
Return result
End
Method FormatFunc:String( str:String )
Local name:String
Local paramData:String
Local params:=New Stack<String>
Local inEsc:Bool
Local result:String
Local chr:String
Local nextChr:String
Local thirdChr:String
Local nested:Int
For Local i:=0 Until str.Length
chr=String.FromChar( str[i] )
nextChr=Null
If i<str.Length-1 nextChr=String.FromChar( str[i+1] )
thirdChr=Null
If i<str.Length-2 thirdChr=String.FromChar( str[i+2] )
If Not inEsc Then
If chr=_funcSymbol Then
'We've found a function!
'Look forward for left symbol
For Local fi:=i+1 Until str.Length
chr=String.FromChar( str[fi] )
'Left symbol found
If chr=_funcParamLeftSymbol Then
'Look forward for parameters
For Local pi:=fi+1 Until str.Length
chr=String.FromChar( str[pi] )
'Is this another function?
If chr=_funcSymbol Then
nested+=1
Endif
If nested Then
paramData+=chr
If chr=_funcParamRightSymbol Then
nested-=1
Endif
Else
If chr=_funcParamSepSymbol Or chr=_funcParamRightSymbol Then
If paramData Then params.Add( paramData )
paramData=Null
If chr=_funcParamRightSymbol Then
'EXECUTE!
For Local pfi:=0 Until params.Length
If ContainsFunc( params[pfi] ) Then
params[pfi]=FormatFunc( params[pfi] )
Endif
Next
result+=CallFunc( name, params )
'Jump forward to the end of the function
i=pi
'Reset data
name=Null
paramData=Null
params.Clear()
Exit
Endif
Else
paramData+=chr
Endif
Endif
Next
Exit
Else
name+=chr
Endif
Next
Elseif chr=_escSymbol Then
If nextChr=_escSymbol And thirdChr=_escSymbol Then
inEsc=False
result+=chr.Dup(3)
i+=2
Else
inEsc=True
result+=chr
Endif
Else
result+=chr
Endif
Else
'Inside escape character
If chr=_escSymbol Then
inEsc=False
result+=chr
Else
result+=chr
Endif
Endif
Next
Return result
End
Method ContainsFunc:Bool( str:String )
Local inEsc:Bool
Local chr:String
Local nextChr:String
Local thirdChr:String
For Local i:=0 Until str.Length
chr=String.FromChar( str[i] )
nextChr=Null
If i<str.Length-1 nextChr=String.FromChar( str[i+1] )
thirdChr=Null
If i<str.Length-2 thirdChr=String.FromChar( str[i+2] )
If chr=_escSymbol Then
If nextChr=_escSymbol And thirdChr=_escSymbol Then
inEsc=False
i+=2
Else
inEsc=Not inEsc
Endif
Endif
'We've found a function!
If Not inEsc And chr=_funcSymbol Then
Return True
Endif
Next
Return False
End
Method FormatVar:String( str:String )
Local inVar:Bool
Local name:String
Local inEsc:Bool
Local result:String
Local chr:String
Local nextChr:String
Local thirdChr:String
For Local i:=0 Until str.Length
chr=String.FromChar( str[i] )
nextChr=Null
If i<str.Length-1 nextChr=String.FromChar( str[i+1] )
thirdChr=Null
If i<str.Length-2 thirdChr=String.FromChar( str[i+2] )
If inVar Then
If chr=_varSymbol Then
result+=GetVar( name )
inVar=False
name=Null
Else
name+=chr
Endif
Else
If Not inEsc Then
If chr=_escSymbol Then
If nextChr=_escSymbol And thirdChr=_escSymbol Then
inEsc=False
result+=chr.Dup(3)
i+=2
Else
inEsc=True
result+=chr
Endif
Elseif chr=_varSymbol
inVar=True
Else
result+=chr
Endif
Else
If chr=_escSymbol Then
inEsc=False
result+=chr
Else
result+=chr
Endif
Endif
Endif
Next
Return result
End
Method CallFunc:String( name:String, param:Stack<String> )
name=name.ToLower()
'Print "Calling function ~q"+name+"~q"
If _funcs.Contains( name ) Then
'Print "Found func ~q"+name+"~q"
'Okay function found, clean parameters
For Local i:=0 Until param.Length
param[i]=param[i].Trim()
param[i]=param[i].Replace( "~n", "" )
param[i]=param[i].Replace( "~r", "" )
param[i]=param[i].Replace( "~t", "" )
Next
Return _funcs.Get( name ).OnCall( param )
Endif
'Print "Could not find func ~q"+name+"~q"
Return Null
End
Method AddFunc( name:String, f:Func )
If f Then
'Print "Adding function ~q"+name
_funcs.Add( name.ToLower(), f )
Endif
End
Method GetVar:String( name:String )
name=name.ToLower()
If _vars.Contains( name ) Then
'Print "Found variable ~q"+name+"~q with value ~q"+_vars.Get( name )+"~q"
Return _vars.Get( name )
Endif
Return Null
End
Method SetVar( name:String, v:String )
'Print "Setting variable ~q"+name+"~q to ~q"+v+"~q"
name=name.ToLower()
If name Then
If _vars.Contains( name ) Then
_vars.Update( name, v )
Else
_vars.Add( name, v )
Endif
Endif
End
Method To:String()
Return _result
End
Method LoadBase()
'Functions
AddFunc( "add", New StpAdd )
AddFunc( "sub", New StpSub )
AddFunc( "div", New StpDiv )
AddFunc( "mul", New StpMul )
'Variables
SetVar( "stp_version", "1" )
End
Class Func Abstract
Method OnCall:String( param:Stack<String> ) Virtual
Return Null
End
End
End