Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Added support syntax assign-bitwise operators #1103

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Library/Expression/Builder/Operators/AssignVariableOperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ class AssignVariableOperator extends AbstractOperator
// %=
const OPERATOR_MOD = 'mod-assign';

// &=
const OPERATOR_BITWISE_AND = 'bitwise-and-assign';

// |=
const OPERATOR_BITWISE_OR = 'bitwise-or-assign';

// ^=
const OPERATOR_BITWISE_XOR = 'bitwise-xor-assign';

// <<=
const OPERATOR_BITWISE_SHIFTLEFT = 'bitwise-shiftleft-assign';

// >>=
const OPERATOR_BITWISE_SHIFTRIGHT = 'bitwise-shiftright-assign';



private $variable;
private $operator = self::OPERATOR_ASSIGN;
Expand Down
57 changes: 57 additions & 0 deletions Library/Statements/LetStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
use Zephir\Statements\Let\Incr as LetIncr;
use Zephir\Statements\Let\ExportSymbol as LetExportSymbol;
use Zephir\Statements\Let\ExportSymbolString as LetExportSymbolString;
use Zephir\Expression\Builder\BuilderFactory;
use Zephir\Expression\Builder\Operators\AssignVariableOperator;
use Zephir\Expression\Builder\Operators\BinaryOperator;

/**
* LetStatement
Expand Down Expand Up @@ -98,6 +101,12 @@ public function compile(CompilationContext $compilationContext)
* Incr/Decr assignments don't require an expression
*/
if (isset($assignment['expr'])) {
/**
* Replace on direct-assignment if this bitwise-assignment
* @Todo: Replace on supported native bitwise-assignment
*/
$assignment = $this->replaceAssignBitwiseOnDirect($assignment);

$expr = new Expression($assignment['expr']);

switch ($assignment['assign-type']) {
Expand Down Expand Up @@ -249,4 +258,52 @@ public function compile(CompilationContext $compilationContext)
}
}
}

