diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a971e75..f777c233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [1.4.0] - 2021-09-18 +### Added +- Added support for `mixed` type [#120](https://github.com/phalcon/php-zephir-parser/issues/120) +- Added support for `yield` statement [#118](https://github.com/phalcon/php-zephir-parser/issues/118) + ## [1.3.8] - 2021-09-08 ### Changed - Changed CI from AppVeyor to Github Actions [#110](https://github.com/phalcon/php-zephir-parser/issues/110) @@ -168,7 +173,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Initial stable release -[Unreleased]: https://github.com/phalcon/php-zephir-parser/compare/v1.3.8...HEAD +[Unreleased]: https://github.com/phalcon/php-zephir-parser/compare/v1.4.0...HEAD +[1.4.0]: https://github.com/phalcon/php-zephir-parser/compare/v1.3.8...v1.4.0 [1.3.8]: https://github.com/phalcon/php-zephir-parser/compare/v1.3.7...v1.3.8 [1.3.7]: https://github.com/phalcon/php-zephir-parser/compare/v1.3.6...v1.3.7 [1.3.6]: https://github.com/phalcon/php-zephir-parser/compare/v1.3.5...v1.3.6 diff --git a/LICENSE b/LICENSE index c2467cd8..da2f50ab 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License -Copyright (c) 2013-2019 Zephir Team +Copyright (c) 2013-present Zephir Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/VERSION b/VERSION index e05cb332..88c5fb89 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.8 +1.4.0 diff --git a/config.m4 b/config.m4 index 2f16e6be..1a7c7d10 100644 --- a/config.m4 +++ b/config.m4 @@ -68,6 +68,11 @@ if test "$PHP_ZEPHIR_PARSER" = "yes"; then [PHP_INSTALL_HEADERS([ext/zephir_parser], $PHP_ZEPHIR_PARSER_HEADERS)]) PHP_ADD_MAKEFILE_FRAGMENT([parser.mk]) + + dnl Create directories because PECL can't + if test ! -d parser; then + mkdir parser + fi fi dnl Code Coverage ------------------------------------------------------------- diff --git a/package.xml b/package.xml new file mode 100644 index 00000000..8a7a31b2 --- /dev/null +++ b/package.xml @@ -0,0 +1,69 @@ + + + zephir_parser + pecl.php.net + Zephir code parser. + Zephir Parser is a code parser, delivered as a C extension for the PHP language. + + Anton Vasiliev + jeckerson + anton@phalcon.io + yes + + 2021-09-18 + + + 1.4.0 + 1.4.0 + + + stable + stable + + MIT + + Sat, Sep 18, 2021 - Zephir Parser 1.4.0 + + = New features: + + - Fixed issue #120: Add support for `mixed` type + - Fixed issue #118: Add support for `yield` statement + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.0.0 + 8.0.99 + + + 1.10 + + + + zephir_parser + + diff --git a/parser/base.c b/parser/base.c index 19b87db9..cb367954 100644 --- a/parser/base.c +++ b/parser/base.c @@ -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; @@ -444,6 +447,9 @@ void xx_parse_program(zval *return_value, char *program, size_t program_length, case XX_T_TYPE_RESOURCE: xx_(xx_parser, XX_TYPE_RESOURCE, NULL, parser_status); break; + case XX_T_TYPE_MIXED: + xx_(xx_parser, XX_TYPE_MIXED, NULL, parser_status); + break; case XX_T_TYPE_CALLABLE: xx_(xx_parser, XX_TYPE_CALLABLE, NULL, parser_status); break; diff --git a/parser/parser.h b/parser/parser.h index 1240979d..90479487 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -534,7 +534,6 @@ static void xx_ret_return_type_item(zval *ret, zval *type, zval *cast, int manda static void xx_ret_type(zval *ret, int type) { switch (type) { - case XX_TYPE_INTEGER: parser_get_string(ret, "int"); return; @@ -587,6 +586,10 @@ static void xx_ret_type(zval *ret, int type) parser_get_string(ret, "object"); return; + case XX_TYPE_MIXED: + parser_get_string(ret, "mixed"); + return; + case XX_T_TYPE_NULL: parser_get_string(ret, "null"); return; @@ -896,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); @@ -1040,6 +1065,10 @@ static void xx_ret_declare_statement(zval *ret, int type, zval *variables, xx_sc parser_add_str(ret, "data-type", "resource"); break; + case XX_T_TYPE_MIXED: + parser_add_str(ret, "data-type", "mixed"); + break; + case XX_T_TYPE_OBJECT: parser_add_str(ret, "data-type", "object"); break; diff --git a/parser/scanner.h b/parser/scanner.h index 104e8400..8ccb6685 100644 --- a/parser/scanner.h +++ b/parser/scanner.h @@ -46,6 +46,7 @@ #define XX_T_TYPE_RESOURCE 333 #define XX_T_TYPE_NULL 334 #define XX_T_TYPE_THIS 335 +#define XX_T_TYPE_MIXED 336 #define XX_T_NAMESPACE 350 #define XX_T_CLASS 351 @@ -98,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 '@' diff --git a/parser/scanner.re b/parser/scanner.re index 88b11a05..661c73ad 100644 --- a/parser/scanner.re +++ b/parser/scanner.re @@ -297,6 +297,12 @@ int xx_get_token(xx_scanner_state *s, xx_scanner_token *token) { return 0; } + 'mixed' { + s->active_char += sizeof("mixed")-1; + token->opcode = XX_T_TYPE_MIXED; + return 0; + } + 'if' { s->active_char += sizeof("if")-1; token->opcode = XX_T_IF; @@ -357,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; diff --git a/parser/zephir.lemon b/parser/zephir.lemon index 5abbddc1..4315c280 100644 --- a/parser/zephir.lemon +++ b/parser/zephir.lemon @@ -946,6 +946,10 @@ xx_parameter_type(R) ::= TYPE_RESOURCE . { xx_ret_type(&R, XX_TYPE_RESOURCE); } +xx_parameter_type(R) ::= TYPE_MIXED . { + xx_ret_type(&R, XX_TYPE_MIXED); +} + xx_parameter_type(R) ::= TYPE_OBJECT . { xx_ret_type(&R, XX_TYPE_OBJECT); } @@ -982,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; } @@ -1522,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); @@ -1596,6 +1619,10 @@ xx_declare_statement(R) ::= TYPE_ARRAY xx_declare_variable_list(L) DOTCOMMA . { xx_ret_declare_statement(&R, XX_T_TYPE_ARRAY, &L, status->scanner_state); } +xx_declare_statement(R) ::= TYPE_MIXED xx_declare_variable_list(L) DOTCOMMA . { + xx_ret_declare_statement(&R, XX_T_TYPE_MIXED, &L, status->scanner_state); +} + xx_declare_variable_list(R) ::= xx_declare_variable_list(L) COMMA xx_declare_variable(V) . { xx_ret_list(&R, &L, &V, status->scanner_state); } @@ -1898,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); } diff --git a/tests/functions/parameter-types/int.phpt b/tests/functions/parameter-types/int.phpt new file mode 100644 index 00000000..354dc7f5 --- /dev/null +++ b/tests/functions/parameter-types/int.phpt @@ -0,0 +1,53 @@ +--TEST-- +Parameter type 'int' +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(4) "test" + ["parameters"]=> + array(1) { + [0]=> + array(9) { + ["type"]=> + string(9) "parameter" + ["name"]=> + string(5) "value" + ["const"]=> + int(0) + ["data-type"]=> + string(3) "int" + ["mandatory"]=> + int(0) + ["reference"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(25) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(9) + } +} diff --git a/tests/functions/parameter-types/mixed.phpt b/tests/functions/parameter-types/mixed.phpt new file mode 100644 index 00000000..92e5371c --- /dev/null +++ b/tests/functions/parameter-types/mixed.phpt @@ -0,0 +1,53 @@ +--TEST-- +Parameter type 'mixed' +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(4) "test" + ["parameters"]=> + array(1) { + [0]=> + array(9) { + ["type"]=> + string(9) "parameter" + ["name"]=> + string(5) "value" + ["const"]=> + int(0) + ["data-type"]=> + string(5) "mixed" + ["mandatory"]=> + int(0) + ["reference"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(27) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(9) + } +} diff --git a/tests/functions/return-types/int.phpt b/tests/functions/return-types/int.phpt new file mode 100644 index 00000000..38a6c8a9 --- /dev/null +++ b/tests/functions/return-types/int.phpt @@ -0,0 +1,60 @@ +--TEST-- +Function definition with mandatory return type +--SKIPIF-- + +--FILE-- + int { } +ZEP; + +$ir = zephir_parse_file($code, '(eval code)'); +var_dump($ir); +?> +--EXPECT-- +array(1) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(4) "test" + ["return-type"]=> + array(6) { + ["type"]=> + string(11) "return-type" + ["list"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(21) "return-type-parameter" + ["data-type"]=> + string(3) "int" + ["mandatory"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(25) + } + } + ["void"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(25) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(9) + } +} diff --git a/tests/functions/return-types/mixed.phpt b/tests/functions/return-types/mixed.phpt new file mode 100644 index 00000000..d85bad8d --- /dev/null +++ b/tests/functions/return-types/mixed.phpt @@ -0,0 +1,60 @@ +--TEST-- +Function definition with void +--SKIPIF-- + +--FILE-- + mixed { } +ZEP; + +$ir = zephir_parse_file($code, '(eval code)'); +var_dump($ir); +?> +--EXPECT-- +array(1) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(4) "test" + ["return-type"]=> + array(6) { + ["type"]=> + string(11) "return-type" + ["list"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(21) "return-type-parameter" + ["data-type"]=> + string(5) "mixed" + ["mandatory"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(27) + } + } + ["void"]=> + int(0) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(27) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(1) + ["char"]=> + int(9) + } +} diff --git a/tests/statements/yield/empty-yield.phpt b/tests/statements/yield/empty-yield.phpt new file mode 100644 index 00000000..5a99587f --- /dev/null +++ b/tests/statements/yield/empty-yield.phpt @@ -0,0 +1,26 @@ +--TEST-- +Empty yield statement +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(4) { + ["type"]=> + string(5) "yield" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(3) + ["char"]=> + int(1) +} diff --git a/tests/statements/yield/yield-array.phpt b/tests/statements/yield/yield-array.phpt new file mode 100644 index 00000000..3577185b --- /dev/null +++ b/tests/statements/yield/yield-array.phpt @@ -0,0 +1,119 @@ +--TEST-- +Array yield statement +--SKIPIF-- + +--FILE-- + +--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) +} diff --git a/tests/statements/yield/yield-closure.phpt b/tests/statements/yield/yield-closure.phpt new file mode 100644 index 00000000..7051b969 --- /dev/null +++ b/tests/statements/yield/yield-closure.phpt @@ -0,0 +1,499 @@ +--TEST-- +Key => value complex yield statement inside closure +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(17) "loop_from_closure" + ["statements"]=> + array(4) { + [0]=> + array(6) { + ["type"]=> + string(7) "declare" + ["data-type"]=> + string(8) "variable" + ["variables"]=> + array(4) { + [0]=> + array(4) { + ["variable"]=> + string(7) "closure" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(16) + } + [1]=> + array(4) { + ["variable"]=> + string(9) "generator" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(27) + } + [2]=> + array(4) { + ["variable"]=> + string(3) "key" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(32) + } + [3]=> + array(4) { + ["variable"]=> + string(5) "value" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(39) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(7) + } + [1]=> + array(5) { + ["type"]=> + string(3) "let" + ["assignments"]=> + array(1) { + [0]=> + array(7) { + ["assign-type"]=> + string(8) "variable" + ["operator"]=> + string(6) "assign" + ["variable"]=> + string(7) "closure" + ["expr"]=> + array(5) { + ["type"]=> + string(7) "closure" + ["right"]=> + array(2) { + [0]=> + array(6) { + ["type"]=> + string(7) "declare" + ["data-type"]=> + string(8) "variable" + ["variables"]=> + array(2) { + [0]=> + array(4) { + ["variable"]=> + string(1) "k" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(5) + ["char"]=> + int(14) + } + [1]=> + array(4) { + ["variable"]=> + string(1) "v" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(5) + ["char"]=> + int(17) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(11) + } + [1]=> + array(9) { + ["type"]=> + string(3) "for" + ["expr"]=> + array(5) { + ["type"]=> + string(5) "array" + ["left"]=> + array(4) { + [0]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "a" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(23) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(23) + } + [1]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "b" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(26) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(26) + } + [2]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "c" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(29) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(29) + } + [3]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "d" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(32) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(32) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(34) + } + ["key"]=> + string(1) "k" + ["value"]=> + string(1) "v" + ["reverse"]=> + int(0) + ["statements"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(5) "yield" + ["key"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(1) "k" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(8) + ["char"]=> + int(20) + } + ["value"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(1) "v" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(8) + ["char"]=> + int(23) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(9) + ["char"]=> + int(9) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(10) + ["char"]=> + int(5) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(10) + ["char"]=> + int(6) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(10) + ["char"]=> + int(6) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(12) + ["char"]=> + int(7) + } + [2]=> + array(5) { + ["type"]=> + string(3) "let" + ["assignments"]=> + array(1) { + [0]=> + array(7) { + ["assign-type"]=> + string(8) "variable" + ["operator"]=> + string(6) "assign" + ["variable"]=> + string(9) "generator" + ["expr"]=> + array(6) { + ["type"]=> + string(5) "fcall" + ["name"]=> + string(7) "closure" + ["call-type"]=> + int(1) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(12) + ["char"]=> + int(30) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(12) + ["char"]=> + int(30) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(7) + } + [3]=> + array(9) { + ["type"]=> + string(3) "for" + ["expr"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(9) "generator" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(33) + } + ["key"]=> + string(3) "key" + ["value"]=> + string(5) "value" + ["reverse"]=> + int(0) + ["statements"]=> + array(1) { + [0]=> + array(5) { + ["type"]=> + string(4) "echo" + ["expressions"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(6) "concat" + ["left"]=> + array(6) { + ["type"]=> + string(6) "concat" + ["left"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(3) "key" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(18) + } + ["right"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "-" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(22) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(22) + } + ["right"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(3) "val" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(27) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(27) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(15) + ["char"]=> + int(5) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(16) + ["char"]=> + int(1) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(26) + } +} diff --git a/tests/statements/yield/yield-key-value-variables.phpt b/tests/statements/yield/yield-key-value-variables.phpt new file mode 100644 index 00000000..4b87a1ef --- /dev/null +++ b/tests/statements/yield/yield-key-value-variables.phpt @@ -0,0 +1,407 @@ +--TEST-- +Key => value complex yield statement +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(8) "generate" + ["statements"]=> + array(2) { + [0]=> + array(6) { + ["type"]=> + string(7) "declare" + ["data-type"]=> + string(8) "variable" + ["variables"]=> + array(2) { + [0]=> + array(4) { + ["variable"]=> + string(1) "k" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(10) + } + [1]=> + array(4) { + ["variable"]=> + string(1) "v" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(13) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(7) + } + [1]=> + array(9) { + ["type"]=> + string(3) "for" + ["expr"]=> + array(5) { + ["type"]=> + string(5) "array" + ["left"]=> + array(4) { + [0]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "a" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(19) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(19) + } + [1]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "b" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(22) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(22) + } + [2]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "c" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(25) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(25) + } + [3]=> + array(4) { + ["value"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "d" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(28) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(28) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(4) + ["char"]=> + int(30) + } + ["key"]=> + string(1) "k" + ["value"]=> + string(1) "v" + ["reverse"]=> + int(0) + ["statements"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(5) "yield" + ["key"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(1) "k" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(5) + ["char"]=> + int(16) + } + ["value"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(1) "v" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(5) + ["char"]=> + int(19) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(6) + ["char"]=> + int(5) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(7) + ["char"]=> + int(1) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(9) + ["char"]=> + int(8) + } + [1]=> + array(6) { + ["type"]=> + string(8) "function" + ["name"]=> + string(14) "loop_generator" + ["statements"]=> + array(2) { + [0]=> + array(6) { + ["type"]=> + string(7) "declare" + ["data-type"]=> + string(8) "variable" + ["variables"]=> + array(2) { + [0]=> + array(4) { + ["variable"]=> + string(3) "key" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(10) + ["char"]=> + int(12) + } + [1]=> + array(4) { + ["variable"]=> + string(5) "value" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(10) + ["char"]=> + int(19) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(12) + ["char"]=> + int(7) + } + [1]=> + array(9) { + ["type"]=> + string(3) "for" + ["expr"]=> + array(6) { + ["type"]=> + string(5) "fcall" + ["name"]=> + string(8) "generate" + ["call-type"]=> + int(1) + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(12) + ["char"]=> + int(34) + } + ["key"]=> + string(3) "key" + ["value"]=> + string(5) "value" + ["reverse"]=> + int(0) + ["statements"]=> + array(1) { + [0]=> + array(5) { + ["type"]=> + string(4) "echo" + ["expressions"]=> + array(1) { + [0]=> + array(6) { + ["type"]=> + string(6) "concat" + ["left"]=> + array(6) { + ["type"]=> + string(6) "concat" + ["left"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(3) "key" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(18) + } + ["right"]=> + array(5) { + ["type"]=> + string(6) "string" + ["value"]=> + string(1) "-" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(22) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(22) + } + ["right"]=> + array(5) { + ["type"]=> + string(8) "variable" + ["value"]=> + string(3) "val" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(27) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(13) + ["char"]=> + int(27) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(14) + ["char"]=> + int(5) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(15) + ["char"]=> + int(1) + } + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(9) + ["char"]=> + int(8) + } +} diff --git a/tests/statements/yield/yield-key-value.phpt b/tests/statements/yield/yield-key-value.phpt new file mode 100644 index 00000000..25ed62a5 --- /dev/null +++ b/tests/statements/yield/yield-key-value.phpt @@ -0,0 +1,52 @@ +--TEST-- +Key => value yield statement +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(6) { + ["type"]=> + string(5) "yield" + ["key"]=> + array(5) { + ["type"]=> + string(4) "char" + ["value"]=> + string(3) "key" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(12) + } + ["value"]=> + array(5) { + ["type"]=> + string(4) "char" + ["value"]=> + string(5) "value" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(20) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(3) + ["char"]=> + int(1) +} diff --git a/tests/statements/yield/yield-value.phpt b/tests/statements/yield/yield-value.phpt new file mode 100644 index 00000000..b0bf7f0f --- /dev/null +++ b/tests/statements/yield/yield-value.phpt @@ -0,0 +1,39 @@ +--TEST-- +Value yield statement +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(5) { + ["type"]=> + string(5) "yield" + ["expr"]=> + array(5) { + ["type"]=> + string(4) "char" + ["value"]=> + string(5) "value" + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(2) + ["char"]=> + int(14) + } + ["file"]=> + string(11) "(eval code)" + ["line"]=> + int(3) + ["char"]=> + int(1) +} diff --git a/zephir_parser.h b/zephir_parser.h index 1ef08044..95c96bb5 100644 --- a/zephir_parser.h +++ b/zephir_parser.h @@ -15,7 +15,7 @@ extern zend_module_entry zephir_parser_module_entry; #define phpext_zephir_parser_ptr &zephir_parser_module_entry #define PHP_ZEPHIR_PARSER_NAME "Zephir Parser" -#define PHP_ZEPHIR_PARSER_VERSION "1.3.8" +#define PHP_ZEPHIR_PARSER_VERSION "1.4.0" #define PHP_ZEPHIR_PARSER_AUTHOR "Zephir Team and contributors" #define PHP_ZEPHIR_PARSER_DESCRIPTION "The Zephir Parser delivered as a C extension for the PHP language."