Skip to content

Commit

Permalink
feat: re-wrote the FunC definition to match the 0.4.4 (#9)
Browse files Browse the repository at this point in the history
* Prism.js definition itself
* Enhanced and expanded the test suite
* Added extra niceties here and there
  • Loading branch information
novusnota committed Sep 18, 2024
1 parent d2b803b commit 1d63481
Show file tree
Hide file tree
Showing 15 changed files with 2,094 additions and 327 deletions.
3 changes: 2 additions & 1 deletion .github/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@
"owner": "RunDevelopment"
},
"func": {
"alias": ["FunC", "Func"],
"title": "FunC",
"alias": "fc",
"owner": "sobolevn"
},
"gml": {
Expand Down
203 changes: 143 additions & 60 deletions langs/prism-func.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,143 @@
/**
* @file Prism.js definition for FunC
* @link https://docs.ton.org/develop/func/overview
* @version 0.2.0
* @author Nikita Sobolev (https://github.com/sobolevn)
* @license MIT
*/
(function (Prism) {
// 1. Does not start from "
// 2. Can start from ` and end with `, containing any character
// 3. Starts with underscore or { or } and have more than 1 character after it
// 4. Starts with letter, contains letters, numbers and underscores
var identifier = /(?!")(`([^`]+)`|((?=_)_|(?=\{)\{|(?=\})\}|(?![_`{}]))([^;,\[\]\(\)\s~.]+))/;
var string = /"[^\n"]+"[Hhcusa]?/;
var number = /\b([\d_]+|0x[\d_a-fA-F]+|0b[1_0]+)\b/;

Prism.languages.func = {
'include': {
pattern: /#include(.*);/,
inside: {
'keyword': /#include/,
'string': string,
'punctuation': /;/
},
},
'pragma': {
pattern: /#pragma(.*);/,
inside: {
'keyword': /#pragma|not-version|version/,
'number': /(\d+)(.\d+)?(.\d+)?/,
'operator': [/>=/, /<=/, /=/, />/, /</, /\^/],
'punctuation': /;/
}
},

'comment': [
{
pattern: /;;.*/,
lookbehind: true,
greedy: true
},
{
pattern: /\{-[\s\S]*?(?:-\}|$)/,
lookbehind: true,
greedy: true
},
],

'keyword': /\b(?:_(?=\s*:)|asm|const|do|else|elseif|elseifnot|forall|global|if|ifnot|impure|inline|inline_ref|method_id|repeat|return|until|while)\b/,
'boolean': /\b(?:false|true)\b/,
'builtin': /\b(?:_|builder|cell|cont|int|slice|tuple|var)\b/,

'string': string,
'number': number,
'variable': identifier,

'operator': /(<=>|>=|<=|!=|==|~>>=|~>>|\/%|\^%=|\^%|~%|\^\/=|\^\/|~\/=|~\/|\+=|-=|\*=|\/=|%=|<<=|>>=|\^>>=|\^>>|&=|>>|<<|\^=|\|=|\^|=|~|\/|%|-|\*|\+|>|<|&|\||:|\?)/,
'punctuation': /[\.;\(\),\[\]~\{\}]/,
};
}(Prism));
/**
* @file Prism.js definition for FunC
* @link https://docs.ton.org/develop/func/overview
* @version 0.4.4
* @author Novus Nota (https://github.com/novusnota)
* @author Nikita Sobolev (https://github.com/sobolevn)
* @license MIT
*/
(function(Prism) {
/** @type {Prism.GrammarValue} */
var number = /-?\b(?:\d+|0x[\da-fA-F]+)\b(?![^\.~,;\[\]\(\)\s])/;

/** @type {Prism.GrammarValue} */
var string = [
{ // multi-line
pattern: /"""[\s\S]*?"""[Hhcusa]?/,
greedy: true,
inside: {
// string type
'symbol': {
pattern: /("""[\s\S]*?""")[Hhcusa]/,
lookbehind: true,
greedy: true,
}
},
},
{ // single-line
pattern: /"[^\n"]*"[Hhcusa]?/,
greedy: true,
inside: {
// string type
'symbol': {
pattern: /("[^\n"]*")[Hhcusa]/,
lookbehind: true,
greedy: true,
}
},
},
];

/** @type {Prism.GrammarValue} */
var operator = /(?:!=|\?|:|%=|%|&=|&|\*=|\*|\+=|\+|->|-=|-|\/%|\/=|\/|<=>|<<=|<<|<=|<|==|=|>>=|>>|>=|>|\^>>=|\^>>|\^=|\^\/=|\^\/|\^%=|\^%|\^|\|=|\||~>>=|~>>|~\/=|~\/|~%|~)(?=\s)/;

/** @type {RegExp[]} */
var var_identifier = [
// quoted
/`[^`\n]+`/,
// plain
/[^\.~,;\[\]\(\)\s]+/
];

/** Prism.js definition for FunC */
Prism.languages.func = {
'comment': [
{ // single-line
pattern: /;;.*/,
lookbehind: true,
greedy: true,
},
{ // multi-line, not nested (TODO: nesting)
// . isn't used, because it only applies to the single line
pattern: /\{-[\s\S]*?(?:-\}|$)/,
lookbehind: true,
greedy: true,
},
{
// unused variable identifier
pattern: /\b_\b(?![^\.~,;\[\]\(\)\s])/
},
],

// Custom token for #pragma's
'pragma': {
pattern: /#pragma(.*);/,
inside: {
'keyword': /(?:#pragma|test-version-set|not-version|version|allow-post-modification|compute-asm-ltr)\b/,
'number': /(?:\d+)(?:.\d+)?(?:.\d+)?/,
'operator': /=|\^|<=|>=|<|>/,
'string': string,
'punctuation': /;/,
}
},

// Custom token for #include's
'include': {
pattern: /#include(.*);/,
inside: {
'keyword': /#include\b/,
'string': string,
'punctuation': /;/,
}
},

// builtin types
'builtin': /\b(?:int|cell|slice|builder|cont|tuple|type)\b/,

// builtin constants
'boolean': /\b(?:false|true|nil|Nil)\b/,

'keyword': /\b(?:forall|extern|global|asm|impure|inline_ref|inline|auto_apply|method_id|operator|infixl|infixr|infix|const|return|var|repeat|do|while|until|try|catch|ifnot|if|then|elseifnot|elseif|else)\b/,

'number': number,

'string': string,

'operator': operator,

'punctuation': [/[\.,;\(\)\[\]]/, /[\{\}](?![^\.~,;\[\]\(\)\s])/],

// Function and method names in declarations, definitions and calls
'function': [
{ // quoted
pattern: new RegExp(var_identifier[0].source + /(?=\s*\()/.source),
greedy: true,
},
{ // bitwise not operator
pattern: /~_/,
greedy: true,
},
{ // remaining operators
pattern: new RegExp(/\^?_/.source + operator.source + /_/.source),
greedy: true,
},
{ // plain function or method name
pattern: new RegExp(/[\.~]?/.source + var_identifier[1].source + /(?=\s*\()/.source),
greedy: true,
},
{ // builtin functions and methods
pattern: /\b(?:divmod|moddiv|muldiv|muldivr|muldivc|muldivmod|null\?|throw|throw_if|throw_unless|throw_arg|throw_arg_if|throw_arg_unless|load_int|load_uint|preload_int|preload_uint|store_int|store_uint|load_bits|preload_bits|int_at|cell_at|slice_at|tuple_at|at|touch|touch2|run_method0|run_method1|run_method2|run_method3|~divmod|~moddiv|~store_int|~store_uint|~touch|~touch2|~dump|~stdump)\b/,
greedy: true,
},
],

// Parametric polymorphism
'class-name': /[A-Z][^\.~,;\[\]\(\)\s]*/,

// All the rest of identifiers
'variable': var_identifier.map(x => { return { pattern: x, greedy: true } }),
};

// Adding a fc alias
Prism.languages.fc = Prism.languages.func;
}(Prism));
Loading

0 comments on commit 1d63481

Please sign in to comment.