/**
* @param $assignment
* @return mixed
* @throws CompilerException
*/
protected function replaceAssignBitwiseOnDirect($assignment)
{
switch ($assignment['operator']) {
case AssignVariableOperator::OPERATOR_BITWISE_AND:
$operator = BinaryOperator::OPERATOR_BITWISE_AND;
break;

case AssignVariableOperator::OPERATOR_BITWISE_OR:
$operator = BinaryOperator::OPERATOR_BITWISE_OR;
break;

case AssignVariableOperator::OPERATOR_BITWISE_XOR:
$operator = BinaryOperator::OPERATOR_BITWISE_XOR;
break;

case AssignVariableOperator::OPERATOR_BITWISE_SHIFTLEFT:
$operator = BinaryOperator::OPERATOR_BITWISE_SHIFT_LEFT;
break;

case AssignVariableOperator::OPERATOR_BITWISE_SHIFTRIGHT:
$operator = BinaryOperator::OPERATOR_BITWISE_SHIFT_RIGHT;
break;

default:
return $assignment;
}

if ($assignment['assign-type'] != 'variable') {
throw new CompilerException("Operator '" . $assignment['operator'] . "' is not supported assign-type: " . $assignment['assign-type']);
}

$builderExpr = BuilderFactory::getInstance();

$leftExpression = $builderExpr->variable($assignment['variable']);

$assignment['expr'] = $builderExpr->operators()
->binary($operator, $leftExpression, $builderExpr->raw($assignment['expr']))
->build();

$assignment['operator'] = AssignVariableOperator::OPERATOR_ASSIGN;
return $assignment;
}
}
39 changes: 27 additions & 12 deletions parser/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,23 +315,38 @@ int xx_parse_program(char *program, unsigned int program_length, char *file_path
case XX_T_ASSIGN:
xx_(xx_parser, XX_ASSIGN, NULL, parser_status);
break;
case XX_T_ADDASSIGN:
xx_(xx_parser, XX_ADDASSIGN, NULL, parser_status);
case XX_T_ASSIGN_ADD:
xx_(xx_parser, XX_ASSIGN_ADD, NULL, parser_status);
break;
case XX_T_SUBASSIGN:
xx_(xx_parser, XX_SUBASSIGN, NULL, parser_status);
case XX_T_ASSIGN_SUB:
xx_(xx_parser, XX_ASSIGN_SUB, NULL, parser_status);
break;
case XX_T_DIVASSIGN:
xx_(xx_parser, XX_DIVASSIGN, NULL, parser_status);
case XX_T_ASSIGN_DIV:
xx_(xx_parser, XX_ASSIGN_DIV, NULL, parser_status);
break;
case XX_T_MULASSIGN:
xx_(xx_parser, XX_MULASSIGN, NULL, parser_status);
case XX_T_ASSIGN_MUL:
xx_(xx_parser, XX_ASSIGN_MUL, NULL, parser_status);
break;
case XX_T_CONCATASSIGN:
xx_(xx_parser, XX_CONCATASSIGN, NULL, parser_status);
case XX_T_ASSIGN_CONCAT:
xx_(xx_parser, XX_ASSIGN_CONCAT, NULL, parser_status);
break;
case XX_T_MODASSIGN:
xx_(xx_parser, XX_MODASSIGN, NULL, parser_status);
case XX_T_ASSIGN_MOD:
xx_(xx_parser, XX_ASSIGN_MOD, NULL, parser_status);
break;
case XX_T_ASSIGN_BITWISE_AND:
xx_(xx_parser, XX_ASSIGN_BITWISE_AND, NULL, parser_status);
break;
case XX_T_ASSIGN_BITWISE_OR:
xx_(xx_parser, XX_ASSIGN_BITWISE_OR, NULL, parser_status);
break;
case XX_T_ASSIGN_BITWISE_XOR:
xx_(xx_parser, XX_ASSIGN_BITWISE_XOR, NULL, parser_status);
break;
case XX_T_ASSIGN_BITWISE_SHIFTLEFT:
xx_(xx_parser, XX_ASSIGN_BITWISE_SHIFTLEFT, NULL, parser_status);
break;
case XX_T_ASSIGN_BITWISE_SHIFTRIGHT:
xx_(xx_parser, XX_ASSIGN_BITWISE_SHIFTRIGHT, NULL, parser_status);
break;
case XX_T_EQUALS:
xx_(xx_parser, XX_EQUALS, NULL, parser_status);
Expand Down
49 changes: 27 additions & 22 deletions parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,30 @@
#define XX_IN 102
#define XX_REVERSE 103
#define XX_LET 104
#define XX_ADDASSIGN 105
#define XX_SUBASSIGN 106
#define XX_MULASSIGN 107
#define XX_DIVASSIGN 108
#define XX_CONCATASSIGN 109
#define XX_MODASSIGN 110
#define XX_STRING 111
#define XX_DOUBLECOLON 112
#define XX_INCR 113
#define XX_DECR 114
#define XX_ECHO 115
#define XX_RETURN 116
#define XX_UNSET 117
#define XX_THROW 118
#define XX_PLUS 119
#define XX_INTEGER 120
#define XX_ISTRING 121
#define XX_CHAR 122
#define XX_DOUBLE 123
#define XX_TRUE 124
#define XX_FALSE 125
#define XX_CBLOCK 126
#define XX_ASSIGN_ADD 105
#define XX_ASSIGN_SUB 106
#define XX_ASSIGN_MUL 107
#define XX_ASSIGN_DIV 108
#define XX_ASSIGN_CONCAT 109
#define XX_ASSIGN_MOD 110
#define XX_ASSIGN_BITWISE_AND 111
#define XX_ASSIGN_BITWISE_OR 112
#define XX_ASSIGN_BITWISE_XOR 113
#define XX_ASSIGN_BITWISE_SHIFTLEFT 114
#define XX_ASSIGN_BITWISE_SHIFTRIGHT 115
#define XX_STRING 116
#define XX_DOUBLECOLON 117
#define XX_INCR 118
#define XX_DECR 119
#define XX_ECHO 120
#define XX_RETURN 121
#define XX_UNSET 122
#define XX_THROW 123
#define XX_PLUS 124
#define XX_INTEGER 125
#define XX_ISTRING 126
#define XX_CHAR 127
#define XX_DOUBLE 128
#define XX_TRUE 129
#define XX_FALSE 130
#define XX_CBLOCK 131
37 changes: 31 additions & 6 deletions parser/parser.lemon
Original file line number Diff line number Diff line change
Expand Up @@ -2421,35 +2421,60 @@ xx_assignment_operator(R) ::= ASSIGN . {
}

// +=
xx_assignment_operator(R) ::= ADDASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_ADD . {
R = json_object_new_string("add-assign");
}

// -=
xx_assignment_operator(R) ::= SUBASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_SUB . {
R = json_object_new_string("sub-assign");
}

// *=
xx_assignment_operator(R) ::= MULASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_MUL . {
R = json_object_new_string("mul-assign");
}

// /=
xx_assignment_operator(R) ::= DIVASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_DIV . {
R = json_object_new_string("div-assign");
}

// .=
xx_assignment_operator(R) ::= CONCATASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_CONCAT . {
R = json_object_new_string("concat-assign");
}

// %=
xx_assignment_operator(R) ::= MODASSIGN . {
xx_assignment_operator(R) ::= ASSIGN_MOD . {
R = json_object_new_string("mod-assign");
}

// &=
xx_assignment_operator(R) ::= ASSIGN_BITWISE_AND . {
R = json_object_new_string("bitwise-and-assign");
}

// |=
xx_assignment_operator(R) ::= ASSIGN_BITWISE_OR . {
R = json_object_new_string("bitwise-or-assign");
}

// ^=
xx_assignment_operator(R) ::= ASSIGN_BITWISE_XOR . {
R = json_object_new_string("bitwise-xor-assign");
}

// <<=
xx_assignment_operator(R) ::= ASSIGN_BITWISE_SHIFTLEFT . {
R = json_object_new_string("bitwise-shiftleft-assign");
}

// >>=
xx_assignment_operator(R) ::= ASSIGN_BITWISE_SHIFTRIGHT . {
R = json_object_new_string("bitwise-shiftright-assign");
}

/* y = {expr} */
xx_let_assignment(R) ::= IDENTIFIER(I) xx_assignment_operator(O) xx_assign_expr(E) . {
R = xx_ret_let_assignment("variable", O, I, NULL, NULL, E, status->scanner_state);
Expand Down
18 changes: 12 additions & 6 deletions parser/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@
#define XX_T_BITWISE_NOT '~'
#define XX_T_GREATEREQUAL 408
#define XX_T_LESSEQUAL 409
#define XX_T_ADDASSIGN 410
#define XX_T_SUBASSIGN 411
#define XX_T_MULASSIGN 412
#define XX_T_DIVASSIGN 413
#define XX_T_CONCATASSIGN 414
#define XX_T_ASSIGN_ADD 410
#define XX_T_ASSIGN_SUB 411
#define XX_T_ASSIGN_MUL 412
#define XX_T_ASSIGN_DIV 413
#define XX_T_ASSIGN_CONCAT 414
#define XX_T_AND 415
#define XX_T_OR 416
#define XX_T_DOUBLECOLON 417
#define XX_T_MODASSIGN 418
#define XX_T_ASSIGN_MOD 418
#define XX_T_BITWISE_SHIFTLEFT 419
#define XX_T_BITWISE_SHIFTRIGHT 420
#define XX_T_DOUBLEARROW 440
Expand All @@ -158,6 +158,12 @@
#define XX_T_ELSEIF 452
#define XX_T_INTERNAL 453

#define XX_T_ASSIGN_BITWISE_AND 454
#define XX_T_ASSIGN_BITWISE_OR 455
#define XX_T_ASSIGN_BITWISE_XOR 456
#define XX_T_ASSIGN_BITWISE_SHIFTLEFT 457
#define XX_T_ASSIGN_BITWISE_SHIFTRIGHT 458

/* List of tokens and their names */
typedef struct _xx_token_names {
unsigned int code;
Expand Down
42 changes: 36 additions & 6 deletions parser/scanner.re
Original file line number Diff line number Diff line change
Expand Up @@ -768,37 +768,67 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) {

"+=" {
s->active_char++;
token->opcode = XX_T_ADDASSIGN;
token->opcode = XX_T_ASSIGN_ADD;
return 0;
}

"-=" {
s->active_char++;
token->opcode = XX_T_SUBASSIGN;
token->opcode = XX_T_ASSIGN_SUB;
return 0;
}

"*=" {
s->active_char++;
token->opcode = XX_T_MULASSIGN;
token->opcode = XX_T_ASSIGN_MUL;
return 0;
}

"/=" {
s->active_char++;
token->opcode = XX_T_DIVASSIGN;
token->opcode = XX_T_ASSIGN_DIV;
return 0;
}

"%=" {
s->active_char++;
token->opcode = XX_T_MODASSIGN;
token->opcode = XX_T_ASSIGN_MOD;
return 0;
}

"&=" {
s->active_char++;
token->opcode = XX_T_ASSIGN_BITWISE_AND;
return 0;
}

"|=" {
s->active_char++;
token->opcode = XX_T_ASSIGN_BITWISE_OR;
return 0;
}

"^=" {
s->active_char++;
token->opcode = XX_T_ASSIGN_BITWISE_XOR;
return 0;
}

"<<=" {
s->active_char++;
token->opcode = XX_T_ASSIGN_BITWISE_SHIFTLEFT;
return 0;
}

">>=" {
s->active_char++;
token->opcode = XX_T_ASSIGN_BITWISE_SHIFTRIGHT;
return 0;
}

".=" {
s->active_char++;
token->opcode = XX_T_CONCATASSIGN;
token->opcode = XX_T_ASSIGN_CONCAT;
return 0;
}

Expand Down
Loading