OSDN Git Service

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