Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
NyLPC_cMiMicVM.c
00001 /********************************************************************************* 00002 * PROJECT: MiMic 00003 * -------------------------------------------------------------------------------- 00004 * 00005 * This file is part of MiMic 00006 * Copyright (C)2011 Ryo Iizuka 00007 * 00008 * MiMic is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published 00010 * by the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 * 00021 * For further information please contact. 00022 * http://nyatla.jp/ 00023 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> 00024 * 00025 *********************************************************************************/ 00026 #include <ctype.h> 00027 #include <stdlib.h> 00028 #include "NyLPC_cMiMicVM_protected.h" 00029 00030 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist,NyLPC_TUInt32* o_code); 00031 00032 00033 00034 void NyLPC_cMiMicVM_initialize(NyLPC_TcMiMicVM_t* i_inst,struct NyLPC_TcMiMicVM_TEvent* i_handler) 00035 { 00036 NyLPC_Assert(i_inst!=NULL); 00037 NyLPC_Assert(i_handler!=NULL); 00038 NyLPC_Assert(i_handler->get_stream!=NULL); 00039 NyLPC_Assert(i_handler->put_stream!=NULL); 00040 NyLPC_Assert(i_handler->sleep!=NULL); 00041 i_inst->_event_handler=i_handler; 00042 return; 00043 } 00044 00045 00046 /** 00047 * 固定長命令+固定長データを実行します。 00048 * 関数の終了条件は、1.EXIT命令に到達する。2.インストラクションの終端に到達する。3.エラーが発生する。 00049 * 00050 */ 00051 NyLPC_TUInt32 NyLPC_cMiMicVM_run(NyLPC_TcMiMicVM_t* i_inst,const NyLPC_TUInt32* i_instruction,const NyLPC_TUInt16 i_size_of_instruction) 00052 { 00053 //データ部をgetstreamと連動させること。 00054 NyLPC_TUInt32 retcode=NyLPC_cMiMicVM_RESULT_OK; 00055 NyLPC_TUInt16 pc=0; 00056 NyLPC_TUInt8 proc_in_byte; 00057 if(i_size_of_instruction>0){ 00058 proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc),&retcode); 00059 pc+=proc_in_byte; 00060 //プログラムの終端に到達するか、0バイト処理の場合にブレーク。 00061 while(proc_in_byte>0 && pc<i_size_of_instruction){ 00062 proc_in_byte=process_instruction(i_inst,(const union NyLPC_TcMiMicVM_TInstruction*)(i_instruction+pc),&retcode); 00063 pc+=proc_in_byte; 00064 } 00065 } 00066 return retcode; 00067 } 00068 /** 00069 * 出力ストリームへ32ビット値を書き出す。 00070 */ 00071 NyLPC_TBool NyLPC_cMiMicVM_sput(NyLPC_TcMiMicVM_t* i_inst,NyLPC_TUInt32 i_val) 00072 { 00073 if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,i_val)){ 00074 return NyLPC_TBool_FALSE; 00075 } 00076 return NyLPC_TBool_TRUE; 00077 } 00078 /** 00079 * 入力ストリームから32ビット値を読み出す。 00080 */ 00081 NyLPC_TBool NyLPC_cMiMicVM_sget(NyLPC_TcMiMicVM_t* i_inst,NyLPC_TUInt32* o_val) 00082 { 00083 if(!i_inst->_event_handler->get_stream(i_inst->_event_handler,o_val)){ 00084 return NyLPC_TBool_FALSE; 00085 } 00086 return NyLPC_TBool_TRUE; 00087 } 00088 00089 00090 00091 /** 00092 * インストラクションを1個処理し、処理したバイト数を返す。 00093 * インストラクションの境界値はチェックされないので、コンパイル時にチェックしておくこと。 00094 * @return 00095 * 処理したインストラクションのワード数(UInt32単位)。 00096 * 終了した場合は0を返す。0を返したときは、ret_codeにMiMicVMの終了コードを返す。 00097 */ 00098 static NyLPC_TUInt8 process_instruction(NyLPC_TcMiMicVM_t* i_inst,const union NyLPC_TcMiMicVM_TInstruction* ist,NyLPC_TUInt32* o_code) 00099 { 00100 NyLPC_TUInt32 tret; 00101 switch(ist->op.opc){ 00102 case NyLPC_TcMiMicVM_OP_TYPE_AND: 00103 switch(ist->op.oprtype){ 00104 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00105 i_inst->wm[ist->wmwm_32.wm1]&=i_inst->wm[ist->wmwm_32.wm2]; 00106 break; 00107 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00108 i_inst->wm[ist->wmh32_64.wm]&=ist->wmh32_64.h32; 00109 break; 00110 default: 00111 NyLPC_OnErrorGoto(ERROR); 00112 } 00113 break; 00114 case NyLPC_TcMiMicVM_OP_TYPE_OR: 00115 switch(ist->op.oprtype){ 00116 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00117 i_inst->wm[ist->wmwm_32.wm1]|=i_inst->wm[ist->wmwm_32.wm2]; 00118 break; 00119 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00120 i_inst->wm[ist->wmh32_64.wm]|=ist->wmh32_64.h32; 00121 break; 00122 default: 00123 NyLPC_OnErrorGoto(ERROR); 00124 } 00125 break; 00126 case NyLPC_TcMiMicVM_OP_TYPE_XOR: 00127 switch(ist->op.oprtype){ 00128 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00129 i_inst->wm[ist->wmwm_32.wm1]^=i_inst->wm[ist->wmwm_32.wm2]; 00130 break; 00131 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00132 i_inst->wm[ist->wmh32_64.wm]^=ist->wmh32_64.h32; 00133 break; 00134 default: 00135 NyLPC_OnErrorGoto(ERROR); 00136 } 00137 break; 00138 case NyLPC_TcMiMicVM_OP_TYPE_NOT: 00139 switch(ist->op.oprtype){ 00140 case NyLPC_TcMiMicVM_OPR_TYPE_WM: 00141 i_inst->wm[ist->wm_32.wm]=~i_inst->wm[ist->wm_32.wm]; 00142 break; 00143 default: 00144 NyLPC_OnErrorGoto(ERROR); 00145 } 00146 break; 00147 case NyLPC_TcMiMicVM_OP_TYPE_SHL: 00148 switch(ist->op.oprtype){ 00149 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08: 00150 i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]<<ist->wmh08_32.h8; 00151 break; 00152 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00153 i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm1]<<i_inst->wm[ist->wmwm_32.wm2]; 00154 break; 00155 default: 00156 NyLPC_OnErrorGoto(ERROR); 00157 } 00158 break; 00159 case NyLPC_TcMiMicVM_OP_TYPE_SHR: 00160 switch(ist->op.oprtype){ 00161 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08: 00162 i_inst->wm[ist->wmh08_32.wm]=i_inst->wm[ist->wmh08_32.wm]>>ist->wmh08_32.h8; 00163 break; 00164 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00165 i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm1]>>i_inst->wm[ist->wmwm_32.wm2]; 00166 break; 00167 default: 00168 NyLPC_OnErrorGoto(ERROR); 00169 } 00170 break; 00171 case NyLPC_TcMiMicVM_OP_TYPE_ADD: 00172 switch(ist->op.oprtype){ 00173 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00174 i_inst->wm[ist->wmwm_32.wm1]+=i_inst->wm[ist->wmwm_32.wm2]; 00175 break; 00176 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00177 i_inst->wm[ist->wmh32_64.wm]+=ist->wmh32_64.h32; 00178 break; 00179 default: 00180 NyLPC_OnErrorGoto(ERROR); 00181 } 00182 break; 00183 case NyLPC_TcMiMicVM_OP_TYPE_SUB: 00184 switch(ist->op.oprtype){ 00185 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00186 i_inst->wm[ist->wmwm_32.wm1]-=i_inst->wm[ist->wmwm_32.wm2]; 00187 break; 00188 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00189 i_inst->wm[ist->wmh32_64.wm]-=ist->wmh32_64.h32; 00190 break; 00191 default: 00192 NyLPC_OnErrorGoto(ERROR); 00193 } 00194 break; 00195 case NyLPC_TcMiMicVM_OP_TYPE_MUL: 00196 switch(ist->op.oprtype){ 00197 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00198 i_inst->wm[ist->wmwm_32.wm1]*=i_inst->wm[ist->wmwm_32.wm2]; 00199 break; 00200 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00201 i_inst->wm[ist->wmh32_64.wm]*=ist->wmh32_64.h32; 00202 break; 00203 default: 00204 NyLPC_OnErrorGoto(ERROR); 00205 } 00206 break; 00207 case NyLPC_TcMiMicVM_OP_TYPE_MGET: 00208 switch(ist->op.oprtype){ 00209 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00210 i_inst->wm[ist->wmh32_64.wm]=*((NyLPC_TUInt32*)(ist->wmh32_64.h32)); 00211 break; 00212 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00213 i_inst->wm[ist->wmwm_32.wm1]=*((NyLPC_TUInt32*)(i_inst->wm[ist->wmwm_32.wm2])); 00214 break; 00215 default: 00216 NyLPC_OnErrorGoto(ERROR); 00217 } 00218 break; 00219 case NyLPC_TcMiMicVM_OP_TYPE_MPUT: 00220 switch(ist->op.oprtype){ 00221 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00222 *((NyLPC_TUInt32*)(ist->wmh32_64.h32))=i_inst->wm[ist->wmh32_64.wm]; 00223 break; 00224 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00225 *((NyLPC_TUInt32*)(i_inst->wm[ist->wmwm_32.wm2]))=i_inst->wm[ist->wmwm_32.wm1]; 00226 break; 00227 default: 00228 NyLPC_OnErrorGoto(ERROR); 00229 } 00230 break; 00231 case NyLPC_TcMiMicVM_OP_TYPE_SGET: 00232 switch(ist->op.oprtype){ 00233 case NyLPC_TcMiMicVM_OPR_TYPE_WM: 00234 if(!i_inst->_event_handler->get_stream(i_inst->_event_handler,&(i_inst->wm[ist->wm_32.wm]))){ 00235 NyLPC_OnErrorGoto(ERROR); 00236 } 00237 break; 00238 default: 00239 NyLPC_OnErrorGoto(ERROR); 00240 } 00241 break; 00242 case NyLPC_TcMiMicVM_OP_TYPE_SPUT: 00243 switch(ist->op.oprtype){ 00244 case NyLPC_TcMiMicVM_OPR_TYPE_WM: 00245 if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,i_inst->wm[ist->wm_32.wm])){ 00246 NyLPC_OnErrorGoto(ERROR); 00247 } 00248 break; 00249 case NyLPC_TcMiMicVM_OPR_TYPE_H32: 00250 if(!i_inst->_event_handler->put_stream(i_inst->_event_handler,ist->h32_64.h32)){ 00251 NyLPC_OnErrorGoto(ERROR); 00252 } 00253 break; 00254 default: 00255 NyLPC_OnErrorGoto(ERROR); 00256 } 00257 break; 00258 case NyLPC_TcMiMicVM_OP_TYPE_LD: 00259 switch(ist->op.oprtype){ 00260 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00261 i_inst->wm[ist->wmwm_32.wm1]=i_inst->wm[ist->wmwm_32.wm2]; 00262 break; 00263 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00264 i_inst->wm[ist->wmh32_64.wm]=ist->wmh32_64.h32; 00265 break; 00266 default: 00267 NyLPC_OnErrorGoto(ERROR); 00268 } 00269 break; 00270 case NyLPC_TcMiMicVM_OP_TYPE_NOP: 00271 switch(ist->op.oprtype){ 00272 case NyLPC_TcMiMicVM_OPR_TYPE_NONE: 00273 break; 00274 case NyLPC_TcMiMicVM_OPR_TYPE_H08: 00275 i_inst->_event_handler->sleep(i_inst->_event_handler,ist->h8_32.h8); 00276 break; 00277 default: 00278 NyLPC_OnErrorGoto(ERROR); 00279 } 00280 break; 00281 //native call 00282 case NyLPC_TcMiMicVM_OP_TYPE_CALL: 00283 switch(ist->op.oprtype){ 00284 case NyLPC_TcMiMicVM_OPR_TYPE_WM: 00285 tret=i_inst->_event_handler->native_call(i_inst->_event_handler,i_inst->wm[ist->wm_32.wm],i_inst); 00286 if(!NyLPC_cMiMicVM_RESULT_isOK(tret)){ 00287 *o_code=tret; 00288 NyLPC_OnErrorGoto(ERROR_INHERIT);//エラー継承 00289 } 00290 break; 00291 case NyLPC_TcMiMicVM_OPR_TYPE_H32: 00292 tret=i_inst->_event_handler->native_call(i_inst->_event_handler,ist->h32_64.h32,i_inst); 00293 if(!NyLPC_cMiMicVM_RESULT_isOK(tret)){ 00294 *o_code=tret; 00295 NyLPC_OnErrorGoto(ERROR_INHERIT);//エラー継承 00296 } 00297 break; 00298 default: 00299 NyLPC_OnErrorGoto(ERROR); 00300 } 00301 break; 00302 case NyLPC_TcMiMicVM_OP_TYPE_EXIT: 00303 *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き 00304 return 0; 00305 default: 00306 NyLPC_OnErrorGoto(ERROR); 00307 } 00308 //実行したコードのワード長を返す。 00309 switch(ist->op.oprtype){ 00310 case NyLPC_TcMiMicVM_OPR_TYPE_NONE: 00311 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM: 00312 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08: 00313 case NyLPC_TcMiMicVM_OPR_TYPE_WM: 00314 case NyLPC_TcMiMicVM_OPR_TYPE_H08: 00315 case NyLPC_TcMiMicVM_OPR_TYPE_H16: 00316 *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き 00317 return 1; 00318 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H16: 00319 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32: 00320 case NyLPC_TcMiMicVM_OPR_TYPE_H32: 00321 *o_code=NyLPC_cMiMicVM_RESULT_OK;//OKに上書き 00322 return 2; 00323 } 00324 ERROR: 00325 *o_code=NyLPC_cMiMicVM_RESULT_RUNTIME_NG;//ランタイムNG 00326 ERROR_INHERIT: 00327 return 0; 00328 } 00329 00330 #define TEST 00331 #ifndef TEST 00332 00333 #include "NyLPC_cMiMicTxtCompiler.h" 00334 void main(void) 00335 { 00336 struct NyLPC_TcMiMicVM_TEvent eh; 00337 NyLPC_TUInt32 ap; 00338 NyLPC_TcMiMicVM_t vm; 00339 struct NyLPC_TCharArrayPtr bc; 00340 NyLPC_TcMiMicTxtCompiler_t inst; 00341 struct NyLPC_TUInt32ArrayPtr bin; 00342 char BC[1024]; 00343 int ist_len; 00344 00345 NyLPC_TUInt16 l,bl; 00346 NyLPC_TUInt32 obuf[1024]; 00347 NyLPC_cMiMicBcCompiler_initialize(&inst); 00348 sprintf(BC,"AA0102AB0100000001AE0203AF0200000003AI0304AJ0300000004AM07BA0505BE0607CA0304CB0300000005CE0304CF0300000005CI0304CJ0300000005ZA.E",&ap,&ap); 00349 bc.ptr=(char* )BC; 00350 bc.len=strlen(BC); 00351 bin.ptr=obuf; 00352 bin.len=100; 00353 ist_len=0; 00354 00355 for(;;){ 00356 00357 switch(NyLPC_cMiMicBcCompiler_compileFragment(&inst,&bc,&bin,&bl,&l)) 00358 { 00359 case NyLPC_TcMiMicTxtCompiler_RET_OK: 00360 //命令確定。 00361 NyLPC_TCharArrayPtr_seek(&bc,l); 00362 ist_len+=bl; 00363 break; 00364 case NyLPC_TcMiMicTxtCompiler_RET_OK_END: 00365 //命令終端 00366 NyLPC_cMiMicVM_initialize(&vm,&eh); 00367 if(!NyLPC_cMiMicVM_run(&vm,obuf,ist_len)){ 00368 printf("エンダァ"); 00369 } 00370 printf("OK"); 00371 break; 00372 case NyLPC_TcMiMicTxtCompiler_RET_CONTINUE: 00373 //蓄積中。 00374 NyLPC_TCharArrayPtr_seek(&bc,l); 00375 break; 00376 case NyLPC_TcMiMicTxtCompiler_RET_NG: 00377 printf("エラー"); 00378 return; 00379 default: 00380 break; 00381 } 00382 } 00383 } 00384 #endif
Generated on Tue Jul 12 2022 16:22:58 by
