リビジョン | f82ed5f039e3eb7b5cf45ddff8b382a21bc47591 (tree) |
---|---|
日時 | 2014-07-19 22:02:45 |
作者 | ttwilb <ttwilb@user...> |
コミッター | ttwilb |
式の評価。
@@ -21,31 +21,30 @@ int asmi_main(int argc, char **argv){ | ||
21 | 21 | init_expression(); |
22 | 22 | init_tokenizer(); |
23 | 23 | |
24 | + printf("***** TOKENS *****\n\n"); | |
25 | + | |
24 | 26 | for (; (tkn = next_token(&stream, &context)).id != NIL;) { |
25 | 27 | |
26 | 28 | debug_token(tkn); |
27 | 29 | |
28 | 30 | } |
31 | + fclose(stream.fp); | |
29 | 32 | |
30 | 33 | // 第二ループ |
31 | 34 | |
32 | 35 | context.defines_top = 0; |
33 | 36 | context.token_stack_top = 0; |
34 | 37 | |
35 | - // 引数が不足している場合はエラー。 | |
36 | - if (argc == 1) { | |
37 | - | |
38 | - printf("Usage >%s file.asmi\n\n", "asmi.exe"); | |
39 | - return -1; | |
40 | - | |
41 | - } | |
42 | - | |
43 | 38 | init_stream(&stream, argv[1]); |
44 | 39 | init_expression(); |
45 | 40 | init_tokenizer(); |
46 | 41 | |
42 | + printf("\n\n***** EXPRESSIONS *****\n\n"); | |
43 | + | |
47 | 44 | parser_entry(&stream, &context); |
48 | 45 | |
46 | + fclose(stream.fp); | |
47 | + | |
49 | 48 | return 0; |
50 | 49 | |
51 | 50 | } |
@@ -106,6 +106,8 @@ void pop_stream(input_stream *stream); // #include で読み込まれたフ | ||
106 | 106 | // トークンの種類。これらの値はnext_token()でセットされる。 |
107 | 107 | typedef enum { |
108 | 108 | |
109 | + Null = NIL, | |
110 | + | |
109 | 111 | // 括弧 |
110 | 112 | Lparen = '(', Rparen = ')', Lbrace = '{', Rbrace = '}', Lbracket = '[', Rbracket = ']', |
111 | 113 |
@@ -133,15 +135,14 @@ typedef enum { | ||
133 | 135 | Int, Char, Short, Long, Float, Double, Void, Signed, Unsigned, |
134 | 136 | |
135 | 137 | // リテラル値 |
136 | - Ident, String, IntValue, FloatValue, | |
137 | - | |
138 | - Null = NIL | |
138 | + Ident, String, IntValue, FloatValue | |
139 | 139 | |
140 | 140 | } token_id; |
141 | 141 | |
142 | 142 | typedef enum { |
143 | 143 | |
144 | - TK_Operator, TK_Type, TK_Other = NIL | |
144 | + TK_Other = NIL, | |
145 | + TK_Operator, TK_Type | |
145 | 146 | |
146 | 147 | } token_kind; |
147 | 148 |
@@ -245,6 +246,9 @@ typedef enum { | ||
245 | 246 | |
246 | 247 | typedef enum { |
247 | 248 | |
249 | + // ヌルタイプ | |
250 | + OP_Null = NIL, | |
251 | + | |
248 | 252 | // 単純演算 |
249 | 253 | OP_ADDI, OP_ADDF, OP_SUBI, OP_SUBF, OP_MULI, OP_MULF, OP_DIVI, OP_DIVF, |
250 | 254 | OP_OR, OP_XOR, OP_AND, OP_SHL, OP_SAR, OP_CMPEQ, OP_CMPNE, OP_CMPLT, OP_CMPGT, OP_CMPLE, OP_CMPGE, |
@@ -258,10 +262,7 @@ typedef enum { | ||
258 | 262 | |
259 | 263 | OP_FACTOR, |
260 | 264 | |
261 | - OP_CNVIF, OP_CNVFI, OP_SBX, | |
262 | - | |
263 | - // ヌルタイプ | |
264 | - OP_Null = NIL | |
265 | + OP_CNVIF, OP_CNVFI, OP_SBX | |
265 | 266 | |
266 | 267 | } operation_id; // operator_typeに改名予定 |
267 | 268 |
@@ -25,7 +25,7 @@ expression *alloc_plain_expression() { | ||
25 | 25 | asmi_fatal("expressionを確保できません。"); |
26 | 26 | return NULL; |
27 | 27 | |
28 | -} | |
28 | +}// http://www.google.com | |
29 | 29 | |
30 | 30 | struct { |
31 | 31 | operation_id id; |
@@ -109,10 +109,27 @@ expression *generate_expression(token_id op, expression *exp0, expression *exp1, | ||
109 | 109 | |
110 | 110 | if ((exp0 == NULL && etyp1 == NIL || (exp0->value_type & etyp1) == etyp1) && |
111 | 111 | (exp1 == NULL && etyp2 == NIL || (exp1->value_type & etyp2) == etyp2) && |
112 | - (exp2 == NULL && etyp2 == NIL || (exp2->value_type & etyp3) == etyp3) && | |
113 | - (!(must_leftval & 1) || (exp0 != NULL && exp0->is_leftval)) && | |
114 | - (!(must_leftval & 2) || (exp1 != NULL && exp1->is_leftval)) && | |
115 | - (!(must_leftval & 4) || (exp2 != NULL && exp2->is_leftval))) { | |
112 | + (exp2 == NULL && etyp3 == NIL || (exp2->value_type & etyp3) == etyp3)) { | |
113 | + | |
114 | + /* | |
115 | + // (!(must_leftval & 1) || (exp0 != NULL && exp0->is_leftval)) && | |
116 | + // (!(must_leftval & 2) || (exp1 != NULL && exp1->is_leftval)) && | |
117 | + // (!(must_leftval & 4) || (exp2 != NULL && exp2->is_leftval))) | |
118 | + | |
119 | + 上のように書くと実行時エラーになってしまう。( && 演算子の簡略評価がなされないみたい) | |
120 | + どうすれば下の if( ... ) continue; 連は簡単にできるのだろうか? | |
121 | + */ | |
122 | + | |
123 | + // 式が左辺値であることを確認 | |
124 | + | |
125 | + if (must_leftval & 1 && !exp0) continue; | |
126 | + if (must_leftval & 2 && !exp1) continue; | |
127 | + if (must_leftval & 4 && !exp2) continue; | |
128 | + if (must_leftval & 1 && !exp0->is_leftval) continue; | |
129 | + if (must_leftval & 2 && !exp1->is_leftval) continue; | |
130 | + if (must_leftval & 4 && !exp2->is_leftval) continue; | |
131 | + | |
132 | + // ここからが本題の処理。 | |
116 | 133 | |
117 | 134 | exp = alloc_plain_expression(); |
118 | 135 | exp->exp[0] = exp0; |
@@ -406,6 +423,9 @@ expression *evaluate_term(input_stream *stream, asmi_context *context, int level | ||
406 | 423 | rexp = generate_conv_expression(exp2, exp->value.type_value); |
407 | 424 | |
408 | 425 | } |
426 | + else { | |
427 | + rexp = exp; | |
428 | + } | |
409 | 429 | |
410 | 430 | } |
411 | 431 |
@@ -457,7 +477,7 @@ void debug_expression(expression *exp, int indent) { | ||
457 | 477 | |
458 | 478 | int i; |
459 | 479 | for (i = 0; i < indent; i++)printf("\t"); |
460 | - printf("%s", get_op_string(exp->id)); | |
480 | + printf("%s\n", get_op_string(exp->id)); | |
461 | 481 | if (exp->exp[0] != NULL) debug_expression(exp->exp[0], indent + 1); |
462 | 482 | if (exp->exp[1] != NULL) debug_expression(exp->exp[1], indent + 1); |
463 | 483 | if (exp->exp[2] != NULL) debug_expression(exp->exp[2], indent + 1); |
@@ -33,6 +33,7 @@ void parse_compound_statement(input_stream *stream, asmi_context *context, int l | ||
33 | 33 | } |
34 | 34 | else { |
35 | 35 | // 式として評価 |
36 | + push_token(tkn, context); | |
36 | 37 | expression *expr = evaluate_expression(stream, context); |
37 | 38 | |
38 | 39 | debug_expression(expr, 0); |
@@ -1,6 +1,3 @@ | ||
1 | 1 | |
2 | -we | |
3 | -#include "source2.txt" | |
4 | -we | |
5 | -we | |
6 | -wewe | |
2 | + | |
3 | +123 * 234 / 3232 * 1234 / 234.5 |
@@ -1,4 +0,0 @@ | ||
1 | - | |
2 | -3 | |
3 | -aiueo | |
4 | -0.12345 | |
\ No newline at end of file |
@@ -325,6 +325,7 @@ BOOL read_operator2(char *c, token *tkn, input_stream *stream, asmi_context *con | ||
325 | 325 | } |
326 | 326 | tkn->id = symbol_word_table[i].id; |
327 | 327 | tkn->kind = symbol_word_table[i].kind; |
328 | + ret = TRUE; | |
328 | 329 | *(++op) = *c = next_char(stream, FALSE, context); |
329 | 330 | if (*c == EOF) break; |
330 | 331 | } |