From 4701e813005266456c6d2aa988583ccaa23cc5d2 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 13:25:45 -0500 Subject: [PATCH 01/14] (chore) zephir grammar cleanups The original grammar was lifted from PHP and is inaccurate. - does not support hash style comments - does not have `__halt_compiler` --- src/languages/zephir.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 45d74075ca..af423399cb 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -36,7 +36,6 @@ function(hljs) { 'likely unlikely', contains: [ hljs.C_LINE_COMMENT_MODE, - hljs.HASH_COMMENT_MODE, hljs.COMMENT( '/\\*', '\\*/', @@ -49,15 +48,6 @@ function(hljs) { ] } ), - hljs.COMMENT( - '__halt_compiler.+?;', - false, - { - endsWithParent: true, - keywords: '__halt_compiler', - lexemes: hljs.UNDERSCORE_IDENT_RE - } - ), { className: 'string', begin: '<<<[\'"]?\\w+[\'"]?$', end: '^\\w+;', From 3f94bf912bc1fcfe92bc514729250e61856ba4d0 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 13:33:07 -0500 Subject: [PATCH 02/14] set a constant for TITLE_MODE --- src/languages/zephir.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index af423399cb..079694189a 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -20,6 +20,7 @@ function(hljs) { hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}) ] }; + var TITLE_MODE = hljs.UNDERSCORE_TITLE_MODE; var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]}; return { aliases: ['zep'], @@ -62,7 +63,7 @@ function(hljs) { beginKeywords: 'function', end: /[;{]/, excludeEnd: true, illegal: '\\$|\\[|%', contains: [ - hljs.UNDERSCORE_TITLE_MODE, + TITLE_MODE, { className: 'params', begin: '\\(', end: '\\)', @@ -81,17 +82,17 @@ function(hljs) { illegal: /[:\(\$"]/, contains: [ {beginKeywords: 'extends implements'}, - hljs.UNDERSCORE_TITLE_MODE + TITLE_MODE ] }, { beginKeywords: 'namespace', end: ';', illegal: /[\.']/, - contains: [hljs.UNDERSCORE_TITLE_MODE] + contains: [TITLE_MODE] }, { beginKeywords: 'use', end: ';', - contains: [hljs.UNDERSCORE_TITLE_MODE] + contains: [TITLE_MODE] }, { begin: '=>' // No markup, just a relevance booster From 180d4696cc5279ede55cde90b457ea863645d528 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 13:48:57 -0500 Subject: [PATCH 03/14] organize common keywords --- src/languages/zephir.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 079694189a..6bbc30ad5a 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -27,14 +27,23 @@ function(hljs) { case_insensitive: true, keywords: 'and include_once list abstract global private echo interface as static endswitch ' + - 'array null if endwhile or const for endforeach self var let while isset public ' + - 'protected exit foreach throw elseif include __FILE__ empty require_once do xor ' + - 'return parent clone use __CLASS__ __LINE__ else break print eval new ' + - 'catch __METHOD__ case exception default die require __FUNCTION__ ' + - 'enddeclare final try switch continue endfor endif declare unset true false ' + - 'trait goto instanceof insteadof __DIR__ __NAMESPACE__ ' + - 'yield finally int uint long ulong char uchar double float bool boolean string' + - 'likely unlikely', + 'null if endwhile or const for endforeach self var let while isset public ' + + 'protected exit foreach throw elseif include empty require_once do xor ' + + 'return parent clone use else break print eval new ' + + 'catch case exception default die require ' + + 'enddeclare final try switch continue endfor endif declare unset ' + + 'trait goto instanceof insteadof ' + + 'yield finally int uint long ulong char uchar bool ' + + // magic constants + // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php + '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + + // types - https://docs.zephir-lang.com/0.12/en/types + 'array boolean float double integer object resource string ' + + 'char long unsigned ' + + // optimizations + 'likely unlikely ' + + // built-ins + 'true false null', contains: [ hljs.C_LINE_COMMENT_MODE, hljs.COMMENT( From 9b4cc1f3df3098fc9f151370b9d053376a43fbbe Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:08:21 -0500 Subject: [PATCH 04/14] more keyword cleanup --- src/languages/zephir.js | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 6bbc30ad5a..bad7bd9c29 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -26,24 +26,41 @@ function(hljs) { aliases: ['zep'], case_insensitive: true, keywords: - 'and include_once list abstract global private echo interface as static endswitch ' + - 'null if endwhile or const for endforeach self var let while isset public ' + - 'protected exit foreach throw elseif include empty require_once do xor ' + - 'return parent clone use else break print eval new ' + - 'catch case exception default die require ' + - 'enddeclare final try switch continue endfor endif declare unset ' + + 'and include_once list global interface as endswitch ' + + 'null endwhile or endforeach self ' + + 'exit foreach include require_once do xor ' + + 'parent clone print eval ' + + 'catch exception default die ' + + 'enddeclare try endfor endif declare unset ' + 'trait goto instanceof insteadof ' + - 'yield finally int uint long ulong char uchar bool ' + + 'yield finally int uchar bool ' + + + // classes and objects + 'namespace class use extends ' + + 'function return ' + + 'abstract final public protected private static deprecated ' + + // error handling + 'throw catch Exception ' + + // keyword-ish things their website does NOT seem to highlight (in their own snippets) + // 'typeof fetch ' + + // operators/helpers + 'echo empty isset ' + + // assignment/variables + 'let var new const ' + + // control + 'require ' + + 'if else elseif switch case ' + + 'while loop for continue break ' + // magic constants // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + // types - https://docs.zephir-lang.com/0.12/en/types 'array boolean float double integer object resource string ' + - 'char long unsigned ' + + 'char long unsigned uint ulong ' + // optimizations 'likely unlikely ' + // built-ins - 'true false null', + 'true false null undefined', contains: [ hljs.C_LINE_COMMENT_MODE, hljs.COMMENT( From d26e2310ba0036cfe07d82e5946d0933155a6ef8 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:08:53 -0500 Subject: [PATCH 05/14] remove end* keywords --- src/languages/zephir.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index bad7bd9c29..b1c512c2c5 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -26,12 +26,12 @@ function(hljs) { aliases: ['zep'], case_insensitive: true, keywords: - 'and include_once list global interface as endswitch ' + - 'null endwhile or endforeach self ' + + 'and include_once list global interface as ' + + 'null or self ' + 'exit foreach include require_once do xor ' + 'parent clone print eval ' + 'catch exception default die ' + - 'enddeclare try endfor endif declare unset ' + + 'try endif declare unset ' + 'trait goto instanceof insteadof ' + 'yield finally int uchar bool ' + From 9b968f737c07fc8135112b86e29b7b0184a93a75 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:22:01 -0500 Subject: [PATCH 06/14] continue keyword cleanupp --- src/languages/zephir.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index b1c512c2c5..c2b938aa7e 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -26,37 +26,37 @@ function(hljs) { aliases: ['zep'], case_insensitive: true, keywords: - 'and include_once list global interface as ' + - 'null or self ' + - 'exit foreach include require_once do xor ' + - 'parent clone print eval ' + - 'catch exception default die ' + - 'try endif declare unset ' + + ' list as ' + + 'self ' + + 'exit require_once do ' + + 'parent print eval ' + + 'die ' + + 'declare unset ' + 'trait goto instanceof insteadof ' + - 'yield finally int uchar bool ' + + 'finally ' + // classes and objects - 'namespace class use extends ' + + 'namespace class interface use extends ' + 'function return ' + 'abstract final public protected private static deprecated ' + // error handling - 'throw catch Exception ' + + 'throw try catch Exception ' + // keyword-ish things their website does NOT seem to highlight (in their own snippets) - // 'typeof fetch ' + + // 'typeof fetch in ' + // operators/helpers 'echo empty isset ' + // assignment/variables 'let var new const ' + // control 'require ' + - 'if else elseif switch case ' + + 'if else elseif switch case default ' + 'while loop for continue break ' + // magic constants // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + // types - https://docs.zephir-lang.com/0.12/en/types 'array boolean float double integer object resource string ' + - 'char long unsigned uint ulong ' + + 'char long unsigned bool int uint ulong uchar' + // optimizations 'likely unlikely ' + // built-ins From 61b8ee0e305118dd23b2eb909b6e366b3803fdc0 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:37:32 -0500 Subject: [PATCH 07/14] finished cleanup --- src/languages/zephir.js | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index c2b938aa7e..22e1f7d174 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -26,15 +26,6 @@ function(hljs) { aliases: ['zep'], case_insensitive: true, keywords: - ' list as ' + - 'self ' + - 'exit require_once do ' + - 'parent print eval ' + - 'die ' + - 'declare unset ' + - 'trait goto instanceof insteadof ' + - 'finally ' + - // classes and objects 'namespace class interface use extends ' + 'function return ' + @@ -44,21 +35,20 @@ function(hljs) { // keyword-ish things their website does NOT seem to highlight (in their own snippets) // 'typeof fetch in ' + // operators/helpers - 'echo empty isset ' + + 'echo empty isset instanceof unset' + // assignment/variables - 'let var new const ' + + 'let var new const self ' + // control 'require ' + 'if else elseif switch case default ' + - 'while loop for continue break ' + + 'do while loop for continue break ' + + 'likely unlikely ' + // magic constants // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + // types - https://docs.zephir-lang.com/0.12/en/types 'array boolean float double integer object resource string ' + - 'char long unsigned bool int uint ulong uchar' + - // optimizations - 'likely unlikely ' + + 'char long unsigned bool int uint ulong uchar ' + // built-ins 'true false null undefined', contains: [ From 2d598d81c743610f7477a09551e657085593185f Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:38:05 -0500 Subject: [PATCH 08/14] pretty sure Zephir is case sensative --- src/languages/zephir.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 22e1f7d174..570054493e 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -24,7 +24,6 @@ function(hljs) { var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]}; return { aliases: ['zep'], - case_insensitive: true, keywords: // classes and objects 'namespace class interface use extends ' + From f3461bdf1b554fceb7b59f39c028b6c0d80c870b Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:40:31 -0500 Subject: [PATCH 09/14] zephir does not support binary strings --- src/languages/zephir.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 570054493e..a24ee9d9b9 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -10,12 +10,6 @@ function(hljs) { className: 'string', contains: [hljs.BACKSLASH_ESCAPE], variants: [ - { - begin: 'b"', end: '"' - }, - { - begin: 'b\'', end: '\'' - }, hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}), hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null}) ] From d8a25c7e34995c14c246d5c3b08c8a4d02e8d7fc Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:41:37 -0500 Subject: [PATCH 10/14] fix spacing --- src/languages/zephir.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index a24ee9d9b9..259ed3342f 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -28,7 +28,7 @@ function(hljs) { // keyword-ish things their website does NOT seem to highlight (in their own snippets) // 'typeof fetch in ' + // operators/helpers - 'echo empty isset instanceof unset' + + 'echo empty isset instanceof unset ' + // assignment/variables 'let var new const self ' + // control From 7f98c239f32e0290ba4bc7ceba0939ed7a4a6597 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sat, 1 Feb 2020 14:44:33 -0500 Subject: [PATCH 11/14] support fn keyword --- src/languages/zephir.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 259ed3342f..1430321330 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -69,7 +69,7 @@ function(hljs) { }, { className: 'function', - beginKeywords: 'function', end: /[;{]/, excludeEnd: true, + beginKeywords: 'function fn', end: /[;{]/, excludeEnd: true, illegal: '\\$|\\[|%', contains: [ TITLE_MODE, From 6897df873368b78fb11b3704f79381b9cbea4bcb Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Sun, 2 Feb 2020 11:05:42 -0500 Subject: [PATCH 12/14] also highlight keywords inside params --- src/languages/zephir.js | 55 ++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/languages/zephir.js b/src/languages/zephir.js index 1430321330..96635280f3 100644 --- a/src/languages/zephir.js +++ b/src/languages/zephir.js @@ -16,34 +16,36 @@ function(hljs) { }; var TITLE_MODE = hljs.UNDERSCORE_TITLE_MODE; var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]}; + var KEYWORDS = + // classes and objects + 'namespace class interface use extends ' + + 'function return ' + + 'abstract final public protected private static deprecated ' + + // error handling + 'throw try catch Exception ' + + // keyword-ish things their website does NOT seem to highlight (in their own snippets) + // 'typeof fetch in ' + + // operators/helpers + 'echo empty isset instanceof unset ' + + // assignment/variables + 'let var new const self ' + + // control + 'require ' + + 'if else elseif switch case default ' + + 'do while loop for continue break ' + + 'likely unlikely ' + + // magic constants + // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php + '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + + // types - https://docs.zephir-lang.com/0.12/en/types + 'array boolean float double integer object resource string ' + + 'char long unsigned bool int uint ulong uchar ' + + // built-ins + 'true false null undefined'; + return { aliases: ['zep'], - keywords: - // classes and objects - 'namespace class interface use extends ' + - 'function return ' + - 'abstract final public protected private static deprecated ' + - // error handling - 'throw try catch Exception ' + - // keyword-ish things their website does NOT seem to highlight (in their own snippets) - // 'typeof fetch in ' + - // operators/helpers - 'echo empty isset instanceof unset ' + - // assignment/variables - 'let var new const self ' + - // control - 'require ' + - 'if else elseif switch case default ' + - 'do while loop for continue break ' + - 'likely unlikely ' + - // magic constants - // https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php - '__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' + - // types - https://docs.zephir-lang.com/0.12/en/types - 'array boolean float double integer object resource string ' + - 'char long unsigned bool int uint ulong uchar ' + - // built-ins - 'true false null undefined', + keywords: KEYWORDS, contains: [ hljs.C_LINE_COMMENT_MODE, hljs.COMMENT( @@ -76,6 +78,7 @@ function(hljs) { { className: 'params', begin: '\\(', end: '\\)', + keywords: KEYWORDS, contains: [ 'self', hljs.C_BLOCK_COMMENT_MODE, From 4b750e68a0189aac8fed5abe673fd8ced7caf28f Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 6 Feb 2020 18:16:48 -0500 Subject: [PATCH 13/14] add general markup tests for Zephir --- test/markup/zephir/default.expect.txt | 55 +++++++++++++++++++++++++++ test/markup/zephir/default.txt | 55 +++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 test/markup/zephir/default.expect.txt create mode 100644 test/markup/zephir/default.txt diff --git a/test/markup/zephir/default.expect.txt b/test/markup/zephir/default.expect.txt new file mode 100644 index 0000000000..099d29299a --- /dev/null +++ b/test/markup/zephir/default.expect.txt @@ -0,0 +1,55 @@ +function testBefore(<Test> a, var b = 5, int c = 10) +{ + a->method1(); + + return b + c; +} + +namespace Test; + +use RuntimeException as RE; + +/** + * Example comment + */ +class Test extends CustomClass implements TestInterface +{ + const C1 = null; + + // Magic constant: http://php.net/manual/ru/language.constants.predefined.php + const className = __CLASS__; + + public function method1() + { + int a = 1, b = 2; + return a + b; + } + + // See fn is allowed like shortcut + public fn method2() -> <Test> + { + call_user_func(function() { echo "hello"; }); + + + [1, 2, 3, 4, 5]->walk( + function(int! x) { + return x * x; + } + ); + + [1, 2, 3, 4, 5]->walk( + function(_, int key) { echo key; } + ); + + array input = [1, 2, 3, 4, 5]; + + input->walk( + function(_, int key) { echo key; } + ); + + + input->map(x => x * x); + + return this; + } +} diff --git a/test/markup/zephir/default.txt b/test/markup/zephir/default.txt new file mode 100644 index 0000000000..8142e7f10c --- /dev/null +++ b/test/markup/zephir/default.txt @@ -0,0 +1,55 @@ +function testBefore( a, var b = 5, int c = 10) +{ + a->method1(); + + return b + c; +} + +namespace Test; + +use RuntimeException as RE; + +/** + * Example comment + */ +class Test extends CustomClass implements TestInterface +{ + const C1 = null; + + // Magic constant: http://php.net/manual/ru/language.constants.predefined.php + const className = __CLASS__; + + public function method1() + { + int a = 1, b = 2; + return a + b; + } + + // See fn is allowed like shortcut + public fn method2() -> + { + call_user_func(function() { echo "hello"; }); + + + [1, 2, 3, 4, 5]->walk( + function(int! x) { + return x * x; + } + ); + + [1, 2, 3, 4, 5]->walk( + function(_, int key) { echo key; } + ); + + array input = [1, 2, 3, 4, 5]; + + input->walk( + function(_, int key) { echo key; } + ); + + + input->map(x => x * x); + + return this; + } +} From e7a2d89a2521ab99f854d11d105844c816004853 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Thu, 6 Feb 2020 18:26:39 -0500 Subject: [PATCH 14/14] add changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c0fadbf799..295c930a63 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ Core Changes: Language Improvements: +- enh(zephir) almost complete rework of the zephir grammar (#2387) [Josh Goebel][] - (markdown) much improved code block support (#2382) [Josh Goebel][] - (markdown) improve bold/italic nesting (#2382) [Josh Goebel][] - enh(csharp) Support `where` keyword as class constraint (#2378) [Josh Goebel][]