1 //--- K.I.LIB ---
2 // kl_rythp.cpp : interpretor for simple script langauage 'Rythp'
3
4 #include "stdafx.h"
5 #include "kilibext.h"
6
7 //-------------------- Variant 型変数 --------------------------//
8
9 int kiVar::getInt()
10 {
11 int n=0;
12 bool minus = (*m_pBuf=='-');
13 for( char* p = minus ? m_pBuf+1 : m_pBuf; *p; p=next(p) )
14 {
15 if( '0'>*p || *p>'9' )
16 return 0;
17 n = (10*n) + (*p-'0');
18 }
19 return minus ? -n : n;
20 }
21
22 kiVar& kiVar::quote()
23 {
24 if( m_pBuf[0]=='\"' )
25 return *this;
26 for( const char* p=m_pBuf; *p; p=next(p) )
27 if( *p==' ' )
28 break;
29 if( !(*p) )
30 return *this;
31
32 int ln=len()+1;
33 if( m_ALen<ln+2 )
34 {
35 char* tmp = new char[m_ALen=ln+2];
36 ki_memcpy( tmp+1,m_pBuf,ln );
37 delete [] m_pBuf;
38 m_pBuf = tmp;
39 }
40 else
41 ki_memmov( m_pBuf+1,m_pBuf,ln );
42 m_pBuf[0]=m_pBuf[ln]='\"', m_pBuf[ln+1]='\0';
43 return *this;
44 }
45
46 kiVar& kiVar::unquote()
47 {
48 if( *m_pBuf!='\"' )
49 return *this;
50 for( const char *last=m_pBuf+1,*p=m_pBuf+1; *p; p=next(p) )
51 last=p;
52 if( *last!='\"' )
53 return *this;
54
55 ki_memmov( m_pBuf,m_pBuf+1,(last-m_pBuf)-1 );
56 m_pBuf[(last-m_pBuf)-1]='\0';
57 return *this;
58 }
59
60 //---------------------- 初期化・破棄 ----------------------------//
61
62 kiRythpVM::kiRythpVM()
63 {
64 ele['%'] = "%";
65 ele['('] = "(";
66 ele[')'] = ")";
67 ele['"'] = "\"";
68 ele['/'] = "\n";
69 }
70
71 //---------------------- パラメータ毎に分割 ----------------------//
72
73 char* kiRythpVM::split_tonext( char* p )
74 {
75 while( *p!='\0' && ( *p=='\t' || *p==' ' || *p=='\r' || *p=='\n' ) )
76 p++;
77 return (*p=='\0' ? NULL : p);
78 }
79
80 char* kiRythpVM::split_toend( char* p )
81 {
82 int kkc=0, dqc=0;
83 while( *p!='\0' && kkc>=0 )
84 {
85 if( *p=='(' && !(dqc&1) )
86 kkc++;
87 else if( *p==')' && !(dqc&1) )
88 kkc--;
89 else if( *p=='\"' )
90 dqc++;
91 else if( *p=='%' )
92 p++;
93 else if( (*p=='\t' || *p==' ' || *p=='\r' || *p=='\n') && kkc==0 && !(dqc&1) )
94 return p;
95 p++;
96 }
97 return (kkc==0 && !(dqc&1)) ? p : NULL;
98 }
99
100 bool kiRythpVM::split( char* buf, kiArray<char*>& argv, kiArray<bool>& argb, int& argc )
101 {
102 argv.empty(), argb.empty(), argc=0;
103
104 for( char* p=buf; p=split_tonext(p); p++,argc++ )
105 {
106 argv.add( p );
107 argb.add( *p=='(' );
108
109 if( !(p=split_toend(p)) )
110 return false;
111
112 if( argv[argc][0]=='(' || argv[argc][0]=='"' )
113 argv[argc]++, *(p-1)='\0';
114 if( *p=='\0' )
115 {
116 argc++;
117 break;
118 }
119 *p='\0';
120 }
121 return true;
122 }
123
124 //------------------------- 実行 -------------------------//
125
126 void kiRythpVM::eval( char* str, kiVar* ans )
127 {
128 // 返値をクリアしておく
129 kiVar tmp,*aaa=&tmp;
130 if(ans)
131 *ans="",aaa=ans;
132
133 // "function param1 param2 ..." 形式の文字列をパラメータに分割
134 kiArray<char*> av;
135 kiArray<bool> ab;
136 int ac;
137 if( split( str,av,ab,ac ) && ac )
138 {
139 // function名取得
140 kiVar name;
141 getarg( av[0],ab[0],&name );
142
143 // function実行!
144 exec_function( name, av, ab, ac, aaa );
145 }
146 }
147
148 void kiRythpVM::getarg( char* a, bool b, kiVar* arg )
149 {
150 kiVar t;
151 const char* p;
152
153 // (...) なら eval する。
154 if( b )
155 {
156 eval( a, &t ), *arg = t;
157 }
158 else
159 {
160 p = a;
161
162 // 変数置き換え
163 *arg="";
164 for( ; *p; *p && p++ )
165 if( *p!='%' )
166 {
167 *arg += *p;
168 }
169 else
170 {
171 p++, *arg+=ele[(*p)&0xff];
172 }
173 }
174 }
175
176 //------------------------- Minimum-Rythp環境 -------------------------//
177
178 namespace {
179 static bool isIntStr( const char* str ) {
180 for(;*str;++str)
181 if( !('0'<=*str && *str<='9' || *str==',' || *str=='-') )
182 return false;
183 return true;
184 }
185 }
186
187 bool kiRythpVM::exec_function( const kiVar& name,
188 const kiArray<char*>& a, const kiArray<bool>& b,int c, kiVar* r )
189 {
190 // Minimum-Rythp で利用できる function は以下の通り。
191 // exec, while, if, let, +, -, *, /, =, !, between, mod, <, >
192
193 kiVar t;
194 int i,A,B,C;
195
196 //----- ---- --- -- - - -
197 //-- (exec 実行文 実行文 ...) returns last-result
198 //----- ---- --- -- - - -
199 if( name=="exec" )
200 {
201 for( i=1; i<c; i++ )
202 getarg( a[i],b[i],r );
203 }
204 //----- ---- --- -- - - -
205 //-- (while 条件 繰り返す内容) returns last-result
206 //----- ---- --- -- - - -
207 else if( name=="while" )
208 {
209 if( c>=3 )
210 {
211 // (特殊処理)複数回呼ぶコードなのでコピらなきゃ駄目。
212 int L1=ki_strlen(a[1]), L2=ki_strlen(a[2]);
213 char* tmp = new char[ 1 + (L1>L2 ? L1 : L2) ];
214 while( getarg( ki_strcpy(tmp,a[1]), b[1], &t ), t.getInt()!=0 )
215 getarg( ki_strcpy(tmp,a[2]), b[2], r );
216 delete [] tmp;
217 }
218 }
219 //----- ---- --- -- - - -
220 //-- (if 条件 真なら [偽なら]) returns executed-result
221 //----- ---- --- -- - - -
222 else if( name=="if" )
223 {
224 if( c>=3 )
225 {
226 if( getarg( a[1],b[1],&t ), t.getInt()!=0 )
227 getarg( a[2],b[2],r );
228 else if( c>=4 )
229 getarg( a[3],b[3],r );
230 }
231 }
232 //----- ---- --- -- - - -
233 //-- (let 変数名 値 値 ...) returns new-value
234 //----- ---- --- -- - - -
235 else if( name=="let" )
236 {
237 if( c>=2 )
238 {
239 *r = "";
240 for( i=2; i<c; i++ )
241 getarg( a[i],b[i],&t ), *r+=t;
242 ele[a[1][0]&0xff] = *r;
243 }
244 }
245 //----- ---- --- -- - - -
246 //-- (= 値A 値B) returns A==B ?
247 //----- ---- --- -- - - -
248 else if( name=="=" )
249 {
250 if( c>=3 )
251 {
252 kiVar t2;
253 getarg(a[1],b[1],&t), A=t.getInt();
254 getarg(a[2],b[2],&t2), B=t2.getInt();
255 if( isIntStr(t) && isIntStr(t2) )
256 *r = A==B ? "1" : "0";
257 else
258 *r = t==t2 ? "1" : "0";
259 }
260 }
261 //----- ---- --- -- - - -
262 //-- (between 値A 値B 値C) returns A <= B <= C ?
263 //----- ---- --- -- - - -
264 else if( name=="between" )
265 {
266 if( c>=4 )
267 {
268 getarg(a[1],b[1],&t), A=t.getInt();
269 getarg(a[2],b[2],&t), B=t.getInt();
270 getarg(a[3],b[3],&t), C=t.getInt();
271 *r = (A<=B && B<=C) ? "1" : "0";
272 }
273 }
274 //----- ---- --- -- - - -
275 //-- (< 値A 値B) returns A < B ?
276 //----- ---- --- -- - - -
277 else if( name=="<" )
278 {
279 if( c>=3 )
280 {
281 getarg(a[1],b[1],&t), A=t.getInt();
282 getarg(a[2],b[2],&t), B=t.getInt();
283 *r = (A<B) ? "1" : "0";
284 }
285 }
286 //----- ---- --- -- - - -
287 //-- (> 値A 値B) returns A > B ?
288 //----- ---- --- -- - - -
289 else if( name==">" )
290 {
291 if( c>=3 )
292 {
293 getarg(a[1],b[1],&t), A=t.getInt();
294 getarg(a[2],b[2],&t), B=t.getInt();
295 *r = (A>B) ? "1" : "0";
296 }
297 }
298 //----- ---- --- -- - - -
299 //-- (! 値A [値B]) returns A!=B ? or !A
300 //----- ---- --- -- - - -
301 else if( name=="!" )
302 {
303 if( c>=2 )
304 {
305 getarg(a[1],b[1],&t), A=t.getInt();
306 if( c==2 )
307 *r = A==0 ? "1" : "0";
308 else
309 {
310 kiVar t2;
311 getarg(a[1],b[1],&t), A=t.getInt();
312 getarg(a[2],b[2],&t2), B=t2.getInt();
313 if( isIntStr(t) && isIntStr(t2) )
314 *r = A!=B ? "1" : "0";
315 else
316 *r = t!=t2 ? "1" : "0";
317 }
318 }
319 }
320 //----- ---- --- -- - - -
321 //-- (+ 値A 値B) returns A+B
322 //----- ---- --- -- - - -
323 else if( name=="+" )
324 {
325 int A = 0;
326 for( i=1; i<c; i++ )
327 A += (getarg(a[i],b[i],&t), t.getInt());
328 r->setInt(A);
329 }
330 //----- ---- --- -- - - -
331 //-- (- 値A 値B) returns A-B
332 //----- ---- --- -- - - -
333 else if( name=="-" )
334 {
335 if( c >= 2 )
336 {
337 getarg(a[1],b[1],&t);
338 int A = t.getInt();
339 if( c==2 )
340 A = -A;
341 else
342 for( i=2; i<c; ++i )
343 A -= (getarg(a[i],b[i],&t), t.getInt());
344 r->setInt(A);
345 }
346 else
347 r->setInt(0);
348 }
349 //----- ---- --- -- - - -
350 //-- (* 値A 値B) returns A*B
351 //----- ---- --- -- - - -
352 else if( name=="*" )
353 {
354 int A = 1;
355 for( i=1; i<c; i++ )
356 A *= (getarg(a[i],b[i],&t), t.getInt());
357 r->setInt(A);
358 }
359 //----- ---- --- -- - - -
360 //-- (/ 値A 値B) returns A/B
361 //----- ---- --- -- - - -
362 else if( name=="/" )
363 {
364 if( c>=3 )
365 {
366 getarg(a[1],b[1],&t), A=t.getInt();
367 getarg(a[2],b[2],&t), B=t.getInt();
368 r->setInt( B ? A/B : A );
369 }
370 }
371 //----- ---- --- -- - - -
372 //-- (mod 値A 値B) returns A%B
373 //----- ---- --- -- - - -
374 else if( name=="mod" )
375 {
376 if( c>=3 )
377 {
378 getarg(a[1],b[1],&t), A=t.getInt();
379 getarg(a[2],b[2],&t), B=t.getInt();
380 r->setInt( B ? A%B : 0 );
381 }
382 }
383 //----- ---- --- -- - - -
384 //-- (slash 値A) returns A.replaceAll("\\", "/")
385 //----- ---- --- -- - - -
386 else if( name=="slash" )
387 {
388 if( c>=2 )
389 {
390 getarg(a[1],b[1],&t);
391 *r = (const char*)t;
392 r->replaceToSlash();
393 }
394 }
395 else
396 return false;
397 return true;
398 }
399