OSDN Git Service

ELCHNOS-OSECPU:式の内部表現への変換は完了した。
[chnosproject/AI004.git] / elcc.js
1 // ELCHNOSCompiler for AI004
2
3 function ELCHNOSCompiler(env){
4         this.env = env;
5         
6         this.line = null;
7         this.separated = null;
8         
9         this.structure = new Array();
10         this.currentStructure = this.structure;
11         this.structureStack = new Array();
12         
13         //0はエントリポイント(main)用に予約
14         this.nextLabelID = 1;
15 }
16 ELCHNOSCompiler.prototype = {
17         keyWordList: [
18                 "@asm",
19                 "@end",
20                 "//",
21                 "/*",
22                 "*/",
23                 "!=",
24                 "==",
25                 "+=",
26                 "-=",
27                 "*=",
28                 "/=",
29                 "++",
30                 "--",
31                 "\n",
32                 "\t",
33                 " ",
34                 "{",
35                 "}",
36                 "(",
37                 ")",
38                 ";",
39                 ",",
40                 "[",
41                 "]",
42                 "=",
43                 "+",
44                 "-",
45                 "*",
46                 "/",
47         ],
48         errorMessageList: [
49                 "Trap.",
50                 "Incompatible value attribute.",
51                 "Unexpected identifier.",
52                 "Unknown assembly language type.",
53                 "Invalid expression of OSECPU Binary."
54         ],
55         
56         Flag_Sign_Signed                        : 0x00000001,
57         Flag_Sign_Unsigned                      : 0x00000002,
58         
59         compile: function(str){
60                 this.line = str.split("\n");
61                 //分割
62                 this.separated = str.splitByArraySeparatorSeparatedLong(this.keyWordList);
63                 //コメント除去
64                 this.compile_removeComment();
65                 
66                 //不要な文字を削除
67                 this.separated.removeAllObject("\t");
68                 this.separated.removeAllObject(" ");
69                 
70                 console.log(this.separated);
71                 
72                 //メイン処理
73                 var currentExpression = null;
74                 var numValSignFlag = 0;
75                 var numValBits = 0;
76                 var pointerCount = 0;
77                 var lineCount = 1;
78                 var blockLevel = 0;
79                 //var DestinationOperand = null;
80                 var mode = 0;
81                 var unexpected = false;
82                 var errno = 2;
83                 var o;
84                 var f;
85                         //次に期待する値を示す。
86                         // 0: 何が来るかわからない
87                         //
88                         //10: 変数・定数の前置属性・型・または識別子
89                         //11: 変数・定数の識別子またはポインタ属性
90                         //12: 変数・定数の後置属性・初期化式または終端記号、もしくは連続した変数宣言の区切り
91                         //13: 変数・定数の初期化式または終端記号、もしくは連続した変数宣言の区切り
92                         //14: 配列長の数値部分
93                         //15: 配列長指定終了の閉じ括弧
94                         //16: 初期化式の開始括弧もしくは値
95                         //17: 初期化式の値部分または終了括弧
96                         //18: 初期化式の区切りまたは終了括弧
97                         //19: 終端記号
98                         //
99                         //50: 関数名または関数属性
100                         //51: 引数開始括弧
101                         //52: 引数or引数終了括弧
102                         //53: 引数区切りor引数終了括弧
103                         //54: 関数内部開始括弧
104                         //
105                         //60: 評価式の内容または終端記号
106                         //
107                         //70: OSECPUアセンブリ直接記述モード
108                         //71: OSECPUアセンブリ評価式の内容または終端記号
109                 for(var i = 0, iLen = this.separated.length; i < iLen; i++){
110                         var s = this.separated[i].toLowerCase();
111                         //this.env.debug((i + 1) + ":" + s + "\n");
112                         
113                         if(s == "\n"){
114                                 //デバッグ用行数カウント
115                                 lineCount++;
116                                 continue;
117                         //予約語
118                         } else if(s == "signed" && (mode == 0 || mode == 10)){
119                                 //符号あり
120                                 if(numValSignFlag == 0){
121                                         numValSignFlag |= this.Flag_Sign_Signed;
122                                         mode = 10;
123                                 } else{
124                                         unexpected = true;
125                                         errno = 1;
126                                 }
127                         } else if(s == "unsigned" && (mode == 0 || mode == 10)){
128                                 //符号なし
129                                 if(numValSignFlag == 0){
130                                         numValSignFlag |= this.Flag_Sign_Unsigned;
131                                         mode = 10;
132                                 } else{
133                                         unexpected = true;
134                                         errno = 1;
135                                 }
136                         } else if(s == "char"  && (mode == 0 || mode == 10 || mode == 11 || mode == 52)){
137                                 //char 8bit符号あり
138                                 numValBits = 8;
139                                 if(mode == 0 || mode == 10 || mode == 11){
140                                         mode = 11;
141                                 }
142                         } else if(s == "int" && (mode == 0 || mode == 10 || mode == 11 || mode == 52)){
143                                 //int 32bit符号あり
144                                 numValBits = 32;
145                                 if(mode == 0 || mode == 10 || mode == 11){
146                                         mode = 11;
147                                 }
148                         } else if(s == ";" && (mode == 0 || mode == 12 || mode == 13 || mode == 19 || mode == 60 || mode == 71)){
149                                 if(mode == 12 || mode == 13 || mode == 19){
150                                         //変数または定数の定義終了
151                                         numValBits = 0;
152                                         numValSignFlag = 0;
153                                         console.log(currentExpression);
154                                         currentExpression = null;
155                                         mode = 0;
156                                 } else if(mode == 60 || mode == 71){
157                                         //評価式終端
158                                         console.log(currentExpression);
159                                         currentExpression = null;
160                                         if(mode == 60){
161                                                 mode = 0;
162                                         } else if(mode == 71){
163                                                 mode = 70;
164                                         }
165                                 } else{
166                                         unexpected = true;
167                                 }
168                         } else if(s == "=" && (mode == 13)){
169                                 if(mode == 13){
170                                         //変数・定数初期化式開始
171                                         mode = 16;
172                                 } else{
173                                         unexpected = true;
174                                 }
175                         } else if(s == "*" && (mode == 11)){
176                                 //ポインタ属性の付加
177                                 pointerCount++;
178                         } else if(s == "," && (mode == 18 || mode == 12 || mode == 13 || mode == 53)){
179                                 if(mode == 18){
180                                         //初期化式の区切り
181                                         mode = 17;
182                                 } else if(mode == 12 || mode == 13 || mode == 53){
183                                         //連続した変数宣言の区切り
184                                         if(mode == 12 || mode == 13){
185                                                 mode = 11;
186                                         } else if(mode == 53){
187                                                 mode = 52;
188                                         }
189                                         console.log(currentExpression);
190                                         currentExpression = null;
191                                 } else{
192                                         unexpected = true;
193                                 }
194                         //括弧系
195                         } else if(s == "[" && (mode == 12)){
196                                 //配列の長さの定義開始
197                                 mode = 14;
198                         } else if(s == "]" && (mode == 15)){
199                                 //配列の長さの定義終了
200                                 mode = 13;
201                         } else if(s == "{" && (mode == 16 || mode == 54)){
202                                 if(mode == 16){
203                                         //初期化式の開始括弧
204                                         mode = 17;
205                                 } else if(mode == 54){
206                                         //54: 関数内部開始括弧
207                                         currentExpression = null;
208                                         mode = 0;
209                                 } else{
210                                         unexpected = true;
211                                 }
212                         } else if(s == "}" && (mode == 17 || mode == 18 || mode == 0)){
213                                 if(mode == 17 || mode == 18){
214                                         //初期化式の終了括弧
215                                         mode = 19;
216                                 } else if(mode == 0){
217                                         if(this.structureStack.length > 0){
218                                                 console.log(this.currentStructure);
219                                                 this.restoreCurrentStructure();
220                                         } else{
221                                                 unexpected = true;
222                                         }
223                                 }
224                         } else if(s == "(" && (mode == 51)){
225                                 //51: 引数開始括弧
226                                 mode = 52;
227                         } else if(s == ")" && (mode == 52 || mode == 53)){
228                                 //52: 引数or引数終了括弧
229                                 //53: 引数区切りor引数終了括弧
230                                 console.log(currentExpression);
231                                 currentExpression = null;
232                                 for(var j = 0, jLen = this.currentStructure.length; j < jLen; j++){
233                                         //引数番号を付与
234                                         this.currentStructure[j].argumentIndex = j;
235                                 }
236                                 mode = 54;
237                         } else if(s == "@asm" && (mode == 0)){
238                                 i++;
239                                 s = this.separated[i].toLowerCase();
240                                 if(s == "osecpu"){
241                                         mode = 70;
242                                 } else{
243                                         unexpected = true;
244                                         errno = 3;
245                                 }
246                         } else if(s == "@end" && (mode == 70)){
247                                 mode = 0;
248                         //リストにない予約語
249                         } else if(s == "procedure" && (mode == 0)){
250                                 //関数宣言
251                                 var f = new ELCHNOSCompiler_ExpressionStructure_Function(this);
252                                 this.currentStructure.push(f);
253                                 this.changeCurrentStructure(f.structure);
254                                 currentExpression = f;
255                                 
256                                 mode = 50;
257                         } else if(s == "inline" && (mode == 50)){
258                                 currentExpression.isInline = true;
259                         } else if(s == "for" && (mode == 0)){
260                                 //forループ
261                                 //
262                                 //初期化式
263                                 //L1:
264                                 //条件評価式-?>L2
265                                 //実行部分
266                                 //(break->L2)
267                                 //更新式->L1
268                                 //L2:
269                                 i++;
270                                 s = this.separated[i];
271                                 if(s == "("){
272                                         var f = new ELCHNOSCompiler_ExpressionStructure_Loop_for(this);
273                                         this.currentStructure.push(f);
274                                         this.changeCurrentStructure(f.structure);
275                                         currentExpression = f;
276                                         //初期化式
277                                         f.initializer = new ELCHNOSCompiler_ExpressionStructure_Expression(this);
278                                         for(i++; ; i++){
279                                                 s = this.separated[i];
280                                                 if(s == ";"){
281                                                         break;
282                                                 }
283                                                 f.initializer.pushIdentifier(s);
284                                                 if(unexpected){
285                                                         break;
286                                                 }
287                                         }
288                                         console.log(f.initializer);
289                                         //条件評価式
290                                         if(!unexpected){
291                                                 f.conditonalExpression = new ELCHNOSCompiler_ExpressionStructure_Expression(this);
292                                                 for(i++; ; i++){
293                                                         s = this.separated[i];
294                                                         if(s == ";"){
295                                                                 break;
296                                                         }
297                                                         f.conditonalExpression.pushIdentifier(s);
298                                                         if(unexpected){
299                                                                 break;
300                                                         }
301                                                 }
302                                                 console.log(f.conditonalExpression);
303                                         }
304                                         //更新式
305                                         if(!unexpected){
306                                                 f.incrementalExpression = new ELCHNOSCompiler_ExpressionStructure_Expression(this);
307                                                 for(i++; ; i++){
308                                                         s = this.separated[i];
309                                                         if(s == ")"){
310                                                                 break;
311                                                         }
312                                                         f.incrementalExpression.pushIdentifier(s);
313                                                         if(unexpected){
314                                                                 break;
315                                                         }
316                                                 }
317                                                 console.log(f.incrementalExpression);
318                                         }
319                                         //開始括弧
320                                         if(!unexpected){
321                                                 i++;
322                                                 if(this.separated[i] != "{"){
323                                                         unexpected = true;
324                                                 }
325                                                 currentExpression = null;
326                                         }
327                                 } else{
328                                         unexpected = true;
329                                 }
330                         } else if(s == "if" && (mode == 0)){
331                                 //if文
332                                 //条件評価式-?>L2
333                                 //実行部分
334                                 //(break->L2)
335                                 //L2:
336                                 i++;
337                                 s = this.separated[i];
338                                 if(s == "("){
339                                         var f = new ELCHNOSCompiler_ExpressionStructure_if(this);
340                                         this.currentStructure.push(f);
341                                         this.changeCurrentStructure(f.structure);
342                                         currentExpression = f;
343                                         //条件評価式
344                                         f.conditonalExpression = new ELCHNOSCompiler_ExpressionStructure_Expression(this);
345                                         for(i++; ; i++){
346                                                 s = this.separated[i];
347                                                 if(s == ")"){
348                                                         break;
349                                                 }
350                                                 f.conditonalExpression.pushIdentifier(s);
351                                                 if(unexpected){
352                                                         break;
353                                                 }
354                                         }
355                                         console.log(f.conditonalExpression);
356                                         //開始括弧
357                                         if(!unexpected){
358                                                 i++;
359                                                 if(this.separated[i] != "{"){
360                                                         unexpected = true;
361                                                 }
362                                                 currentExpression = null;
363                                         }
364                                 } else{
365                                         unexpected = true;
366                                 }
367                         //OSECPUアセンブリ
368                         } else if(s == "remark" && (mode == 70)){
369                                 //超手抜き
370                                 var b = new ELCHNOSCompiler_ExpressionStructure_OSECPUBinary(this);
371                                 this.currentStructure.push(b);
372                                 //FE    len     ...
373                                 b.bin.push(0xfe);
374                                 //len
375                                 i++;
376                                 s = this.separated[i];
377                                 if(s.length == 2){
378                                         var len = parseInt(s, 16);
379                                         b.bin.push(len);
380                                 } else{
381                                         unexpected = true;
382                                         errno = 4;
383                                 }
384                                 //data
385                                 if(!unexpected){
386                                         i++;
387                                         s = this.separated[i];
388                                         if(s.length == len * 2){
389                                                 for(var j = 0; j < len; j++){
390                                                         b.bin.push(parseInt(s.substr(j * 2, 2), 16));
391                                                 }
392                                         } else{
393                                                 unexpected = true;
394                                                 errno = 4;
395                                         }
396                                 }
397                                 
398                                 if(!unexpected){
399                                         i++;
400                                         if(this.separated[i] != ";"){
401                                                 unexpected = true;
402                                         } else{
403                                                 //この命令は定数のみで構成されているのでコンパイル済みとマークする
404                                                 b.isCompiled = true;
405                                                 b = null;
406                                         }
407                                 }
408                         } else if(s == "call" && (mode == 70)){
409                                 //超手抜き
410                                 var b = new ELCHNOSCompiler_ExpressionStructure_OSECPUBinary(this);
411                                 this.currentStructure.push(b);
412                                 
413                                 //第二引数が何か確認する
414                                 i++;
415                                 s = this.separated[i].toLowerCase();
416                                 if((s.indexOf("p") == 0) && s.length == 3){
417                                         //ポインタレジスタをcall
418                                         //新しいラベル番号をもらう
419                                         var labelID = this.allocateLabelID();
420                                         //PLIMM(P30, labelID)
421                                                 //03    reg0    imm32
422                                         b.bin.push(0x03);
423                                         b.bin.push(0x30);
424                                         b.bin.push((labelID >> 24) & 0xFF);
425                                         b.bin.push((labelID >> 16) & 0xFF);
426                                         b.bin.push((labelID >> 8) & 0xFF);
427                                         b.bin.push(labelID & 0xFF);
428                                         //PCP(P3F, Pxx)
429                                                 //1E    reg0P   reg1P
430                                         b.bin.push(0x1e);
431                                         b.bin.push(0x3f);
432                                         b.bin.push(parseInt(s.substr(1),16));
433                                         //LB(1, labelID)
434                                                 //02    opt     imm32
435                                         b.bin.push(0x02);
436                                         b.bin.push(0x01);
437                                         b.bin.push((labelID >> 24) & 0xFF);
438                                         b.bin.push((labelID >> 16) & 0xFF);
439                                         b.bin.push((labelID >> 8) & 0xFF);
440                                         b.bin.push(labelID & 0xFF);
441                                         //[FE] [01] [00]
442                                         b.bin.push(0xfe);
443                                         b.bin.push(0x01);
444                                         b.bin.push(0x00);
445                                         //終端記号
446                                         i++;
447                                         if(this.separated[i] != ";"){
448                                                 unexpected = true;
449                                         } else{
450                                                 //この命令は定数のみで構成されているのでコンパイル済みとマークする
451                                                 b.isCompiled = true;
452                                                 b = null;
453                                         }
454                                 } else{
455                                         unexpected = true;
456                                         errno = 0;
457                                 }
458                         //予約語以外
459                         } else if(mode == 11 || mode == 52){
460                                 //変数または定数の宣言
461                                 //52: 引数名
462                                 var v = new ELCHNOSCompiler_ExpressionStructure_Variable(this);
463                                 v.bits = numValBits;
464                                 v.isSigned = (numValSignFlag == 0) ? false : (0 != (numValSignFlag & this.Flag_Sign_Signed));
465                                 s = this.separated[i];
466                                 v.isPointer = (pointerCount != 0) ? true : false;
467                                 pointerCount = 0;
468                                 if(s.length > 0){
469                                         v.identifier = s;
470                                         
471                                         this.currentStructure.push(v);
472                                         currentExpression = v;
473                                         
474                                         //mode:11->12
475                                         //mode:52->53
476                                         mode++;
477                                 } else{
478                                         unexpected = true;
479                                 }
480                         } else if(mode == 14){
481                                 currentExpression.length = parseInt(s);
482                                 mode = 15;
483                         } else if(mode == 17){
484                                 //定数値のみ対応
485                                 currentExpression.initValue.push(parseInt(s));
486                                 mode = 18;
487                         } else if(mode == 50){
488                                 //関数名
489                                 //大文字小文字を区別
490                                 currentExpression.identifier = this.separated[i];
491                                 mode = 51;
492                         } else{
493                                 if(mode == 0 || mode == 70 || mode == 60 || mode == 71){
494                                         //大文字小文字を区別
495                                         s = this.separated[i];
496                                         if(mode == 0 || mode == 70){
497                                                 //最初の左辺だったら追加処理
498                                                 var f = new ELCHNOSCompiler_ExpressionStructure_Expression(this);
499                                                 this.currentStructure.push(f);
500                                                 currentExpression = f;
501                                         }
502                                         currentExpression.pushIdentifier(s);
503                                         if(!unexpected){
504                                                 if(mode == 0){
505                                                         mode = 60;
506                                                 } else if(mode == 70){
507                                                         mode = 71;
508                                                 }
509                                         }
510                                 }
511                         }
512                         if(unexpected){
513                                 //期待されていない値
514                                 s = this.separated[i];
515                                 this.raiseError(errno, lineCount, [s, mode]);
516                                 console.log(this.structure);
517                                 return;
518                         }
519                 }
520                 console.log(this.structure);
521         },
522         compile_removeComment: function(){
523                 //コメント削除
524                 var commentLineStartIndex = -1;
525                 var commentBlockStartIndex = -1;
526                 var commentBlockCount = 0;
527                 var linesInCommentBlock = 0;
528                 
529                 for(var i = 0, iLen = this.separated.length; i < iLen; i++){
530                         var s = this.separated[i];
531                         if(commentLineStartIndex == -1){
532                                 if(s == "//"){
533                                         //行コメント開始
534                                         commentLineStartIndex = i;
535                                 }
536                         } else{
537                                 if(s == "\n"){
538                                         //行コメント終了
539                                         var len = i - commentLineStartIndex;
540                                         this.separated.splice(commentLineStartIndex, len);
541                                         iLen -= len;
542                                         i -= len;
543                                         commentLineStartIndex = -1;
544                                 }
545                         }
546                         if(s == "/*"){
547                                 //ブロックコメント開始
548                                 if(commentBlockCount == 0){
549                                         commentBlockStartIndex = i;
550                                 }
551                                 commentBlockCount++;
552                         } else if(s == "*/"){
553                                 //ブロックコメント終了
554                                 commentBlockCount--;
555                                 if(commentBlockCount == 0){
556                                         var len = i - commentBlockStartIndex + 1;
557                                         var padding = new Array();
558                                         padding.push(commentBlockStartIndex);
559                                         padding.push(len);
560                                         for(var j = 0, jLen = linesInCommentBlock; j < jLen; j++){
561                                                 padding.push("\n");
562                                         }
563                                         this.separated.splice.apply(this.separated, padding);
564                                         i -= len - linesInCommentBlock;
565                                         iLen -= len - linesInCommentBlock;
566                                         linesInCommentBlock = 0;
567                                 } else if(commentBlockCount < 0){
568                                         this.env.debug("Too many block comment closure [].\n");
569                                         return;
570                                 }
571                         } else if(commentBlockCount > 0 && s == "\n"){
572                                 linesInCommentBlock++;
573                         }
574                 }
575         },
576         raiseError: function(errno, lineCount, infoArray){
577                 if(errno < 0 || this.errorMessageList.length <= errno){
578                         this.env.debug(lineCount + ":Error" + errno.toString().toUpperCase() + ":Unknown\n");
579                 } else{
580                         this.env.debug(lineCount + ":Error" + errno.toString().toUpperCase() + ":" + this.errorMessageList[errno] + "\n");
581                 }
582                 if(infoArray){
583                         this.env.debug("  >" + infoArray.toString() + "\n");
584                 }
585         },
586         changeCurrentStructure: function(newstructure){
587                 this.structureStack.push(this.currentStructure);
588                 this.currentStructure = newstructure;
589         },
590         restoreCurrentStructure: function(){
591                 this.currentStructure = this.structureStack.pop();
592         },
593         searchIdentifier: function(identifier){
594                 var o;
595                 var cf = function(aryobj, obj){ return (aryobj.identifier == obj) };
596                 
597                 o = this.currentStructure.isIncluded(identifier, cf);
598                 if(!o){
599                         for(var i = this.structureStack.length - 1; i >= 0; i--){
600                                 o = this.structureStack[i].isIncluded(identifier, cf);
601                                 if(o){
602                                         break;
603                                 }
604                         }
605                 }
606                 return o;
607         },
608         isOperator: function(s){
609                 return (
610                         s == "=" ||
611                         s == "+" ||
612                         s == "-" ||
613                         s == "*" ||
614                         s == "/" ||
615                         s == "!=" ||
616                         s == "++" ||
617                         s == "<" ||
618                         s == "(" ||
619                         s == ")"||
620                         s == "," ||
621                         false
622                 );
623         },
624         allocateLabelID: function(){
625                 this.nextLabelID++;
626                 return this.nextLabelID - 1;
627         },
628 }
629
630 function ELCHNOSCompiler_ExpressionStructure_Variable(compiler){
631         this.compiler = compiler;
632         this.bits = 0;
633         this.length = 0;
634         this.isSigned = false;
635         this.isPointer = false;
636         this.identifier = null;
637         this.initValue = new Array();
638         //引数として渡されるものであれば、引数の左から数えて何番目かが入る。
639         this.argumentIndex = -1;
640 }
641 ELCHNOSCompiler_ExpressionStructure_Variable.prototype = {
642
643 }
644
645 function ELCHNOSCompiler_ExpressionStructure_Function(compiler){
646         this.compiler = compiler;
647         this.structure = new Array();
648         this.identifier = null;
649 }
650 ELCHNOSCompiler_ExpressionStructure_Function.prototype = {
651
652 }
653
654 function ELCHNOSCompiler_ExpressionStructure_Loop_for(compiler){
655         this.compiler = compiler;
656         this.structure = new Array();
657         this.initializer = null;
658         this.conditonalExpression = null;
659         this.incrementalExpression = null;
660         this.isInline = false;
661 }
662 ELCHNOSCompiler_ExpressionStructure_Loop_for.prototype = {
663
664 }
665
666 function ELCHNOSCompiler_ExpressionStructure_if(compiler){
667         this.compiler = compiler;
668         this.structure = new Array();
669         this.conditonalExpression = null;
670 }
671 ELCHNOSCompiler_ExpressionStructure_if.prototype = {
672
673 }
674
675 function ELCHNOSCompiler_ExpressionStructure_Expression(compiler){
676         this.compiler = compiler;
677         this.evalStack = new Array();
678         this.evalOperatorStack = new Array();
679         this.lastOperatorPriority = ELCHNOSCompiler_ExpressionStructure_Expression.prototype.operatorPriorityList.length;
680         this.startBracketIndexStack = new Array();
681 }
682 ELCHNOSCompiler_ExpressionStructure_Expression.prototype = {
683         //drawLine(1 + 4, x0, y0, x1, y1, col);
684         //->    drawLine 1 4 + x0 y0 x1 y1 col ()
685         //f(g(1 + 4 * (2 - 3)), 4 * 2 + 1);
686         //->    f g 1 4 2 3 - * + () 4 2 * 1 + ()
687         
688         operatorPriorityList: [
689                 "/",
690                 "*",
691                 "-",
692                 "+",
693                 //"/=",
694                 //"+=",
695                 //"-=",
696                 //"+=",
697         ],
698         pushOperand: function(identifier){
699                 //オペランドを追加する
700                 //数値ならば数値自体もしくは等価な文字列
701                 //オブジェクトであればそのオブジェクトのインスタンスを渡す
702                 this.evalStack.push(identifier);
703         },
704         pushOperator: function(operator){
705                 //演算子を追加する。
706                 //演算子は文字列で渡す
707                 if(operator == "("){
708                         //開き括弧のevalOperatorStack内でのIndexを記憶
709                         if(this.evalStack[this.evalStack.length - 1] instanceof ELCHNOSCompiler_ExpressionStructure_Function){
710                                 //関数呼び出しの括弧
711                                 //-(index + 1)で記憶しておく
712                                 this.startBracketIndexStack.push(-(this.evalOperatorStack.length + 1));
713                         } else{
714                                 //式の優先順位を示す括弧
715                                 this.startBracketIndexStack.push(this.evalOperatorStack.length);
716                         }
717                         this.evalOperatorStack.push(operator);
718                 } else if(operator == ")"){
719                         //開き括弧のインデックスを得る
720                         //開き括弧までのOperatorを順にevalStackにpushして、括弧内の式を完結させる
721                         var i = this.startBracketIndexStack.pop();
722                         for(;;){
723                                 var o = this.evalOperatorStack.pop();
724                                 if(o == "("){
725                                         break;
726                                 } else if(o === undefined){
727                                         //括弧の個数が合わないのでエラー
728                                         this.compiler.unexpected = true;
729                                         return;
730                                 }
731                                 this.evalStack.push(o);
732                         }
733                         if(i < 0){
734                                 //関数呼び出しの括弧
735                                 this.evalStack.push("()");
736                         }
737                 } else if(operator == ","){
738                         //現在の階層の式を完結させる
739                         for(;;){
740                                 var o = this.evalOperatorStack.pop();
741                                 if(o == "("){
742                                         //開き括弧は戻しておく
743                                         this.evalOperatorStack.push(o);
744                                         break;
745                                 } else if(o === undefined){
746                                         //すべてプッシュしたので終了
747                                         break;
748                                 }
749                                 this.evalStack.push(o);
750                         }
751                 } else{
752                         //一般operator
753                         var p = this.getOperatorPriority(operator);
754                         if(this.lastOperatorPriority >= p){
755                                 //とりあえずとっておく
756                                 this.evalOperatorStack.push(operator);
757                         } else{
758                                 //優先順位がより高い演算子を先に積んでおき、そのあと自分をとっておく
759                                 for(var i = 0, iLen = this.evalOperatorStack.length; i < iLen; i++){
760                                         var o = this.evalOperatorStack.pop();
761                                         if(this.getOperatorPriority(o) < p){
762                                                 this.evalStack.push(o);
763                                         } else{
764                                                 this.evalOperatorStack.push(o);
765                                                 break;
766                                         }
767                                 }
768                                 this.evalOperatorStack.push(operator);
769                         }
770                         this.lastOperatorPriority = p;
771                 }
772         },
773         pushIdentifier: function(identifier){
774                 //識別子を式に追加する。
775                 //自動的にオペランドか演算子かを判別し、適切にプッシュする。
776                 //識別子は大文字小文字を区別できる状態で渡すようにする
777                 //レジスタ直接指定もできる
778                 
779                 if(this.isOperator(identifier)){
780                         //演算子
781                         this.pushOperator(identifier);
782                 } else {
783                         var o = this.compiler.searchIdentifier(identifier);
784                         if(o){
785                                 //オブジェクトオペランド
786                                 this.pushOperand(o);
787                         } else if(!isNaN(identifier)){
788                                 //即値オペランド
789                                 this.pushOperand(parseInt(identifier));
790                         } else{
791                                 //レジスタ名である可能性を確認
792                                 var s = identifier.toLowerCase();
793                                 if((s.indexOf("r") == 0 || s.indexOf("p") == 0) && s.length == 3){
794                                         //レジスタ名指定
795                                         this.pushOperand(s);
796                                 } else{
797                                         this.compiler.unexpected = true;
798                                 }
799                         }
800                 }
801         },
802         getOperatorPriority: function(operator){
803                 for(var i = 0, iLen = this.operatorPriorityList.length; i < iLen; i++){
804                         if(this.operatorPriorityList[i] == operator){
805                                 break;
806                         }
807                 }
808                 return i;
809         },
810         isOperator: function(s){
811                 return (
812                         s == "=" ||
813                         s == "+" ||
814                         s == "-" ||
815                         s == "*" ||
816                         s == "/" ||
817                         s == "!=" ||
818                         s == "++" ||
819                         s == "<" ||
820                         s == "(" ||
821                         s == ")"||
822                         s == "," ||
823                         false
824                 );
825         },
826 }
827
828 function ELCHNOSCompiler_ExpressionStructure_OSECPUBinary(compiler){
829         this.compiler = compiler;
830         this.bin = new Array();
831         this.isCompiled = false;
832 }
833 ELCHNOSCompiler_ExpressionStructure_OSECPUBinary.prototype = {
834
835 }