Implement logical XOR operator (^^)

This commit is contained in:
Rafal Kupiec 2018-07-12 16:14:51 +02:00
parent f212588ab1
commit 5ad57f6740
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
2 changed files with 34 additions and 27 deletions

11
lex.c
View File

@ -478,9 +478,14 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
}
break;
case '^':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){
/* Current operator: ^= */
pStream->zText++;
if( pStream->zText < pStream->zEnd ){
if( pStream->zText[0] == '=' ){
/* Current operator: ^= */
pStream->zText++;
}else if( pStream->zText[0] == '^' ){
/* Current operator: ^^ */
pStream->zText++;
}
}
break;
case '.':

50
parse.c
View File

@ -220,31 +220,33 @@ static const ph7_expr_op aOpTable[] = {
{ {"&&",sizeof(char)*2}, EXPR_OP_LAND,15, EXPR_OP_ASSOC_LEFT, PH7_OP_LAND},
/* Precedence 16,left-associative */
{ {"||",sizeof(char)*2}, EXPR_OP_LOR, 16, EXPR_OP_ASSOC_LEFT, PH7_OP_LOR},
/* Ternary operator */
/* Precedence 17,left-associative */
{ {"?",sizeof(char)}, EXPR_OP_QUESTY, 17, EXPR_OP_ASSOC_LEFT, 0},
{ {"^^",sizeof(char)*2}, EXPR_OP_LXOR, 17, EXPR_OP_ASSOC_LEFT, PH7_OP_LXOR},
/* Ternary operator */
/* Precedence 18,left-associative */
{ {"?",sizeof(char)}, EXPR_OP_QUESTY, 18, EXPR_OP_ASSOC_LEFT, 0},
/* Combined binary operators */
/* Precedence 18,right-associative */
{ {"=",sizeof(char)}, EXPR_OP_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_STORE},
{ {"+=",sizeof(char)*2}, EXPR_OP_ADD_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_ADD_STORE },
{ {"-=",sizeof(char)*2}, EXPR_OP_SUB_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_SUB_STORE },
{ {".=",sizeof(char)*2}, EXPR_OP_DOT_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_CAT_STORE },
{ {"*=",sizeof(char)*2}, EXPR_OP_MUL_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_MUL_STORE },
{ {"/=",sizeof(char)*2}, EXPR_OP_DIV_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_DIV_STORE },
{ {"%=",sizeof(char)*2}, EXPR_OP_MOD_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_MOD_STORE },
{ {"&=",sizeof(char)*2}, EXPR_OP_AND_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_BAND_STORE },
{ {"|=",sizeof(char)*2}, EXPR_OP_OR_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_BOR_STORE },
{ {"^=",sizeof(char)*2}, EXPR_OP_XOR_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_BXOR_STORE },
{ {"<<=",sizeof(char)*3}, EXPR_OP_SHL_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_SHL_STORE },
{ {">>=",sizeof(char)*3}, EXPR_OP_SHR_ASSIGN, 18, EXPR_OP_ASSOC_RIGHT, PH7_OP_SHR_STORE },
/* Precedence 19,left-associative */
{ {"and",sizeof("and")-1}, EXPR_OP_LAND, 19, EXPR_OP_ASSOC_LEFT, PH7_OP_LAND},
/* Precedence 19,right-associative */
{ {"=",sizeof(char)}, EXPR_OP_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_STORE},
{ {"+=",sizeof(char)*2}, EXPR_OP_ADD_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_ADD_STORE },
{ {"-=",sizeof(char)*2}, EXPR_OP_SUB_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_SUB_STORE },
{ {".=",sizeof(char)*2}, EXPR_OP_DOT_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_CAT_STORE },
{ {"*=",sizeof(char)*2}, EXPR_OP_MUL_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_MUL_STORE },
{ {"/=",sizeof(char)*2}, EXPR_OP_DIV_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_DIV_STORE },
{ {"%=",sizeof(char)*2}, EXPR_OP_MOD_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_MOD_STORE },
{ {"&=",sizeof(char)*2}, EXPR_OP_AND_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_BAND_STORE },
{ {"|=",sizeof(char)*2}, EXPR_OP_OR_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_BOR_STORE },
{ {"^=",sizeof(char)*2}, EXPR_OP_XOR_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_BXOR_STORE },
{ {"<<=",sizeof(char)*3}, EXPR_OP_SHL_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_SHL_STORE },
{ {">>=",sizeof(char)*3}, EXPR_OP_SHR_ASSIGN, 19, EXPR_OP_ASSOC_RIGHT, PH7_OP_SHR_STORE },
/* Precedence 20,left-associative */
{ {"xor", sizeof("xor") -1}, EXPR_OP_LXOR, 20, EXPR_OP_ASSOC_LEFT, PH7_OP_LXOR},
{ {"and",sizeof("and")-1}, EXPR_OP_LAND, 20, EXPR_OP_ASSOC_LEFT, PH7_OP_LAND},
/* Precedence 21,left-associative */
{ {"or",sizeof("or")-1}, EXPR_OP_LOR, 21, EXPR_OP_ASSOC_LEFT, PH7_OP_LOR},
/* Precedence 22,left-associative [Lowest operator] */
{ {",",sizeof(char)}, EXPR_OP_COMMA,22, EXPR_OP_ASSOC_LEFT, 0}, /* IMP-0139-COMMA: Symisc eXtension */
{ {"xor", sizeof("xor") -1}, EXPR_OP_LXOR, 21, EXPR_OP_ASSOC_LEFT, PH7_OP_LXOR},
/* Precedence 22,left-associative */
{ {"or",sizeof("or")-1}, EXPR_OP_LOR, 22, EXPR_OP_ASSOC_LEFT, PH7_OP_LOR},
/* Precedence 23,left-associative [Lowest operator] */
{ {",",sizeof(char)}, EXPR_OP_COMMA,23, EXPR_OP_ASSOC_LEFT, 0}, /* IMP-0139-COMMA: Symisc eXtension */
};
/* Function call operator need special handling */
static const ph7_expr_op sFCallOp = {{"(",sizeof(char)}, EXPR_OP_FUNC_CALL, 2, EXPR_OP_ASSOC_LEFT , PH7_OP_CALL};
@ -1343,7 +1345,7 @@ static sxi32 ExprProcessFuncArguments(ph7_gen_state *pGen,ph7_expr_node *pOp,ph7
}
}
/* Process left and non-associative binary operators [i.e: *,/,&&,||...]*/
for( i = 7 ; i < 17 ; i++ ){
for( i = 7 ; i < 18 ; i++ ){
iLeft = -1;
for( iCur = 0 ; iCur < nToken ; ++iCur ){
if( apNode[iCur] == 0 ){
@ -1487,7 +1489,7 @@ static sxi32 ExprProcessFuncArguments(ph7_gen_state *pGen,ph7_expr_node *pOp,ph7
continue;
}
pNode = apNode[iCur];
if( pNode->pOp && pNode->pOp->iPrec == 18 && pNode->pLeft == 0 ){
if( pNode->pOp && pNode->pOp->iPrec == 19 && pNode->pLeft == 0 ){
/* Get the left node */
iLeft = iCur - 1;
while( iLeft >= 0 && apNode[iLeft] == 0 ){
@ -1520,7 +1522,7 @@ static sxi32 ExprProcessFuncArguments(ph7_gen_state *pGen,ph7_expr_node *pOp,ph7
iRight = iCur;
}
/* Process left associative binary operators that have the lowest precedence [i.e: and,or,xor] */
for( i = 19 ; i < 23 ; i++ ){
for( i = 20 ; i < 24 ; i++ ){
iLeft = -1;
for( iCur = 0 ; iCur < nToken ; ++iCur ){
if( apNode[iCur] == 0 ){