?? c.y
字號:
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oMODASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oMODASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'%=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov dx, $3
gen_mov_value_to_reg($3, "dx");
// mov ax, $1
gen_mov_value_to_reg($1, "ax");
// idiv dx
gen_div("dx");
// mov $1, dx
gen_mov_reg_to_var("dx", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push dx
gen_push_reg("dx");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oBITORASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oBITORASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'|=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// or ax, $1
gen_or("ax", $1->rname);
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oBITANDASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oBITANDASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'&=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// and ax, $1
gen_and("ax", $1->rname);
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oBITXORASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oBITXORASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'^=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov ax, $3
gen_mov_value_to_reg($3, "ax");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// xor ax, $1
gen_xor("ax", $1->rname);
// mov $1, ax
gen_mov_reg_to_var("ax", $1);
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oLFTSHTASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oLFTSHTASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'<<=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov cx, $3
gen_mov_value_to_reg($3, "cx");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// shl $1, cl
gen_shl($1->rname, "cl");
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
| unary_expression oRITSHTASSIGN assignment_expression
{
PARSE_INFO("assignment_expression :unary_expression oRITSHTASSIGN assignment_expression")
if ( !IS_LVALUE($1) )
{
yyerror("'>>=' : left operand must be l-value");
user_exit(1);
}
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
// mov cx, $3
gen_mov_value_to_reg($3, "cx");
if ( IS_ARRAY($1) )
gen_get_array_element($1);
// shr $1, cl
gen_shr($1->rname, "cl");
del_symbol($3);
// set rvalue flag
$1->is_rvalue = 1;
if ( IS_ARRAY($1) )
{
// push ax
gen_push_reg("ax");
// set pushed flag
$1->is_pushed = 1;
}
// not push, so not set pushed flag
}
;
/*
assignment_operator
: oASSIGN
{
PARSE_INFO("assignment_operator :oASSIGN")
}
| oPLUSASSIGN
{
PARSE_INFO("assignment_operator :oPLUSASSIGN")
}
| oMINUSASSIGN
{
PARSE_INFO("assignment_operator :oMINUSASSIGN")
}
| oMULASSIGN
{
PARSE_INFO("assignment_operator :oMULASSIGN")
}
| oDIVASSIGN
{
PARSE_INFO("assignment_operator :oDIVASSIGN")
}
| oMODASSIGN
{
PARSE_INFO("assignment_operator :oMODASSIGN")
}
| oBITORASSIGN
{
PARSE_INFO("assignment_operator :oBITORASSIGN")
}
| oBITANDASSIGN
{
PARSE_INFO("assignment_operator :oBITANDASSIGN")
}
| oBITXORASSIGN
{
PARSE_INFO("assignment_operator :oBITXORASSIGN")
}
;
*/
conditional_expression
: logical_OR_expression
{
PARSE_INFO("conditional_expression :logical_OR_expression")
}
| logical_OR_expression oQUESTION expression oCOLON conditional_expression
{
symbol *p;
PARSE_INFO("conditional_expression :logical_OR_expression oQUESTION expression oCOLON conditional_expression")
if ( !$3 )
{
yyerror("empty between '?' and ':'");
user_exit(1);
}
if ( IS_CL($1) && IS_CL($3) && IS_CL($5) )
{
cast_cl_type($1, $3);
cast_cl_type($3, $5);
cast_cl_type($1, $5);
switch($1->NOUN)
{
case SPEC_CHAR:
$1->V_C = ($1->V_C ? $3->V_C : $5->V_C);
break;
case SPEC_INT:
$1->V_I = ($1->V_I ? $3->V_I : $5->V_I);
break;
case SPEC_DOUBLE:
$1->V_LF = ($1->V_LF ? $3->V_LF : $5->V_LF);
break;
case SPEC_FLOAT:
$1->V_F = ($1->V_F ? $3->V_F : $5->V_F);
break;
default:
yyerror("can't do cl operator");
user_exit(1);
}
del_symbol($3);
del_symbol($5);
p = $1;
}
else
{
char lab1[LABEL_LEN], lab2[LABEL_LEN];
strcpy(lab1, get_a_label());
strcpy(lab2, get_a_label());
// at least one is not cl
gen_mov_value_to_reg($5, "dx");
gen_mov_value_to_reg($3, "ax");
gen_mov_value_to_reg($1, "bx");
/* bx ? ax : dx */
// or bx, bx
gen_or("bx", "bx");
// jnz lab1
gen_jump("jnz", lab1);
// push dx
gen_push_reg("dx");
// jmp lab2
gen_jump("jmp", lab2);
//lab1:
gen_label(lab1);
// push ax
gen_push_reg("ax");
//lab2:
gen_label(lab2);
if ( !IS_CL($1) )
{
del_symbol($3);
del_symbol($5);
p = $1;
}
if ( !IS_CL($3) )
{
del_symbol($1);
del_symbol($5);
p = $3;
}
del_symbol($1);
del_symbol($3);
p = $5;
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
constant_expression
: conditional_expression
{
PARSE_INFO("constant_expression :conditional_expression")
}
;
logical_OR_expression
: logical_AND_expression
{
PARSE_INFO("logical_OR_expression :logical_AND_expression")
}
| logical_OR_expression oOR logical_AND_expression
{
symbol *p;
PARSE_INFO("logical_OR_expression :logical_OR_expression oOR logical_AND_expression")
if ( IS_CL($1) && IS_CL($3) )
{
cast_cl_type($1, $3);
_CL_DOUBLE_OPERATION($1, $3, ||)
del_symbol($3);
p = $1;
}
else
{
char lab1[LABEL_LEN], lab2[LABEL_LEN];
strcpy(lab1, get_a_label());
strcpy(lab2, get_a_label());
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
// or ax, ax
gen_or("ax", "ax");
// jnz lab1
gen_jump("jnz", lab1);
// or dx, dx
gen_or("dx", "dx");
// jnz lab1
gen_jump("jnz", lab1);
// xor ax, ax
gen_xor("ax", "ax");
// jmp lab2
gen_jump("jmp", lab2);
// lab1:
gen_label(lab1);
// mov ax, 1
gen_mov_cl("ax", 1);
// lab2:
gen_label(lab2);
// push ax
gen_push_reg("ax");
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
logical_AND_expression
: inclusive_OR_expression
{
PARSE_INFO("logical_AND_expression :inclusive_OR_expression")
}
| logical_AND_expression oAND inclusive_OR_expression
{
symbol *p;
PARSE_INFO("logical_AND_expression :logical_AND_expression oAND inclusive_OR_expression")
if ( IS_CL($1) && IS_CL($3) )
{
cast_cl_type($1, $3);
_CL_DOUBLE_OPERATION($1, $3, &&)
del_symbol($3);
p = $1;
}
else
{
char lab1[LABEL_LEN], lab2[LABEL_LEN];
strcpy(lab1, get_a_label());
strcpy(lab2, get_a_label());
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
// or ax, ax
gen_or("ax", "ax");
// jz lab1
gen_jump("jz", lab1);
// or dx, dx
gen_or("dx", "dx");
// jz lab1
gen_jump("jz", lab1);
// mov ax, 1
gen_mov_cl("ax", 1);
// jmp lab2
gen_jump("jmp", lab2);
// lab1:
gen_label(lab1);
// xor ax, ax
gen_xor("ax", "ax");
// lab2:
gen_label(lab2);
// push ax
gen_push_reg("ax");
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
inclusive_OR_expression
: exclusive_OR_expression
{
PARSE_INFO("inclusive_OR_expression :exclusive_OR_expression")
}
| inclusive_OR_expression oBITOR exclusive_OR_expression
{
symbol *p;
PARSE_INFO("inclusive_OR_expression :inclusive_OR_expression oBITOR exclusive_OR_expression")
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
if ( IS_CL($1) && IS_CL($3) )
{
cast_cl_type($1, $3);
_CL_DOUBLE_BIT_OPERATION($1, $3, |)
del_symbol($3);
p = $1;
}
else
{
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
// or ax, dx
gen_or("ax", "dx");
// push ax
gen_push_reg("ax");
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
exclusive_OR_expression
: AND_expression
{
PARSE_INFO("exclusive_OR_expression :AND_expression")
}
| exclusive_OR_expression oBITXOR AND_expression
{
symbol *p;
PARSE_INFO("exclusive_OR_expression :exclusive_OR_expression oBITXOR AND_expression")
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
if ( IS_CL($1) && IS_CL($3) )
{
cast_cl_type($1, $3);
_CL_DOUBLE_BIT_OPERATION($1, $3, ^)
del_symbol($3);
p = $1;
}
else
{
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
// xor ax, dx
gen_xor("ax", "dx");
// push ax
gen_push_reg("ax");
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
AND_expression
: equality_expression
{
PARSE_INFO("AND_expression :equality_expression")
}
| AND_expression oBITAND equality_expression
{
symbol *p;
PARSE_INFO("AND_expression :AND_expression oBITAND equality_expression")
CHECK_BIT_OP_TYPE($1)
CHECK_BIT_OP_TYPE($3)
if ( IS_CL($1) && IS_CL($3) )
{
cast_cl_type($1, $3);
_CL_DOUBLE_BIT_OPERATION($1, $3, &)
del_symbol($3);
p = $1;
}
else
{
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
// and ax, dx
gen_and("ax", "dx");
// push ax
gen_push_reg("ax");
// set rvalue flag
p->is_rvalue = 1;
// set pused flag
p->is_pushed = 1;
}
$$ = p;
}
;
equality_expression
: relational_expression
{
PARSE_INFO("equality_expression :relational_expression")
}
| equality_expression oEQUAL relational_expression
{
symbol *p;
PARSE_INFO("equality_expression :equality_expression oEQUAL relational_expression")
if ( IS_CL($1) && IS_CL($3) )
{
// calcu it
cast_cl_type($1, $3);
_CL_DOUBLE_OPERATION($1, $3, ==)
del_symbol($3);
p = $1;
}
else
{
char lab1[LABEL_LEN], lab2[LABEL_LEN];
strcpy(lab1, get_a_label());
strcpy(lab2, get_a_label());
p = gen_get_two_op_not_cl($1, $3, "ax", "dx");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -