Artifact Content

Not logged in

Artifact 3294a27309b29b65d4b365b6ff5d3af5f05ed144


     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