This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
core/mimicvm/NyLPC_cMiMicTxtCompiler.c@12:efe841863fc8, 2013-04-20 (annotated)
- Committer:
- nyatla
- Date:
- Sat Apr 20 05:03:57 2013 +0000
- Revision:
- 12:efe841863fc8
- Parent:
- core/mimicvm/NyLPC_cMiMicTxtCompiler.cpp@2:b96c1e90d120
MiMic r218
Who changed what in which revision?
User | Revision | Line number | New 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 |