Skip to content

Commit fa799a0

Browse files
authored
Merge pull request #122 from zephir-lang/#118-yield-statement
#118 - Add support for `yield` statement
2 parents 5ff6c22 + 1dc8955 commit fa799a0

File tree

11 files changed

+1196
-3
lines changed

11 files changed

+1196
-3
lines changed

parser/base.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length,
178178
case XX_T_RETURN:
179179
xx_(xx_parser, XX_RETURN, NULL, parser_status);
180180
break;
181+
case XX_T_YIELD:
182+
xx_(xx_parser, XX_YIELD, NULL, parser_status);
183+
break;
181184
case XX_T_REQUIRE_ONCE:
182185
xx_(xx_parser, XX_REQUIRE_ONCE, NULL, parser_status);
183186
break;

parser/parser.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,28 @@ static void xx_ret_return_statement(zval *ret, zval *expr, xx_scanner_state *sta
899899
parser_add_int(ret, "char", state->active_char);
900900
}
901901

902+
static void xx_ret_yield_statement(zval *ret, zval *expr, zval *K, zval *V, xx_scanner_state *state)
903+
{
904+
array_init(ret);
905+
906+
parser_add_str(ret, "type", "yield");
907+
if (expr) {
908+
parser_add_zval(ret, "expr", expr);
909+
}
910+
911+
if (K) {
912+
parser_add_zval(ret, "key", K);
913+
}
914+
915+
if (V) {
916+
parser_add_zval(ret, "value", V);
917+
}
918+
919+
parser_add_str(ret, "file", state->active_file);
920+
parser_add_int(ret, "line", state->active_line);
921+
parser_add_int(ret, "char", state->active_char);
922+
}
923+
902924
static void xx_ret_require_once_statement(zval *ret, zval *expr, xx_scanner_state *state)
903925
{
904926
array_init(ret);

parser/scanner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#define XX_T_CATCH 398
100100
#define XX_T_DEPRECATED 399
101101
#define XX_T_REQUIRE_ONCE 459
102+
#define XX_T_YIELD 460
102103

103104
/* Operators */
104105
#define XX_T_AT '@'

parser/scanner.re

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,12 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) {
363363
return 0;
364364
}
365365
366+
'yield' {
367+
s->active_char += sizeof("yield")-1;
368+
token->opcode = XX_T_YIELD;
369+
return 0;
370+
}
371+
366372
'require' {
367373
s->active_char += sizeof("require")-1;
368374
token->opcode = XX_T_REQUIRE;

parser/zephir.lemon

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,10 @@ xx_statement(R) ::= xx_return_statement(S) . {
986986
R = S;
987987
}
988988

989+
xx_statement(R) ::= xx_yield_statement(S) . {
990+
R = S;
991+
}
992+
989993
xx_statement(R) ::= xx_require_once_statement(S) . {
990994
R = S;
991995
}
@@ -1526,16 +1530,31 @@ xx_fetch_statement(R) ::= xx_fetch_expr(E) DOTCOMMA . {
15261530
xx_ret_fetch_statement(&R, &E, status->scanner_state);
15271531
}
15281532

1529-
/* return statement */
1533+
/* return var; */
15301534
xx_return_statement(R) ::= RETURN xx_common_expr(E) DOTCOMMA . {
15311535
xx_ret_return_statement(&R, &E, status->scanner_state);
15321536
}
15331537

1534-
/* return statement */
1538+
/* return; */
15351539
xx_return_statement(R) ::= RETURN DOTCOMMA . {
15361540
xx_ret_return_statement(&R, NULL, status->scanner_state);
15371541
}
15381542

1543+
/* yield var; */
1544+
xx_yield_statement(R) ::= YIELD xx_common_expr(E) DOTCOMMA . {
1545+
xx_ret_yield_statement(&R, &E, NULL, NULL, status->scanner_state);
1546+
}
1547+
1548+
/* yield key, val; */
1549+
xx_yield_statement(R) ::= YIELD xx_common_expr(K) COMMA xx_common_expr(V) DOTCOMMA . {
1550+
xx_ret_yield_statement(&R, NULL, &K, &V, status->scanner_state);
1551+
}
1552+
1553+
/* yield; */
1554+
xx_yield_statement(R) ::= YIELD DOTCOMMA . {
1555+
xx_ret_yield_statement(&R, NULL, NULL, NULL, status->scanner_state);
1556+
}
1557+
15391558
/* require_once statement */
15401559
xx_require_once_statement(R) ::= REQUIRE_ONCE xx_common_expr(E) DOTCOMMA . {
15411560
xx_ret_require_once_statement(&R, &E, status->scanner_state);
@@ -1906,7 +1925,7 @@ xx_common_expr(R) ::= NULL . {
19061925
xx_ret_literal(&R, XX_T_NULL, NULL, status->scanner_state);
19071926
}
19081927

1909-
/* y = false */
1928+
/* y = true */
19101929
xx_common_expr(R) ::= TRUE . {
19111930
xx_ret_literal(&R, XX_T_TRUE, NULL, status->scanner_state);
19121931
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Empty yield statement
3+
--SKIPIF--
4+
<?php include(__DIR__ . '/../../skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
$code =<<<ZEP
8+
function test() {
9+
yield;
10+
}
11+
ZEP;
12+
13+
$ir = zephir_parse_file($code, '(eval code)');
14+
var_dump($ir[0]["statements"][0]);
15+
?>
16+
--EXPECT--
17+
array(4) {
18+
["type"]=>
19+
string(5) "yield"
20+
["file"]=>
21+
string(11) "(eval code)"
22+
["line"]=>
23+
int(3)
24+
["char"]=>
25+
int(1)
26+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
--TEST--
2+
Array yield statement
3+
--SKIPIF--
4+
<?php include(__DIR__ . '/../../skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
$code =<<<ZEP
8+
function test() {
9+
yield ['key': 'value', 'another', 'val'];
10+
}
11+
ZEP;
12+
13+
$ir = zephir_parse_file($code, '(eval code)');
14+
var_dump($ir[0]["statements"][0]);
15+
?>
16+
--EXPECT--
17+
array(5) {
18+
["type"]=>
19+
string(5) "yield"
20+
["expr"]=>
21+
array(5) {
22+
["type"]=>
23+
string(5) "array"
24+
["left"]=>
25+
array(3) {
26+
[0]=>
27+
array(5) {
28+
["key"]=>
29+
array(5) {
30+
["type"]=>
31+
string(4) "char"
32+
["value"]=>
33+
string(3) "key"
34+
["file"]=>
35+
string(11) "(eval code)"
36+
["line"]=>
37+
int(2)
38+
["char"]=>
39+
int(13)
40+
}
41+
["value"]=>
42+
array(5) {
43+
["type"]=>
44+
string(4) "char"
45+
["value"]=>
46+
string(5) "value"
47+
["file"]=>
48+
string(11) "(eval code)"
49+
["line"]=>
50+
int(2)
51+
["char"]=>
52+
int(21)
53+
}
54+
["file"]=>
55+
string(11) "(eval code)"
56+
["line"]=>
57+
int(2)
58+
["char"]=>
59+
int(21)
60+
}
61+
[1]=>
62+
array(4) {
63+
["value"]=>
64+
array(5) {
65+
["type"]=>
66+
string(4) "char"
67+
["value"]=>
68+
string(7) "another"
69+
["file"]=>
70+
string(11) "(eval code)"
71+
["line"]=>
72+
int(2)
73+
["char"]=>
74+
int(31)
75+
}
76+
["file"]=>
77+
string(11) "(eval code)"
78+
["line"]=>
79+
int(2)
80+
["char"]=>
81+
int(31)
82+
}
83+
[2]=>
84+
array(4) {
85+
["value"]=>
86+
array(5) {
87+
["type"]=>
88+
string(4) "char"
89+
["value"]=>
90+
string(3) "val"
91+
["file"]=>
92+
string(11) "(eval code)"
93+
["line"]=>
94+
int(2)
95+
["char"]=>
96+
int(37)
97+
}
98+
["file"]=>
99+
string(11) "(eval code)"
100+
["line"]=>
101+
int(2)
102+
["char"]=>
103+
int(37)
104+
}
105+
}
106+
["file"]=>
107+
string(11) "(eval code)"
108+
["line"]=>
109+
int(2)
110+
["char"]=>
111+
int(38)
112+
}
113+
["file"]=>
114+
string(11) "(eval code)"
115+
["line"]=>
116+
int(3)
117+
["char"]=>
118+
int(1)
119+
}

0 commit comments

Comments
 (0)