5128eecc9f 2011-02-23 kinaba: //--- K.I.LIB --- 5128eecc9f 2011-02-23 kinaba: // kl_rythp.cpp : interpretor for simple script langauage 'Rythp' 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #include "stdafx.h" 5128eecc9f 2011-02-23 kinaba: #include "kilibext.h" 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //-------------------- Variant 型変数 --------------------------// 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int kiVar::getInt() 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int n=0; 5128eecc9f 2011-02-23 kinaba: bool minus = (*m_pBuf=='-'); 5128eecc9f 2011-02-23 kinaba: for( char* p = minus ? m_pBuf+1 : m_pBuf; *p; p=next(p) ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( '0'>*p || *p>'9' ) 5128eecc9f 2011-02-23 kinaba: return 0; 5128eecc9f 2011-02-23 kinaba: n = (10*n) + (*p-'0'); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return minus ? -n : n; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: void kiVar::quote() 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( m_pBuf[0]=='\"' ) 5128eecc9f 2011-02-23 kinaba: return; 5128eecc9f 2011-02-23 kinaba: for( const char* p=m_pBuf; *p; p=next(p) ) 5128eecc9f 2011-02-23 kinaba: if( *p==' ' ) 5128eecc9f 2011-02-23 kinaba: break; 5128eecc9f 2011-02-23 kinaba: if( !(*p) ) 5128eecc9f 2011-02-23 kinaba: return; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int ln=len()+1; 5128eecc9f 2011-02-23 kinaba: if( m_ALen<ln+2 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char* tmp = new char[m_ALen=ln+2]; 5128eecc9f 2011-02-23 kinaba: ki_memcpy( tmp+1,m_pBuf,ln ); 5128eecc9f 2011-02-23 kinaba: delete [] m_pBuf; 5128eecc9f 2011-02-23 kinaba: m_pBuf = tmp; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: ki_memmov( m_pBuf+1,m_pBuf,ln ); 5128eecc9f 2011-02-23 kinaba: m_pBuf[0]=m_pBuf[ln]='\"', m_pBuf[ln+1]='\0'; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //---------------------- 初期化・破棄 ----------------------------// 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: kiRythpVM::kiRythpVM() 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: ele['%'] = "%"; 5128eecc9f 2011-02-23 kinaba: ele['('] = "("; 5128eecc9f 2011-02-23 kinaba: ele[')'] = ")"; 5128eecc9f 2011-02-23 kinaba: ele['"'] = "\""; 5128eecc9f 2011-02-23 kinaba: ele['/'] = "\n"; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //---------------------- パラメータ毎に分割 ----------------------// 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: char* kiRythpVM::split_tonext( char* p ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: while( *p!='\0' && ( *p=='\t' || *p==' ' || *p=='\r' || *p=='\n' ) ) 5128eecc9f 2011-02-23 kinaba: p++; 5128eecc9f 2011-02-23 kinaba: return (*p=='\0' ? NULL : p); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: char* kiRythpVM::split_toend( char* p ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int kkc=0, dqc=0; 5128eecc9f 2011-02-23 kinaba: while( *p!='\0' && kkc>=0 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( *p=='(' && !(dqc&1) ) 5128eecc9f 2011-02-23 kinaba: kkc++; 5128eecc9f 2011-02-23 kinaba: else if( *p==')' && !(dqc&1) ) 5128eecc9f 2011-02-23 kinaba: kkc--; 5128eecc9f 2011-02-23 kinaba: else if( *p=='\"' ) 5128eecc9f 2011-02-23 kinaba: dqc++; 5128eecc9f 2011-02-23 kinaba: else if( *p=='%' ) 5128eecc9f 2011-02-23 kinaba: p++; 5128eecc9f 2011-02-23 kinaba: else if( (*p=='\t' || *p==' ' || *p=='\r' || *p=='\n') && kkc==0 && !(dqc&1) ) 5128eecc9f 2011-02-23 kinaba: return p; 5128eecc9f 2011-02-23 kinaba: p++; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return (kkc==0 && !(dqc&1)) ? p : NULL; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: bool kiRythpVM::split( char* buf, kiArray<char*>& argv, kiArray<bool>& argb, int& argc ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: argv.empty(), argb.empty(), argc=0; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: for( char* p=buf; p=split_tonext(p); p++,argc++ ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: argv.add( p ); 5128eecc9f 2011-02-23 kinaba: argb.add( *p=='(' ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if( !(p=split_toend(p)) ) 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: if( argv[argc][0]=='(' || argv[argc][0]=='"' ) 5128eecc9f 2011-02-23 kinaba: argv[argc]++, *(p-1)='\0'; 5128eecc9f 2011-02-23 kinaba: if( *p=='\0' ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: argc++; 5128eecc9f 2011-02-23 kinaba: break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: *p='\0'; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return true; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //------------------------- 実行 -------------------------// 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: void kiRythpVM::eval( char* str, kiVar* ans ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: // 返値をクリアしておく 5128eecc9f 2011-02-23 kinaba: kiVar tmp,*aaa=&tmp; 5128eecc9f 2011-02-23 kinaba: if(ans) 5128eecc9f 2011-02-23 kinaba: *ans="",aaa=ans; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // "function param1 param2 ..." 形式の文字列をパラメータに分割 5128eecc9f 2011-02-23 kinaba: kiArray<char*> av; 5128eecc9f 2011-02-23 kinaba: kiArray<bool> ab; 5128eecc9f 2011-02-23 kinaba: int ac; 5128eecc9f 2011-02-23 kinaba: if( split( str,av,ab,ac ) && ac ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: // function名取得 5128eecc9f 2011-02-23 kinaba: kiVar name; 5128eecc9f 2011-02-23 kinaba: getarg( av[0],ab[0],&name ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // function実行! 5128eecc9f 2011-02-23 kinaba: exec_function( name, av, ab, ac, aaa ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: void kiRythpVM::getarg( char* a, bool b, kiVar* arg ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: kiVar t; 5128eecc9f 2011-02-23 kinaba: const char* p; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // (...) なら eval する。 5128eecc9f 2011-02-23 kinaba: if( b ) 5128eecc9f 2011-02-23 kinaba: eval( a,&t ), p = t; 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: p = a; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // 変数置き換え 5128eecc9f 2011-02-23 kinaba: *arg=""; 5128eecc9f 2011-02-23 kinaba: for( ; *p; *p && p++ ) 5128eecc9f 2011-02-23 kinaba: if( *p!='%' ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: *arg += *p; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: p++, *arg+=ele[(*p)&0xff]; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //------------------------- Minimum-Rythp環境 -------------------------// 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: bool kiRythpVM::exec_function( const kiVar& name, 5128eecc9f 2011-02-23 kinaba: const kiArray<char*>& a, const kiArray<bool>& b,int c, kiVar* r ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: // Minimum-Rythp で利用できる function は以下の通り。 5128eecc9f 2011-02-23 kinaba: // exec, while, if, let, +, -, *, /, =, !, between, mod 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: kiVar t; 5128eecc9f 2011-02-23 kinaba: int i,A,B,C; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (exec 実行文 実行文 ...) returns last-result 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: if( name=="exec" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: for( i=1; i<c; i++ ) 5128eecc9f 2011-02-23 kinaba: getarg( a[i],b[i],r ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (while 条件 繰り返す内容) returns last-result 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="while" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: // (特殊処理)複数回呼ぶコードなのでコピらなきゃ駄目。 5128eecc9f 2011-02-23 kinaba: int L1=ki_strlen(a[1]), L2=ki_strlen(a[2]); 5128eecc9f 2011-02-23 kinaba: char* tmp = new char[ 1 + (L1>L2 ? L1 : L2) ]; 5128eecc9f 2011-02-23 kinaba: while( getarg( ki_strcpy(tmp,a[1]), b[1], &t ), t.len() ) 5128eecc9f 2011-02-23 kinaba: getarg( ki_strcpy(tmp,a[2]), b[2], r ); 5128eecc9f 2011-02-23 kinaba: delete [] tmp; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (if 条件 真なら [偽なら]) returns executed-result 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="if" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( getarg( a[1],b[1],&t ), t.len() ) 5128eecc9f 2011-02-23 kinaba: getarg( a[2],b[2],r ); 5128eecc9f 2011-02-23 kinaba: else if( c>=4 ) 5128eecc9f 2011-02-23 kinaba: getarg( a[3],b[3],r ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (let 変数名 値 値 ...) returns new-value 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="let" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=2 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: *r = ""; 5128eecc9f 2011-02-23 kinaba: for( i=2; i<c; i++ ) 5128eecc9f 2011-02-23 kinaba: getarg( a[i],b[i],&t ), *r+=t; 5128eecc9f 2011-02-23 kinaba: ele[a[1][0]&0xff] = *r; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (= 値A 値B) returns A==B ? 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="=" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: *r = A==B ? "1" : ""; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (between 値A 値B 値C) returns A <= B <= C ? 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="between" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=4 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[3],b[3],&t), C=t.getInt(); 5128eecc9f 2011-02-23 kinaba: *r = (A<=B && B<=C) ? "1" : ""; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (! 値A [値B]) returns A!=B ? or !A 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="!" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=2 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: if( c==2 ) 5128eecc9f 2011-02-23 kinaba: *r = A==0 ? "1" : ""; 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: *r = A!=B ? "1" : ""; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (+ 値A 値B) returns A+B 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="+" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: r->setInt( A+B ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (- 値A 値B) returns A-B 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="-" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: r->setInt( A-B ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (* 値A 値B) returns A*B 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="*" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: r->setInt( A*B ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (/ 値A 値B) returns A/B 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="/" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: r->setInt( A/B ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: //-- (mod 値A 値B) returns A%B 5128eecc9f 2011-02-23 kinaba: //----- ---- --- -- - - - 5128eecc9f 2011-02-23 kinaba: else if( name=="mod" ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( c>=3 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: getarg(a[1],b[1],&t), A=t.getInt(); 5128eecc9f 2011-02-23 kinaba: getarg(a[2],b[2],&t), B=t.getInt(); 5128eecc9f 2011-02-23 kinaba: r->setInt( A%B ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: return true; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: