Skip to content

Commit

Permalink
Merge pull request #122 from zephir-lang/#118-yield-statement
Browse files Browse the repository at this point in the history
#118 - Add support for `yield` statement
  • Loading branch information
Jeckerson authored Sep 18, 2021
2 parents 5ff6c22 + 1dc8955 commit fa799a0
Show file tree
Hide file tree
Showing 11 changed files with 1,196 additions and 3 deletions.
3 changes: 3 additions & 0 deletions parser/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
case XX_T_RETURN:
xx_(xx_parser, XX_RETURN, NULL, parser_status);
break;
case XX_T_YIELD:
xx_(xx_parser, XX_YIELD, NULL, parser_status);
break;
case XX_T_REQUIRE_ONCE:
xx_(xx_parser, XX_REQUIRE_ONCE, NULL, parser_status);
break;
Expand Down
22 changes: 22 additions & 0 deletions parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,28 @@ static void xx_ret_return_statement(zval *ret, zval *expr, xx_scanner_state *sta
parser_add_int(ret, "char", state->active_char);
}

static void xx_ret_yield_statement(zval *ret, zval *expr, zval *K, zval *V, xx_scanner_state *state)
{
array_init(ret);

parser_add_str(ret, "type", "yield");
if (expr) {
parser_add_zval(ret, "expr", expr);
}

if (K) {
parser_add_zval(ret, "key", K);
}

if (V) {
parser_add_zval(ret, "value", V);
}

parser_add_str(ret, "file", state->active_file);
parser_add_int(ret, "line", state->active_line);
parser_add_int(ret, "char", state->active_char);
}

static void xx_ret_require_once_statement(zval *ret, zval *expr, xx_scanner_state *state)
{
array_init(ret);
Expand Down
1 change: 1 addition & 0 deletions parser/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
#define XX_T_CATCH 398
#define XX_T_DEPRECATED 399
#define XX_T_REQUIRE_ONCE 459
#define XX_T_YIELD 460

/* Operators */
#define XX_T_AT '@'
Expand Down
6 changes: 6 additions & 0 deletions parser/scanner.re
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,12 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) {
return 0;
}
'yield' {
s->active_char += sizeof("yield")-1;
token->opcode = XX_T_YIELD;
return 0;
}
'require' {
s->active_char += sizeof("require")-1;
token->opcode = XX_T_REQUIRE;
Expand Down
25 changes: 22 additions & 3 deletions parser/zephir.lemon
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,10 @@ xx_statement(R) ::= xx_return_statement(S) . {
R = S;
}

xx_statement(R) ::= xx_yield_statement(S) . {
R = S;
}

xx_statement(R) ::= xx_require_once_statement(S) . {
R = S;
}
Expand Down Expand Up @@ -1526,16 +1530,31 @@ xx_fetch_statement(R) ::= xx_fetch_expr(E) DOTCOMMA . {
xx_ret_fetch_statement(&R, &E, status->scanner_state);
}

/* return statement */
/* return var; */
xx_return_statement(R) ::= RETURN xx_common_expr(E) DOTCOMMA . {
xx_ret_return_statement(&R, &E, status->scanner_state);
}

/* return statement */
/* return; */
xx_return_statement(R) ::= RETURN DOTCOMMA . {
xx_ret_return_statement(&R, NULL, status->scanner_state);
}

/* yield var; */
xx_yield_statement(R) ::= YIELD xx_common_expr(E) DOTCOMMA . {
xx_ret_yield_statement(&R, &E, NULL, NULL, status->scanner_state);
}

/* yield key, val; */
xx_yield_statement(R) ::= YIELD xx_common_expr(K) COMMA xx_common_expr(V) DOTCOMMA . {
xx_ret_yield_statement(&R, NULL, &K, &V, status->scanner_state);
}

/* yield; */
xx_yield_statement(R) ::= YIELD DOTCOMMA . {
xx_ret_yield_statement(&R, NULL, NULL, NULL, status->scanner_state);
}

/* require_once statement */
xx_require_once_statement(R) ::= REQUIRE_ONCE xx_common_expr(E) DOTCOMMA . {
xx_ret_require_once_statement(&R, &E, status->scanner_state);
Expand Down Expand Up @@ -1906,7 +1925,7 @@ xx_common_expr(R) ::= NULL . {
xx_ret_literal(&R, XX_T_NULL, NULL, status->scanner_state);
}

/* y = false */
/* y = true */
xx_common_expr(R) ::= TRUE . {
xx_ret_literal(&R, XX_T_TRUE, NULL, status->scanner_state);
}
Expand Down
26 changes: 26 additions & 0 deletions tests/statements/yield/empty-yield.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
Empty yield statement
--SKIPIF--
<?php include(__DIR__ . '/../../skipif.inc'); ?>
--FILE--
<?php
$code =<<<ZEP
function test() {
yield;
}
ZEP;

$ir = zephir_parse_file($code, '(eval code)');
var_dump($ir[0]["statements"][0]);
?>
--EXPECT--
array(4) {
["type"]=>
string(5) "yield"
["file"]=>
string(11) "(eval code)"
["line"]=>
int(3)
["char"]=>
int(1)
}
119 changes: 119 additions & 0 deletions tests/statements/yield/yield-array.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
--TEST--
Array yield statement
--SKIPIF--
<?php include(__DIR__ . '/../../skipif.inc'); ?>
--FILE--
<?php
$code =<<<ZEP
function test() {
yield ['key': 'value', 'another', 'val'];
}
ZEP;

$ir = zephir_parse_file($code, '(eval code)');
var_dump($ir[0]["statements"][0]);
?>
--EXPECT--
array(5) {
["type"]=>
string(5) "yield"
["expr"]=>
array(5) {
["type"]=>
string(5) "array"
["left"]=>
array(3) {
[0]=>
array(5) {
["key"]=>
array(5) {
["type"]=>
string(4) "char"
["value"]=>
string(3) "key"
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(13)
}
["value"]=>
array(5) {
["type"]=>
string(4) "char"
["value"]=>
string(5) "value"
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(21)
}
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(21)
}
[1]=>
array(4) {
["value"]=>
array(5) {
["type"]=>
string(4) "char"
["value"]=>
string(7) "another"
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(31)
}
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(31)
}
[2]=>
array(4) {
["value"]=>
array(5) {
["type"]=>
string(4) "char"
["value"]=>
string(3) "val"
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(37)
}
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(37)
}
}
["file"]=>
string(11) "(eval code)"
["line"]=>
int(2)
["char"]=>
int(38)
}
["file"]=>
string(11) "(eval code)"
["line"]=>
int(3)
["char"]=>
int(1)
}
Loading

0 comments on commit fa799a0

Please sign in to comment.