This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Fork of libMiMic by Ryo Iizuka

Committer:
nyatla
Date:
Wed Mar 27 12:07:47 2013 +0000
Revision:
2:b96c1e90d120
???????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 2:b96c1e90d120 1 /*********************************************************************************
nyatla 2:b96c1e90d120 2 * PROJECT: MiMic
nyatla 2:b96c1e90d120 3 * --------------------------------------------------------------------------------
nyatla 2:b96c1e90d120 4 *
nyatla 2:b96c1e90d120 5 * This file is part of MiMic
nyatla 2:b96c1e90d120 6 * Copyright (C)2011 Ryo Iizuka
nyatla 2:b96c1e90d120 7 *
nyatla 2:b96c1e90d120 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 2:b96c1e90d120 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 2:b96c1e90d120 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 2:b96c1e90d120 11 * (at your option) any later version.
nyatla 2:b96c1e90d120 12 *
nyatla 2:b96c1e90d120 13 * This program is distributed in the hope that it will be useful,
nyatla 2:b96c1e90d120 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 2:b96c1e90d120 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 2:b96c1e90d120 16 * GNU General Public License for more details.
nyatla 2:b96c1e90d120 17 *
nyatla 2:b96c1e90d120 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 2:b96c1e90d120 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 2:b96c1e90d120 20 *
nyatla 2:b96c1e90d120 21 * For further information please contact.
nyatla 2:b96c1e90d120 22 * http://nyatla.jp/
nyatla 2:b96c1e90d120 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 2:b96c1e90d120 24 *
nyatla 2:b96c1e90d120 25 *********************************************************************************/
nyatla 2:b96c1e90d120 26 #include <ctype.h>
nyatla 2:b96c1e90d120 27 #include <stdlib.h>
nyatla 2:b96c1e90d120 28 #include "NyLPC_cMiMicTxtCompiler.h"
nyatla 2:b96c1e90d120 29 #include "NyLPC_cMiMicVM_protected.h"
nyatla 2:b96c1e90d120 30 #include "NyLPC_mimicvm_utils_protected.h"
nyatla 2:b96c1e90d120 31
nyatla 2:b96c1e90d120 32
nyatla 2:b96c1e90d120 33 struct TInstructionDef
nyatla 2:b96c1e90d120 34 {
nyatla 2:b96c1e90d120 35 /** MiMicBCのオペコード */
nyatla 2:b96c1e90d120 36 const char* bcopcode;
nyatla 2:b96c1e90d120 37 /** インストラクションID */
nyatla 2:b96c1e90d120 38 NyLPC_TcMiMicVM_OP_TYPE opid;
nyatla 2:b96c1e90d120 39 /** オペコードのタイプ */
nyatla 2:b96c1e90d120 40 NyLPC_TcMiMicVM_OPR_TYPE optype;
nyatla 2:b96c1e90d120 41 };
nyatla 2:b96c1e90d120 42 static NyLPC_TBool bc2opc(const NyLPC_TChar* i_char,NyLPC_TcMiMicVM_OP_TYPE* o_opc,NyLPC_TcMiMicVM_OPR_TYPE* o_opt);
nyatla 2:b96c1e90d120 43 static NyLPC_TBool bc2ctrlc(const NyLPC_TChar* i_char,NyLPC_TcMiMicVM_OP_TYPE* o_opc,NyLPC_TcMiMicVM_OPR_TYPE* o_opt);
nyatla 2:b96c1e90d120 44 static NyLPC_TBool txt2UInt(const NyLPC_TChar* i_txt,NyLPC_TUInt8 i_num,void* out);
nyatla 2:b96c1e90d120 45 static NyLPC_TBool txt2WMId(const NyLPC_TChar* i_txt,NyLPC_TUInt8* out);
nyatla 2:b96c1e90d120 46 static void NyLPC_TcMiMicVM_OPR_TYPE_getOpInfo(NyLPC_TcMiMicVM_OPR_TYPE i_type,NyLPC_TUInt8* oprbc_len,NyLPC_TUInt8* o_istlen);
nyatla 2:b96c1e90d120 47
nyatla 2:b96c1e90d120 48
nyatla 2:b96c1e90d120 49 void NyLPC_cMiMicTxtCompiler_initialize(NyLPC_TcMiMicTxtCompiler_t* i_inst)
nyatla 2:b96c1e90d120 50 {
nyatla 2:b96c1e90d120 51 i_inst->out_buf=NULL;
nyatla 2:b96c1e90d120 52 i_inst->st=NyLPC_TcMiMicTxtCompiler_ST_OPC;
nyatla 2:b96c1e90d120 53 i_inst->tmp_len=0;
nyatla 2:b96c1e90d120 54 }
nyatla 2:b96c1e90d120 55
nyatla 2:b96c1e90d120 56
nyatla 2:b96c1e90d120 57
nyatla 2:b96c1e90d120 58 #define NyLPC_TcMiMicTxtCompiler_ST_OPC 0x01 //OPをパース中
nyatla 2:b96c1e90d120 59 #define NyLPC_TcMiMicTxtCompiler_ST_OPR 0x02 //オペランドを解析中
nyatla 2:b96c1e90d120 60 #define NyLPC_TcMiMicTxtCompiler_ST_CTR 0x03 //制御パラメータを解析中
nyatla 2:b96c1e90d120 61 #define NyLPC_TcMiMicTxtCompiler_ST_OK 0x04 //パースを完了した。(.EMD検出)
nyatla 2:b96c1e90d120 62 #define NyLPC_TcMiMicTxtCompiler_ST_NG 0xff //パースでエラーが発生ウェーイ
nyatla 2:b96c1e90d120 63
nyatla 2:b96c1e90d120 64
nyatla 2:b96c1e90d120 65
nyatla 2:b96c1e90d120 66 /**
nyatla 2:b96c1e90d120 67 * バイトコードフラグメントから1命令をコンパイルして、i_binへ出力します。
nyatla 2:b96c1e90d120 68 * バイトコードは、バイナリ値に変換されます。
nyatla 2:b96c1e90d120 69 * バイナリ値は、MiMicVMの実行形式です。
nyatla 2:b96c1e90d120 70 * @param i_bin
nyatla 2:b96c1e90d120 71 * コンパイルしたBCを格納する配列を指定します。
nyatla 2:b96c1e90d120 72 * 関数が成功した場合、配列のポインターは追加したBCの数だけ進行します。
nyatla 2:b96c1e90d120 73 * @return
nyatla 2:b96c1e90d120 74 * 実行結果を返します。NyLPC_TcMiMicTxtCompiler_RET_OKの場合に、i_binへo_bin_lenの長さのインストラクションを出力します。
nyatla 2:b96c1e90d120 75 *
nyatla 2:b96c1e90d120 76 */
nyatla 2:b96c1e90d120 77 NyLPC_TcMiMicTxtCompiler_RET NyLPC_cMiMicTxtCompiler_compileFragment(NyLPC_TcMiMicTxtCompiler_t* i_inst,const struct NyLPC_TCharArrayPtr* i_bc,struct NyLPC_TUInt32ArrayPtr* i_bin,NyLPC_TUInt16* o_bin_len,NyLPC_TUInt16* o_parsed_bc)
nyatla 2:b96c1e90d120 78 {
nyatla 2:b96c1e90d120 79 union NyLPC_TcMiMicVM_TInstruction* wptr;
nyatla 2:b96c1e90d120 80 int i;
nyatla 2:b96c1e90d120 81 for(i=0;i<i_bc->len;i++)
nyatla 2:b96c1e90d120 82 {
nyatla 2:b96c1e90d120 83 switch(i_inst->st){
nyatla 2:b96c1e90d120 84 case NyLPC_TcMiMicTxtCompiler_ST_OPC:
nyatla 2:b96c1e90d120 85 if(i_inst->tmp_len>2){
nyatla 2:b96c1e90d120 86 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 87 }
nyatla 2:b96c1e90d120 88 i_inst->tmp[i_inst->tmp_len]=*(i_bc->ptr+i);
nyatla 2:b96c1e90d120 89 i_inst->tmp_len++;
nyatla 2:b96c1e90d120 90 if(i_inst->tmp_len==2){
nyatla 2:b96c1e90d120 91 //[A-Z]{2}がそろった。命令コードか制御命令か判定
nyatla 2:b96c1e90d120 92 if(bc2opc(i_inst->tmp,&(i_inst->_current_opc),&(i_inst->_current_oprtype))){
nyatla 2:b96c1e90d120 93 //命令コードならインストラクションの情報をもらってくる。
nyatla 2:b96c1e90d120 94 NyLPC_TcMiMicVM_OPR_TYPE_getOpInfo(i_inst->_current_oprtype,&i_inst->_oprbc_len,&i_inst->_inst_len);
nyatla 2:b96c1e90d120 95 //オペランドが無ければ、命令確定。
nyatla 2:b96c1e90d120 96 if(i_inst->_oprbc_len<=0){
nyatla 2:b96c1e90d120 97 //書込みポインタ保管
nyatla 2:b96c1e90d120 98 wptr=(union NyLPC_TcMiMicVM_TInstruction*)i_bin->ptr;
nyatla 2:b96c1e90d120 99 //バッファのシーク
nyatla 2:b96c1e90d120 100 if(!NyLPC_TUInt32ArrayPtr_seek(i_bin,1)){
nyatla 2:b96c1e90d120 101 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 102 }
nyatla 2:b96c1e90d120 103 //インストラクションの出力と処理したBC長の計算
nyatla 2:b96c1e90d120 104 wptr->op.opc=i_inst->_current_opc;
nyatla 2:b96c1e90d120 105 wptr->op.oprtype=i_inst->_current_oprtype;
nyatla 2:b96c1e90d120 106 *o_parsed_bc=i+1; //パースしたBCの長さ
nyatla 2:b96c1e90d120 107 *o_bin_len=i_inst->_inst_len;
nyatla 2:b96c1e90d120 108 //解析バッファの長さをリセットして、次のBCブロックのパース準備
nyatla 2:b96c1e90d120 109 i_inst->tmp_len=0;
nyatla 2:b96c1e90d120 110 return NyLPC_TcMiMicTxtCompiler_RET_OK;//命令確定。
nyatla 2:b96c1e90d120 111 }
nyatla 2:b96c1e90d120 112 //オペランドがあるなら、パース対象を変更。
nyatla 2:b96c1e90d120 113 i_inst->tmp_len=0;
nyatla 2:b96c1e90d120 114 i_inst->st=NyLPC_TcMiMicTxtCompiler_ST_OPR;
nyatla 2:b96c1e90d120 115 }else if(bc2ctrlc(i_inst->tmp,&(i_inst->_current_opc),&(i_inst->_current_oprtype))){
nyatla 2:b96c1e90d120 116 //命令コードならインストラクションの情報をもらってくる。
nyatla 2:b96c1e90d120 117 NyLPC_TcMiMicVM_OPR_TYPE_getOpInfo(i_inst->_current_oprtype,&i_inst->_oprbc_len,&i_inst->_inst_len);
nyatla 2:b96c1e90d120 118 //制御コードの解析
nyatla 2:b96c1e90d120 119 if(i_inst->_oprbc_len>0){
nyatla 2:b96c1e90d120 120 //パラメータのある制御命令未定義だからエラー。
nyatla 2:b96c1e90d120 121 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 122 }
nyatla 2:b96c1e90d120 123 //END制御命令?
nyatla 2:b96c1e90d120 124 if(i_inst->_current_opc==NyLPC_TcMiMicVM_CP_TYPE_END){
nyatla 2:b96c1e90d120 125 *o_bin_len=0;
nyatla 2:b96c1e90d120 126 *o_parsed_bc=i+1; //パースしたBCの長さ
nyatla 2:b96c1e90d120 127 i_inst->tmp_len=0;
nyatla 2:b96c1e90d120 128 return NyLPC_TcMiMicTxtCompiler_RET_OK_END;//命令確定。(パース完了)
nyatla 2:b96c1e90d120 129 }
nyatla 2:b96c1e90d120 130 //END制御命令以外ならエラー
nyatla 2:b96c1e90d120 131 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 132 }else{
nyatla 2:b96c1e90d120 133 //不明な命令
nyatla 2:b96c1e90d120 134 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 135 }
nyatla 2:b96c1e90d120 136 }
nyatla 2:b96c1e90d120 137 break;
nyatla 2:b96c1e90d120 138 case NyLPC_TcMiMicTxtCompiler_ST_CTR:
nyatla 2:b96c1e90d120 139 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 140 case NyLPC_TcMiMicTxtCompiler_ST_OPR:
nyatla 2:b96c1e90d120 141 //オペランド蓄積.
nyatla 2:b96c1e90d120 142 i_inst->tmp[i_inst->tmp_len]=*(i_bc->ptr+i);
nyatla 2:b96c1e90d120 143 i_inst->tmp_len++;
nyatla 2:b96c1e90d120 144 //オペランド長さになるまで値を追記
nyatla 2:b96c1e90d120 145 if(i_inst->_oprbc_len==i_inst->tmp_len){
nyatla 2:b96c1e90d120 146 //書込みポインタ保管
nyatla 2:b96c1e90d120 147 wptr=(union NyLPC_TcMiMicVM_TInstruction*)i_bin->ptr;
nyatla 2:b96c1e90d120 148 //シーク
nyatla 2:b96c1e90d120 149 if(!NyLPC_TUInt32ArrayPtr_seek(i_bin,i_inst->_inst_len)){
nyatla 2:b96c1e90d120 150 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 151 }
nyatla 2:b96c1e90d120 152 wptr->op.opc=i_inst->_current_opc;
nyatla 2:b96c1e90d120 153 wptr->op.oprtype=i_inst->_current_oprtype;
nyatla 2:b96c1e90d120 154 //オペランドの変換処理
nyatla 2:b96c1e90d120 155 switch(i_inst->_current_oprtype){
nyatla 2:b96c1e90d120 156 case NyLPC_TcMiMicVM_OPR_TYPE_WM_WM:
nyatla 2:b96c1e90d120 157 if(!( txt2WMId(i_inst->tmp,&(wptr->wmwm_32.wm1)) &&
nyatla 2:b96c1e90d120 158 txt2WMId(i_inst->tmp+2,&(wptr->wmwm_32.wm2))))
nyatla 2:b96c1e90d120 159 {
nyatla 2:b96c1e90d120 160 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 161 }
nyatla 2:b96c1e90d120 162 break;
nyatla 2:b96c1e90d120 163 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H08:
nyatla 2:b96c1e90d120 164 if(!( txt2WMId(i_inst->tmp,&(wptr->wmh08_32.wm)) &&
nyatla 2:b96c1e90d120 165 txt2UInt(i_inst->tmp+2,2,&(wptr->wmh08_32.h8))))
nyatla 2:b96c1e90d120 166 {
nyatla 2:b96c1e90d120 167 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 168 }
nyatla 2:b96c1e90d120 169 break;
nyatla 2:b96c1e90d120 170 case NyLPC_TcMiMicVM_OPR_TYPE_WM_H32:
nyatla 2:b96c1e90d120 171 if(!( txt2WMId(i_inst->tmp,&(wptr->wmh32_64.wm)) &&
nyatla 2:b96c1e90d120 172 txt2UInt(i_inst->tmp+2,8,&(wptr->wmh32_64.h32)))){
nyatla 2:b96c1e90d120 173 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 174 }
nyatla 2:b96c1e90d120 175 break;
nyatla 2:b96c1e90d120 176 case NyLPC_TcMiMicVM_OPR_TYPE_WM:
nyatla 2:b96c1e90d120 177 if(!txt2WMId(i_inst->tmp,&(wptr->wm_32.wm))){
nyatla 2:b96c1e90d120 178 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 179 }
nyatla 2:b96c1e90d120 180 break;
nyatla 2:b96c1e90d120 181 case NyLPC_TcMiMicVM_OPR_TYPE_H32:
nyatla 2:b96c1e90d120 182 if(!txt2UInt(i_inst->tmp,8,&(wptr->h32_64.h32))){
nyatla 2:b96c1e90d120 183 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 184 }
nyatla 2:b96c1e90d120 185 break;
nyatla 2:b96c1e90d120 186 case NyLPC_TcMiMicVM_OPR_TYPE_H08:
nyatla 2:b96c1e90d120 187 if(!txt2UInt(i_inst->tmp,2,&(wptr->h8_32.h8)))
nyatla 2:b96c1e90d120 188 {
nyatla 2:b96c1e90d120 189 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 190 }
nyatla 2:b96c1e90d120 191 break;
nyatla 2:b96c1e90d120 192 default:
nyatla 2:b96c1e90d120 193 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 194 }
nyatla 2:b96c1e90d120 195 //OPR解析成功。パースしたブロックサイズの計算。
nyatla 2:b96c1e90d120 196 *o_parsed_bc=i+1; //パースしたBCの長さ
nyatla 2:b96c1e90d120 197 *o_bin_len=i_inst->_inst_len;
nyatla 2:b96c1e90d120 198 i_inst->tmp_len=0;
nyatla 2:b96c1e90d120 199 i_inst->st=NyLPC_TcMiMicTxtCompiler_ST_OPC;
nyatla 2:b96c1e90d120 200 return NyLPC_TcMiMicTxtCompiler_RET_OK;
nyatla 2:b96c1e90d120 201 }
nyatla 2:b96c1e90d120 202 break;
nyatla 2:b96c1e90d120 203 default:
nyatla 2:b96c1e90d120 204 NyLPC_OnErrorGoto(ERROR);
nyatla 2:b96c1e90d120 205 }
nyatla 2:b96c1e90d120 206 }
nyatla 2:b96c1e90d120 207 *o_bin_len=0;
nyatla 2:b96c1e90d120 208 *o_parsed_bc=i_bc->len;
nyatla 2:b96c1e90d120 209 return NyLPC_TcMiMicTxtCompiler_RET_CONTINUE;
nyatla 2:b96c1e90d120 210 ERROR:
nyatla 2:b96c1e90d120 211 i_inst->st=NyLPC_TcMiMicTxtCompiler_ST_NG;
nyatla 2:b96c1e90d120 212 return NyLPC_TcMiMicTxtCompiler_RET_NG;
nyatla 2:b96c1e90d120 213 }
nyatla 2:b96c1e90d120 214
nyatla 2:b96c1e90d120 215
nyatla 2:b96c1e90d120 216
nyatla 2:b96c1e90d120 217 /**
nyatla 2:b96c1e90d120 218 * フラグメント入力のMiMicBCをコンパイルします。
nyatla 2:b96c1e90d120 219 * この関数は、1文字のフラグメントMiMicBCをコンパイラに入力します。
nyatla 2:b96c1e90d120 220 * @param i_bin
nyatla 2:b96c1e90d120 221 * コンパイルしたBCを格納する配列を指定します。
nyatla 2:b96c1e90d120 222 * 関数が成功した場合、配列のポインターは追加したBCの数だけ進行します。
nyatla 2:b96c1e90d120 223 * @return
nyatla 2:b96c1e90d120 224 * 実行結果を返します。TRUEのときは、ステータスをチェックしてください。
nyatla 2:b96c1e90d120 225 *
nyatla 2:b96c1e90d120 226 */
nyatla 2:b96c1e90d120 227 NyLPC_TcMiMicTxtCompiler_RET NyLPC_cMiMicTxtCompiler_compileFragment2(NyLPC_TcMiMicTxtCompiler_t* i_inst,NyLPC_TChar i_bc,struct NyLPC_TUInt32ArrayPtr* i_bin,NyLPC_TUInt16* o_bin_len)
nyatla 2:b96c1e90d120 228 {
nyatla 2:b96c1e90d120 229 struct NyLPC_TCharArrayPtr bc;
nyatla 2:b96c1e90d120 230 NyLPC_TUInt16 bc_len;
nyatla 2:b96c1e90d120 231 bc.ptr=&i_bc;
nyatla 2:b96c1e90d120 232 bc.len=1;
nyatla 2:b96c1e90d120 233 return NyLPC_cMiMicTxtCompiler_compileFragment(i_inst,&bc,i_bin,o_bin_len,&bc_len);
nyatla 2:b96c1e90d120 234 }
nyatla 2:b96c1e90d120 235
nyatla 2:b96c1e90d120 236
nyatla 2:b96c1e90d120 237
nyatla 2:b96c1e90d120 238 /**
nyatla 2:b96c1e90d120 239 * 2バイトのバイトコードを、制御コードに変換します。
nyatla 2:b96c1e90d120 240 */
nyatla 2:b96c1e90d120 241 static NyLPC_TBool bc2ctrlc(const NyLPC_TChar* i_char,NyLPC_TcMiMicVM_OP_TYPE* o_opc,NyLPC_TcMiMicVM_OPR_TYPE* o_opt)
nyatla 2:b96c1e90d120 242 {
nyatla 2:b96c1e90d120 243 //バイトコード変換の為のテーブル
nyatla 2:b96c1e90d120 244 const struct TInstructionDef _bc_type_tbl[]=
nyatla 2:b96c1e90d120 245 {
nyatla 2:b96c1e90d120 246 //制御命令
nyatla 2:b96c1e90d120 247 {".E",NyLPC_TcMiMicVM_CP_TYPE_END,NyLPC_TcMiMicVM_OPR_TYPE_NONE},
nyatla 2:b96c1e90d120 248 {NULL}
nyatla 2:b96c1e90d120 249 };
nyatla 2:b96c1e90d120 250 int i;
nyatla 2:b96c1e90d120 251 for(i=0;_bc_type_tbl[i].bcopcode!=NULL;i++){
nyatla 2:b96c1e90d120 252 //2バイト一致?
nyatla 2:b96c1e90d120 253 if((*i_char==_bc_type_tbl[i].bcopcode[0])&&(*(i_char+1)==_bc_type_tbl[i].bcopcode[1])){
nyatla 2:b96c1e90d120 254 *o_opc=_bc_type_tbl[i].opid;
nyatla 2:b96c1e90d120 255 *o_opt=_bc_type_tbl[i].optype;
nyatla 2:b96c1e90d120 256 return NyLPC_TBool_TRUE;
nyatla 2:b96c1e90d120 257 }
nyatla 2:b96c1e90d120 258 }
nyatla 2:b96c1e90d120 259 return NyLPC_TBool_FALSE;
nyatla 2:b96c1e90d120 260 }
nyatla 2:b96c1e90d120 261
nyatla 2:b96c1e90d120 262
nyatla 2:b96c1e90d120 263 /**
nyatla 2:b96c1e90d120 264 * 2バイトのバイトコードを、命令定義に変換します。
nyatla 2:b96c1e90d120 265 */
nyatla 2:b96c1e90d120 266 static NyLPC_TBool bc2opc(const NyLPC_TChar* i_char,NyLPC_TcMiMicVM_OP_TYPE* o_opc,NyLPC_TcMiMicVM_OPR_TYPE* o_opt)
nyatla 2:b96c1e90d120 267 {
nyatla 2:b96c1e90d120 268 //バイトコード変換の為のテーブル
nyatla 2:b96c1e90d120 269 const struct TInstructionDef _bc_type_tbl[]=
nyatla 2:b96c1e90d120 270 {
nyatla 2:b96c1e90d120 271 {"AA",NyLPC_TcMiMicVM_OP_TYPE_AND,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 272 {"AB",NyLPC_TcMiMicVM_OP_TYPE_AND,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 273 {"AE",NyLPC_TcMiMicVM_OP_TYPE_OR,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 274 {"AF",NyLPC_TcMiMicVM_OP_TYPE_OR,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 275 {"AI",NyLPC_TcMiMicVM_OP_TYPE_XOR,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 276 {"AJ",NyLPC_TcMiMicVM_OP_TYPE_XOR,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 277 {"AM",NyLPC_TcMiMicVM_OP_TYPE_NOT,NyLPC_TcMiMicVM_OPR_TYPE_WM},
nyatla 2:b96c1e90d120 278
nyatla 2:b96c1e90d120 279 {"BA",NyLPC_TcMiMicVM_OP_TYPE_SHL,NyLPC_TcMiMicVM_OPR_TYPE_WM_H08},
nyatla 2:b96c1e90d120 280 {"BB",NyLPC_TcMiMicVM_OP_TYPE_SHL,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 281 {"BE",NyLPC_TcMiMicVM_OP_TYPE_SHR,NyLPC_TcMiMicVM_OPR_TYPE_WM_H08},
nyatla 2:b96c1e90d120 282 {"BF",NyLPC_TcMiMicVM_OP_TYPE_SHR,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 283
nyatla 2:b96c1e90d120 284 {"CA",NyLPC_TcMiMicVM_OP_TYPE_ADD,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 285 {"CB",NyLPC_TcMiMicVM_OP_TYPE_ADD,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 286 {"CE",NyLPC_TcMiMicVM_OP_TYPE_SUB,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 287 {"CF",NyLPC_TcMiMicVM_OP_TYPE_SUB,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 288 {"CI",NyLPC_TcMiMicVM_OP_TYPE_MUL,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 289 {"CJ",NyLPC_TcMiMicVM_OP_TYPE_MUL,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 290
nyatla 2:b96c1e90d120 291 {"DA",NyLPC_TcMiMicVM_OP_TYPE_MGET,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 292 {"DB",NyLPC_TcMiMicVM_OP_TYPE_MGET,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 293 {"DE",NyLPC_TcMiMicVM_OP_TYPE_MPUT,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 294 {"DF",NyLPC_TcMiMicVM_OP_TYPE_MPUT,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 295
nyatla 2:b96c1e90d120 296 {"EA",NyLPC_TcMiMicVM_OP_TYPE_SGET,NyLPC_TcMiMicVM_OPR_TYPE_WM},
nyatla 2:b96c1e90d120 297 {"EE",NyLPC_TcMiMicVM_OP_TYPE_SPUT,NyLPC_TcMiMicVM_OPR_TYPE_WM},
nyatla 2:b96c1e90d120 298 {"EF",NyLPC_TcMiMicVM_OP_TYPE_SPUT,NyLPC_TcMiMicVM_OPR_TYPE_H32},
nyatla 2:b96c1e90d120 299
nyatla 2:b96c1e90d120 300 {"FA",NyLPC_TcMiMicVM_OP_TYPE_LD,NyLPC_TcMiMicVM_OPR_TYPE_WM_WM},
nyatla 2:b96c1e90d120 301 {"FB",NyLPC_TcMiMicVM_OP_TYPE_LD,NyLPC_TcMiMicVM_OPR_TYPE_WM_H32},
nyatla 2:b96c1e90d120 302
nyatla 2:b96c1e90d120 303 {"ZA",NyLPC_TcMiMicVM_OP_TYPE_NOP,NyLPC_TcMiMicVM_OPR_TYPE_NONE},
nyatla 2:b96c1e90d120 304 {"ZB",NyLPC_TcMiMicVM_OP_TYPE_NOP,NyLPC_TcMiMicVM_OPR_TYPE_H08},
nyatla 2:b96c1e90d120 305
nyatla 2:b96c1e90d120 306 {"ZE",NyLPC_TcMiMicVM_OP_TYPE_CALL,NyLPC_TcMiMicVM_OPR_TYPE_WM},
nyatla 2:b96c1e90d120 307 {"ZF",NyLPC_TcMiMicVM_OP_TYPE_CALL,NyLPC_TcMiMicVM_OPR_TYPE_H32},
nyatla 2:b96c1e90d120 308
nyatla 2:b96c1e90d120 309
nyatla 2:b96c1e90d120 310 {"ZZ",NyLPC_TcMiMicVM_OP_TYPE_EXIT,NyLPC_TcMiMicVM_OPR_TYPE_NONE},
nyatla 2:b96c1e90d120 311 {NULL}
nyatla 2:b96c1e90d120 312 };
nyatla 2:b96c1e90d120 313 int i;
nyatla 2:b96c1e90d120 314 //ここ早くできますよね。
nyatla 2:b96c1e90d120 315 for(i=0;_bc_type_tbl[i].bcopcode!=NULL;i++){
nyatla 2:b96c1e90d120 316 //2バイト一致?
nyatla 2:b96c1e90d120 317 if((*i_char==_bc_type_tbl[i].bcopcode[0])&&(*(i_char+1)==_bc_type_tbl[i].bcopcode[1])){
nyatla 2:b96c1e90d120 318 *o_opc=_bc_type_tbl[i].opid;
nyatla 2:b96c1e90d120 319 *o_opt=_bc_type_tbl[i].optype;
nyatla 2:b96c1e90d120 320 return NyLPC_TBool_TRUE;
nyatla 2:b96c1e90d120 321 }
nyatla 2:b96c1e90d120 322 }
nyatla 2:b96c1e90d120 323 return NyLPC_TBool_FALSE;
nyatla 2:b96c1e90d120 324 }
nyatla 2:b96c1e90d120 325
nyatla 2:b96c1e90d120 326
nyatla 2:b96c1e90d120 327 /**
nyatla 2:b96c1e90d120 328 * 長さi_numの16進数文字列を数値に変換する。アルファベットは小文字であること。
nyatla 2:b96c1e90d120 329 * @param i_num
nyatla 2:b96c1e90d120 330 * 変換する文字数
nyatla 2:b96c1e90d120 331 * @param out
nyatla 2:b96c1e90d120 332 *
nyatla 2:b96c1e90d120 333 */
nyatla 2:b96c1e90d120 334 static NyLPC_TBool txt2UInt(const NyLPC_TChar* i_txt,NyLPC_TUInt8 i_num,void* out)
nyatla 2:b96c1e90d120 335 {
nyatla 2:b96c1e90d120 336 NyLPC_TUInt32 ret=0;
nyatla 2:b96c1e90d120 337 NyLPC_TChar c;
nyatla 2:b96c1e90d120 338 int i;
nyatla 2:b96c1e90d120 339
nyatla 2:b96c1e90d120 340 for(i=0;i<i_num;i++){
nyatla 2:b96c1e90d120 341 c=(*(i_txt+i));
nyatla 2:b96c1e90d120 342 if('f'>=c && c>='a'){
nyatla 2:b96c1e90d120 343 c=c-(NyLPC_TUInt8)'a'+10;
nyatla 2:b96c1e90d120 344 }else if('9'>=c && c>='0'){
nyatla 2:b96c1e90d120 345 c-=(NyLPC_TUInt8)'0';
nyatla 2:b96c1e90d120 346 }else{
nyatla 2:b96c1e90d120 347 return NyLPC_TBool_FALSE;
nyatla 2:b96c1e90d120 348 }
nyatla 2:b96c1e90d120 349 ret=(ret<<4)|c;
nyatla 2:b96c1e90d120 350 }
nyatla 2:b96c1e90d120 351 //2,4,8だけ。
nyatla 2:b96c1e90d120 352 switch(i_num){
nyatla 2:b96c1e90d120 353 case 2:
nyatla 2:b96c1e90d120 354 *((NyLPC_TUInt8*)out)=(NyLPC_TUInt8)ret;
nyatla 2:b96c1e90d120 355 break;
nyatla 2:b96c1e90d120 356 case 4:
nyatla 2:b96c1e90d120 357 *((NyLPC_TUInt16*)out)=(NyLPC_TUInt16)ret;
nyatla 2:b96c1e90d120 358 break;
nyatla 2:b96c1e90d120 359 case 8:
nyatla 2:b96c1e90d120 360 *((NyLPC_TUInt32*)out)=(NyLPC_TUInt32)ret;
nyatla 2:b96c1e90d120 361 break;
nyatla 2:b96c1e90d120 362 default:
nyatla 2:b96c1e90d120 363 return NyLPC_TBool_FALSE;
nyatla 2:b96c1e90d120 364 }
nyatla 2:b96c1e90d120 365 return NyLPC_TBool_TRUE;
nyatla 2:b96c1e90d120 366 }
nyatla 2:b96c1e90d120 367 /**
nyatla 2:b96c1e90d120 368 * テキストデータをWMIDに変換する。WMIDは、VMの使用の影響を受ける。
nyatla 2:b96c1e90d120 369 */
nyatla 2:b96c1e90d120 370 static NyLPC_TBool txt2WMId(const NyLPC_TChar* i_txt,NyLPC_TUInt8* out)
nyatla 2:b96c1e90d120 371 {
nyatla 2:b96c1e90d120 372 if(txt2UInt(i_txt,2,out)){
nyatla 2:b96c1e90d120 373 if(*out<=NyLPC_TcMiMicVM_NUMBER_OF_WM){
nyatla 2:b96c1e90d120 374 return NyLPC_TBool_TRUE;
nyatla 2:b96c1e90d120 375 }
nyatla 2:b96c1e90d120 376 }
nyatla 2:b96c1e90d120 377 return NyLPC_TBool_FALSE;
nyatla 2:b96c1e90d120 378 }
nyatla 2:b96c1e90d120 379 /**
nyatla 2:b96c1e90d120 380 * オペランドタイプからオペランドのBC長と、インストラクションサイズを計算
nyatla 2:b96c1e90d120 381 */
nyatla 2:b96c1e90d120 382 static void NyLPC_TcMiMicVM_OPR_TYPE_getOpInfo(NyLPC_TcMiMicVM_OPR_TYPE i_type,NyLPC_TUInt8* oprbc_len,NyLPC_TUInt8* o_istlen)
nyatla 2:b96c1e90d120 383 {
nyatla 2:b96c1e90d120 384 const struct{
nyatla 2:b96c1e90d120 385 NyLPC_TcMiMicVM_OPR_TYPE t;
nyatla 2:b96c1e90d120 386 NyLPC_TUInt8 oprbc_len;
nyatla 2:b96c1e90d120 387 NyLPC_TUInt8 ist_len;
nyatla 2:b96c1e90d120 388 }_tbl[]={
nyatla 2:b96c1e90d120 389 {NyLPC_TcMiMicVM_OPR_TYPE_NONE, 0, 1},
nyatla 2:b96c1e90d120 390 {NyLPC_TcMiMicVM_OPR_TYPE_WM_WM, (1+1)*2, 1},
nyatla 2:b96c1e90d120 391 {NyLPC_TcMiMicVM_OPR_TYPE_WM_H08, (1+1)*2, 1},
nyatla 2:b96c1e90d120 392 {NyLPC_TcMiMicVM_OPR_TYPE_WM_H16, (1+2)*2, 2},
nyatla 2:b96c1e90d120 393 {NyLPC_TcMiMicVM_OPR_TYPE_WM_H32, (1+4)*2, 2},
nyatla 2:b96c1e90d120 394 {NyLPC_TcMiMicVM_OPR_TYPE_WM, (1)*2, 1},
nyatla 2:b96c1e90d120 395 {NyLPC_TcMiMicVM_OPR_TYPE_H08, (1)*2, 1},
nyatla 2:b96c1e90d120 396 {NyLPC_TcMiMicVM_OPR_TYPE_H16, (2)*2, 1},
nyatla 2:b96c1e90d120 397 {NyLPC_TcMiMicVM_OPR_TYPE_H32, (4)*2, 2},
nyatla 2:b96c1e90d120 398 {0,0,0}
nyatla 2:b96c1e90d120 399 };
nyatla 2:b96c1e90d120 400 int i;
nyatla 2:b96c1e90d120 401 for(i=0;_tbl[i].t!=0;i++){
nyatla 2:b96c1e90d120 402 if(_tbl[i].t==i_type){
nyatla 2:b96c1e90d120 403 *oprbc_len=_tbl[i].oprbc_len;
nyatla 2:b96c1e90d120 404 *o_istlen=_tbl[i].ist_len;
nyatla 2:b96c1e90d120 405 return;
nyatla 2:b96c1e90d120 406 }
nyatla 2:b96c1e90d120 407 }
nyatla 2:b96c1e90d120 408 NyLPC_Abort();
nyatla 2:b96c1e90d120 409 return;
nyatla 2:b96c1e90d120 410 }
nyatla 2:b96c1e90d120 411
nyatla 2:b96c1e90d120 412 #define TEST
nyatla 2:b96c1e90d120 413 #ifndef TEST
nyatla 2:b96c1e90d120 414 void main(void)
nyatla 2:b96c1e90d120 415 {
nyatla 2:b96c1e90d120 416 struct NyLPC_TCharArrayPtr bc;
nyatla 2:b96c1e90d120 417 const char* BC="AA0102AB0100000001AE0203AF0200000003AI0304AJ0300000004AM07BA0505BE0607CA0304CB0300000005CE0304CF0300000005CI0304CJ0300000005DA0400000000DE0400000000EA04EE04EF00000000ZAZZ.E";
nyatla 2:b96c1e90d120 418 NyLPC_TcMiMicTxtCompiler_t inst;
nyatla 2:b96c1e90d120 419 struct NyLPC_TUInt32ArrayPtr bin;
nyatla 2:b96c1e90d120 420
nyatla 2:b96c1e90d120 421 NyLPC_TUInt16 l,bl;
nyatla 2:b96c1e90d120 422 NyLPC_TUInt32 obuf[1024];
nyatla 2:b96c1e90d120 423 NyLPC_cMiMicBcCompiler_initialize(&inst);
nyatla 2:b96c1e90d120 424 bc.ptr=(char* )BC;
nyatla 2:b96c1e90d120 425 bc.len=strlen(BC);
nyatla 2:b96c1e90d120 426 bin.ptr=obuf;
nyatla 2:b96c1e90d120 427 bin.len=5;
nyatla 2:b96c1e90d120 428
nyatla 2:b96c1e90d120 429 for(;;){
nyatla 2:b96c1e90d120 430
nyatla 2:b96c1e90d120 431 switch(NyLPC_cMiMicBcCompiler_compileFragment(&inst,&bc,&bin,&bl,&l))
nyatla 2:b96c1e90d120 432 {
nyatla 2:b96c1e90d120 433 case NyLPC_TcMiMicTxtCompiler_RET_OK:
nyatla 2:b96c1e90d120 434 //命令確定。
nyatla 2:b96c1e90d120 435 NyLPC_TUInt32ArrayPtr_seek(&bin,bl);
nyatla 2:b96c1e90d120 436 NyLPC_TCharArrayPtr_seek(&bc,l);
nyatla 2:b96c1e90d120 437 break;
nyatla 2:b96c1e90d120 438 case NyLPC_TcMiMicTxtCompiler_RET_OK_END:
nyatla 2:b96c1e90d120 439 //命令終端
nyatla 2:b96c1e90d120 440 printf("OK");
nyatla 2:b96c1e90d120 441 break;
nyatla 2:b96c1e90d120 442 case NyLPC_TcMiMicTxtCompiler_RET_CONTINUE:
nyatla 2:b96c1e90d120 443 //蓄積中。
nyatla 2:b96c1e90d120 444 NyLPC_TCharArrayPtr_seek(&bc,l);
nyatla 2:b96c1e90d120 445 break;
nyatla 2:b96c1e90d120 446 case NyLPC_TcMiMicTxtCompiler_RET_NG:
nyatla 2:b96c1e90d120 447 printf("エラー");
nyatla 2:b96c1e90d120 448 return;
nyatla 2:b96c1e90d120 449 default:
nyatla 2:b96c1e90d120 450 break;
nyatla 2:b96c1e90d120 451 }
nyatla 2:b96c1e90d120 452 }
nyatla 2:b96c1e90d120 453 }
nyatla 2:b96c1e90d120 454 #endif