diff --git a/docs.json b/docs.json index ea7350a15..2d132621c 100644 --- a/docs.json +++ b/docs.json @@ -24,7 +24,22 @@ "background": "/resources/logo/og-image-bg.svg" }, "styling": { - "eyebrows": "breadcrumbs" + "eyebrows": "breadcrumbs", + "codeblocks": { + "theme": { + "light": "github-light-default", + "dark": "dark-plus" + }, + "languages": { + "custom": [ + "/resources/grammars/tolk.tmLanguage.json", + "/resources/grammars/tlb.tmLanguage.json", + "/resources/grammars/fift.tmLanguage.json", + "/resources/grammars/tasm.tmLanguage.json", + "/resources/grammars/func.tmLanguage.json" + ] + } + } }, "contextual": { "options": [ diff --git a/extra.css b/extra.css index 9414b769c..a1c8fbe4c 100644 --- a/extra.css +++ b/extra.css @@ -75,57 +75,3 @@ table { div[data-component-part="callout-content"]>.code-block:last-child { margin-bottom: 0; } - -/* - A temporary solution syntax highlighting of Tolk snippets: invoke Prism.js on a client-side. - See `snippets/tolk-highlight.jsx`. - @link https://github.com/ton-org/docs/issues/1473 - */ - -:root { - --tolk-token-comment: #808080; - --tolk-token-type-hint: #D500EC; - --tolk-token-keyword: #0000FF; - --tolk-token-struct: #007EA2; - --tolk-token-variable: #444444; - --tolk-token-attr-name: #808000; - --tolk-token-function: #A82D2D; - --tolk-token-number: #0B9000; - --tolk-token-string: #008000; - --tolk-token-string-bg: #FAF9EF; - --tolk-token-operator: #A0A000; - --tolk-token-punctuation: #808000; - --tolk-token-three-dots: #999999; -} - -code.language-tolk { color: var(--tolk-token-variable); } -.token.comment { color: var(--tolk-token-comment); font-style: italic; } -.token.type-hint { color: var(--tolk-token-type-hint); } -.token.boolean { color: var(--tolk-token-keyword); } -.token.keyword { color: var(--tolk-token-keyword); } -.token.self { color: var(--tolk-token-variable); font-weight: bold; } -.token.attr-name { color: var(--tolk-token-attr-name); } -.token.function { color: var(--tolk-token-function); } -.token.number { color: var(--tolk-token-number); } -.token.string { color: var(--tolk-token-string); background-color: var(--tolk-token-string-bg); } -.token.operator { color: var(--tolk-token-operator); } -.token.punctuation { color: var(--tolk-token-punctuation); } -.token.three-dots { color: var(--tolk-token-three-dots); } -.token.struct { color: var(--tolk-token-struct); } -.token.variable { color: var(--tolk-token-variable); } - -html.dark { - --tolk-token-comment: #808080; - --tolk-token-type-hint: #DF90F8; - --tolk-token-keyword: #D75F02; - --tolk-token-struct: #56C1FF; - --tolk-token-variable: #C5D2E0; - --tolk-token-attr-name: #808000; - --tolk-token-function: #F9B900; - --tolk-token-number: #33A033; - --tolk-token-string: #33A033; - --tolk-token-string-bg: #1B1C1E; - --tolk-token-operator: #A0A000; - --tolk-token-punctuation: #85B2A0; - --tolk-token-three-dots: #777777; -} diff --git a/extra.js b/extra.js index 8c7a19e45..0d08e578a 100644 --- a/extra.js +++ b/extra.js @@ -1,118 +1 @@ /* See: https://mintlify.com/docs/settings/custom-scripts#custom-javascript */ -/* - A temporary solution syntax highlighting of Tolk snippets: invoke Prism.js on a client-side. - Sources of Prism.js are embedded right here, it's not downloaded separately. - @link https://github.com/ton-org/docs/issues/1473 - - All code blocks for the Tolk language are highlighted: - ```tolk - // automatically highlighted: see isTolkBlockCode() - ``` - - Visual appearance is defined in `extra.css`. - */ - -(function() { - const TOLK_GRAMMAR = { - 'comment': [ - { pattern: /\/\/.*/, greedy: true }, - // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890 - { pattern: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//, greedy: true }, - ], - 'attr-name': /@[a-zA-Z0-9_]+/, - 'keyword': /\b(do|if|as|is|try|else|while|break|throw|catch|return|assert|repeat|continue|asm|builtin|import|export|true|false|null|redef|mutate|tolk|global|const|var|val|fun|get\sfun|struct|match|type|lazy|enum|private|readonly)\b/, - 'function': /[a-zA-Z$_][a-zA-Z0-9$_]*(?=(<[^>]+>)*\()/, - 'type-hint': /\b(int|cell|void|never|bool|slice|tuple|builder|continuation|coins|int\d+|uint\d+|bytes\d+|bits\d+|address|any_address|map|dict)\b/, - 'boolean': /\b(false|true|null)\b/, - 'self': /\b(self)\b/, - 'number': /\b(-?\d+|0x[\da-fA-F]+|0b[01]+)\b/, - 'string': [ - { pattern: /"""[\s\S]*?"""/, greedy: true }, - { pattern: /"[^\n"]*"\w?/, greedy: true }, - ], - 'operator': new RegExp("\\+|-|\\*|/|%|\\?|:|=|<|>|!|&|\\||\\^|==|!=|<=|>=|<<|>>|&&|\\|\\||~/|\\^/|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\^=|->|<=>|~>>|\\^>>|<<=|>>=|=>"), - 'three-dots': /\.\.\./, - 'punctuation': /[.,;(){}\[\]]/, - 'struct': /\b[A-Z][a-z][a-zA-Z0-9$_]*\b/, - 'variable': [ - { pattern: /`[^`]+`/ }, - { pattern: /\b[a-zA-Z$_][a-zA-Z0-9$_]*\b/ }, - ], - }; - - // code blocks inserted with ```tolk are rendered as actually, - // because Mintlify knows nothing about custom languages; - // here we try to detect whether it's not func/fift/tlb - function isTolkBlockCode(/**HTMLElement*/ codeElement) { - if (codeElement.getAttribute('language') !== 'text') { - return false; - } - - // highlight all snippets inside the "Tolk" left menu sections - // (even small ones, like `var x = 123`; they cannot be distinguished from FunC, - // but on "Tolk" pages, no other languages are present) - const isTolkPage = window.location.href.includes('/languages/tolk'); - if (isTolkPage) { - return true; - } - - // highlight if markdown has a title: ```tolk title="filename.tolk" - const hasTitleFilenameTolk = codeElement - .closest('div.code-block') - ?.querySelector('div[data-component-part="code-block-header-filename"]') - ?.innerText - ?.toLowerCase() - ?.endsWith('tolk'); - if (hasTitleFilenameTolk) { - return true; - } - - // try to detect the language based on innerText; - // treat the occurrence of fun/struct/enum/etc. as Tolk; - // it works without false positives for quite big, "real-world", meaningful snippets; - // it does not work for small snippets like `var x = 123` or `if (x != 0) {}` - const innerText = codeElement.innerText; - return /\b(fun\s\w+|struct\s\w+|struct\s*\([0-9a-fx]{4,}|enum\s\w+|lazy\s\w+)\b/.test(innerText); - } - - // check if Prism was called for - function isCodeHighlighted(/**HTMLElement*/ codeElement) { - return codeElement.classList.contains('language-tolk'); - } - - // call Prism for - function highlightCode(/**HTMLElement*/ codeElement, Prism) { - codeElement.classList.add('language-tolk'); - codeElement.parentElement.style.backgroundColor = ''; // parent is
-    codeElement.parentElement.classList.remove('shiki'); // avoid css mixing
-    try {
-      Prism.highlightElement(codeElement);
-    } catch (ex) {
-      console.error('suppressed Prism error for code', codeElement, ex);
-    }
-  }
-
-  function highlightAllCodeElementsOnPage(Prism) {
-    let allCodes = document.querySelectorAll('code');
-    for (let i = 0; i < allCodes.length; ++i) {
-      if (isTolkBlockCode(allCodes[i]) && !isCodeHighlighted(allCodes[i])) {
-        highlightCode(allCodes[i], Prism)
-      }
-    }
-
-    // call it iteratively in case of dynamic content changes
-    setTimeout(function() {
-      highlightAllCodeElementsOnPage(Prism)
-    }, 500);
-  }
-
-  if (typeof window !== "undefined") {
-    /* PrismJS 1.30.0 */
-    var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var P=w.value;if(n.length>e.length)return;if(!(P instanceof i)){var E,S=1;if(y){if(!(E=l(b,A,e,m))||E.index>=e.length)break;var L=E.index,O=E.index+E[0].length,C=A;for(C+=w.value.length;L>=C;)C+=(w=w.next).value.length;if(A=C-=w.value.length,w.value instanceof i)continue;for(var j=w;j!==n.tail&&(Cg.reach&&(g.reach=W);var I=w.prev;if(_&&(I=u(n,I,_),A+=_.length),c(n,I,S),w=u(n,I,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),S>1){var T={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,T),g&&T.reach>g.reach&&(g.reach=T.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
-    Prism.languages.tolk = TOLK_GRAMMAR;
-
-    setTimeout(function() {
-      highlightAllCodeElementsOnPage(Prism);
-    }, 0);
-  }
-})();
diff --git a/languages/tl-b/syntax-and-semantics.mdx b/languages/tl-b/syntax-and-semantics.mdx
index ecb69fdb6..f42a6145e 100644
--- a/languages/tl-b/syntax-and-semantics.mdx
+++ b/languages/tl-b/syntax-and-semantics.mdx
@@ -61,17 +61,18 @@ _ {X:Type} my_val:(## 32) next_val:X = A X;
 - **Combinator name**: the right side of the TL-B scheme that represents the name of the defined combinator. Could be parameterized.
 
 ```tlb
-... = MsgAddrSmpl;
-// parameterized combinators
-... = Maybe X;
-... = Hashmap n X.
+_ = MsgAddrSmpl;
+
+// Parameterized combinators
+_ = Maybe X;
+_ = Hashmap n X.
 ```
 
 ### Comments
 
 The comments follow the same conventions as in C++.
 
-```
+```tlb
 /*
 This is
 a comment
diff --git a/resources/grammars/fift.tmLanguage.json b/resources/grammars/fift.tmLanguage.json
new file mode 100644
index 000000000..6cbe6ecbb
--- /dev/null
+++ b/resources/grammars/fift.tmLanguage.json
@@ -0,0 +1,145 @@
+{
+    "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+    "name": "fift",
+    "scopeName": "source.fift",
+    "fileTypes": ["fif"],
+    "patterns": [
+        {
+            "include": "#comments"
+        },
+        {
+            "include": "#strings"
+        },
+        {
+            "include": "#numbers"
+        },
+        {
+            "include": "#stack_words"
+        },
+        {
+            "include": "#program_words"
+        },
+        {
+            "include": "#control_words"
+        },
+        {
+            "include": "#literals"
+        },
+        {
+            "include": "#commands"
+        }
+    ],
+    "repository": {
+        "comments": {
+            "patterns": [
+                {
+                    "match": "//.*$",
+                    "name": "comment.line.double-slash.fift"
+                }
+            ]
+        },
+        "strings": {
+            "patterns": [
+                {
+                    "begin": "\"",
+                    "end": "\"",
+                    "name": "string.quoted.double.fift",
+                    "patterns": [
+                        {
+                            "match": "\\\\.",
+                            "name": "constant.character.escape.fift"
+                        }
+                    ]
+                },
+                {
+                    "match": "abort\"[^\"]*\"",
+                    "name": "string.quoted.double.abort.fift"
+                },
+                {
+                    "match": "\\.\"[^\"]*\"",
+                    "name": "string.quoted.double.print.fift"
+                }
+            ]
+        },
+        "numbers": {
+            "patterns": [
+                {
+                    "match": "\\b-?[0-9]+(/-?[0-9]+)?\\b",
+                    "name": "constant.numeric.decimal.fift"
+                },
+                {
+                    "match": "\\b0x[0-9a-fA-F]+\\b",
+                    "name": "constant.numeric.hex.fift"
+                },
+                {
+                    "match": "\\b0b[01]+\\b",
+                    "name": "constant.numeric.binary.fift"
+                }
+            ]
+        },
+        "stack_words": {
+            "patterns": [
+                {
+                    "match": "\\b(dup|drop|swap|rot|-rot|over|tuck|nip|2dup|2drop|2swap|pick|roll|-roll|exch|exch2|\\?dup)\\b",
+                    "name": "keyword.operator.stack.fift"
+                }
+            ]
+        },
+        "program_words": {
+            "patterns": [
+                {
+                    "match": "\\b(PROGRAM|END>c|PROC|PROCINLINE|DECLPROC|DECLMETHOD)\\b",
+                    "name": "keyword.control.program.fift"
+                },
+                {
+                    "match": "\\b(CALLDICT|INLINECALLDICT)\\b",
+                    "name": "keyword.control.call.fift"
+                }
+            ]
+        },
+        "control_words": {
+            "patterns": [
+                {
+                    "match": "\\b(if|ifnot|cond|until|while|times)\\b",
+                    "name": "keyword.control.flow.fift"
+                },
+                {
+                    "match": "\\b(include)\\b",
+                    "name": "keyword.control.import.fift"
+                }
+            ]
+        },
+        "literals": {
+            "patterns": [
+                {
+                    "match": "\\b(true|false)\\b",
+                    "name": "constant.language.boolean.fift"
+                },
+                {
+                    "match": "b\\{[01]+\\}",
+                    "name": "constant.other.binary-slice.fift"
+                },
+                {
+                    "match": "x\\{[0-9a-fA-F_]+\\}",
+                    "name": "constant.other.hex-slice.fift"
+                },
+                {
+                    "match": "B\\{[0-9a-fA-F_]+\\}",
+                    "name": "constant.other.hex-bytes.fift"
+                },
+                {
+                    "match": "char .",
+                    "name": "constant.character.fift"
+                }
+            ]
+        },
+        "commands": {
+            "patterns": [
+                {
+                    "match": "\\b[A-Z][A-Z0-9_]*\\b",
+                    "name": "keyword.other.command.fift"
+                }
+            ]
+        }
+    }
+}
diff --git a/resources/grammars/func.tmLanguage.json b/resources/grammars/func.tmLanguage.json
new file mode 100644
index 000000000..696513e23
--- /dev/null
+++ b/resources/grammars/func.tmLanguage.json
@@ -0,0 +1,117 @@
+{
+  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+  "name": "func",
+  "foldingStartMarker": "\\{\\s*$",
+  "foldingStopMarker": "^\\s*\\}",
+  "patterns": [
+    {
+      "include": "#keywords"
+    },
+    {
+      "include": "#strings"
+    },
+    {
+      "include": "#directives"
+    },
+    {
+      "include": "#numeric"
+    },
+    {
+      "include": "#comments"
+    },
+    {
+      "include": "#storage"
+    },
+    {
+      "include": "#functions"
+    },
+    {
+      "include": "#variables"
+    }
+  ],
+  "repository": {
+    "keywords": {
+      "patterns": [
+        {
+          "name": "keyword.control.",
+          "match": "\\b(if|ifnot|else|elseif|elseifnot|while|do|until|repeat|return|impure|method_id|forall|asm|inline|inline_ref)\\b"
+        },
+        {
+          "name": "keyword.operator",
+          "match": "(?<=\\s)(<=>|>=|<=|!=|==|\\^>>|\\~>>|>>|<<|\\/%|\\^%|\\~%|\\^\\/|\\~\\/|\\+=|-=|\\*=|\\/=|~\\/=|\\^\\/=|%=|\\^%=|<<=|>>=|~>>=|\\^>>=|&=|\\|=|\\^=|\\^|=|~|\\/|%|-|\\*|\\+|>|<|&|\\||:|\\?)(?=\\s)"
+        },
+        {
+          "name": "keyword.other",
+          "match": "\\b(false|true)\\b"
+        }
+      ]
+    },
+    "directives": {
+      "name": "storage.modifier.import",
+      "begin": "#include|#pragma",
+      "end": ";",
+      "patterns": [
+        {
+          "begin": "\"",
+          "end": "\"",
+          "name": "string.quoted.double"
+        },
+        {
+          "match": "(>=|<=|=|>|<|\\^)?([0-9]+)(.[0-9]+)?(.[0-9]+)?",
+          "name": "constant.numeric"
+        }
+      ]
+    },
+    "strings": {
+      "name": "string.quoted.double.",
+      "begin": "\"",
+      "end": "\"(H|h|c|u|s|a)?"
+    },
+    "numeric": {
+      "name": "constant.numeric",
+      "match": "(-?([\\d]+|0x[\\da-fA-F]+))\\b"
+    },
+    "comments": {
+      "patterns": [
+        {
+          "name": "comment.line",
+          "match": ";;(.*)"
+        },
+        {
+          "name": "comment.block",
+          "begin": "{-",
+          "end": "-}"
+        }
+      ]
+    },
+    "storage": {
+      "patterns": [
+        {
+          "name": "storage.type",
+          "match": "\\b(var|int|slice|tuple|cell|builder|cont|_)(?=[\\s\\),\\[\\]])"
+        },
+        {
+          "name": "storage.modifier",
+          "match": "\\b(global|const)\\s"
+        }
+      ]
+    },
+    "variables": {
+      "patterns": [
+        {
+          "match": "(?!\")(`([^`]+)`|((?=_)_|(?={){|(?=})}|(?![_`{}]))([^;,\\[\\]\\(\\)\\s~.]+))",
+          "name": "variable.name"
+        }
+      ]
+    },
+    "functions": {
+      "patterns": [
+        {
+          "match": "(?!\")(`([^`]+)`|(\\.|~)?((?=_)_|(?={){|(?=})}|(?![_`{}]))([^;,\\[\\]\\(\\)\\s~.]+))(?=[\\(])",
+          "name": "entity.name.function"
+        }
+      ]
+    }
+  },
+  "scopeName": "source.func"
+}
diff --git a/resources/grammars/tasm.tmLanguage.json b/resources/grammars/tasm.tmLanguage.json
new file mode 100644
index 000000000..ca9890276
--- /dev/null
+++ b/resources/grammars/tasm.tmLanguage.json
@@ -0,0 +1,200 @@
+{
+  "name": "tasm",
+  "displayName": "TASM",
+  "scopeName": "source.tasm",
+  "fileTypes": ["tasm"],
+  "foldingStartMarker": "\\{\\s*$",
+  "foldingStopMarker": "^\\s*\\}",
+  "patterns": [
+    {
+      "include": "#comment"
+    },
+    {
+      "include": "#keyword"
+    },
+    {
+      "include": "#instruction"
+    },
+    {
+      "include": "#literal"
+    },
+    {
+      "include": "#register"
+    },
+    {
+      "include": "#code_block"
+    },
+    {
+      "include": "#dictionary"
+    },
+    {
+      "include": "#punctuation"
+    }
+  ],
+  "repository": {
+    "comment": {
+      "patterns": [
+        {
+          "name": "comment.line.double-slash.tasm",
+          "begin": "//",
+          "beginCaptures": {
+            "0": {
+              "name": "punctuation.definition.comment.tasm"
+            }
+          },
+          "end": "$"
+        }
+      ]
+    },
+    "keyword": {
+      "patterns": [
+        {
+          "name": "keyword.other.ref.tasm",
+          "match": "\\b(ref)(?!\\w)"
+        },
+        {
+          "name": "keyword.other.embed.tasm",
+          "match": "\\b(embed)(?!\\w)"
+        },
+        {
+          "name": "keyword.other.exotic.tasm",
+          "match": "\\b(exotic)(?!\\w)"
+        },
+        {
+          "name": "keyword.other.library.tasm",
+          "match": "\\b(library)(?!\\w)"
+        }
+      ]
+    },
+    "instruction": {
+      "patterns": [
+        {
+          "match": "\\b([A-Z_][A-Z0-9_]*)\\b",
+          "name": "keyword.control.instruction.tasm"
+        }
+      ]
+    },
+    "literal": {
+      "patterns": [
+        {
+          "comment": "Hexadecimal integer literal (0x...)",
+          "match": "\\b(0[xX][a-fA-F0-9](?:_?[a-fA-F0-9])*)\\b",
+          "name": "constant.numeric.hex.tasm"
+        },
+        {
+          "comment": "Binary integer literal (0b...)",
+          "match": "\\b(0[bB][01](?:_?[01])*)\\b",
+          "name": "constant.numeric.binary.tasm"
+        },
+        {
+          "comment": "Octal integer literal (0o...)",
+          "match": "\\b(0[oO][0-7](?:_?[0-7])*)\\b",
+          "name": "constant.numeric.octal.tasm"
+        },
+        {
+          "comment": "Decimal integer literal",
+          "match": "\\b(-?(?:[0-9](?:_?[0-9])*))\\b",
+          "name": "constant.numeric.decimal.tasm"
+        },
+        {
+          "comment": "Hex data literal (x{...})",
+          "match": "x\\{[a-fA-F0-9_]*\\}",
+          "name": "constant.other.hex.tasm"
+        },
+        {
+          "comment": "Binary data literal (b{...})",
+          "match": "b\\{[01_]*\\}",
+          "name": "constant.other.binary.tasm"
+        },
+        {
+          "comment": "BOC data literal (boc{...})",
+          "match": "boc\\{[a-fA-F0-9_]*\\}",
+          "name": "constant.other.boc.tasm"
+        },
+        {
+          "comment": "String literal",
+          "begin": "\"",
+          "beginCaptures": {
+            "0": {"name": "punctuation.definition.string.begin.tasm"}
+          },
+          "end": "\"",
+          "endCaptures": {
+            "0": {"name": "punctuation.definition.string.end.tasm"}
+          },
+          "name": "string.quoted.double.tasm",
+          "patterns": [
+            {
+              "match": "\\\\.",
+              "name": "constant.character.escape.tasm"
+            }
+          ]
+        }
+      ]
+    },
+    "register": {
+      "patterns": [
+        {
+          "comment": "Stack registers (s0, s-1, etc.)",
+          "match": "\\b(s-?[0-9]+)\\b",
+          "name": "variable.parameter.register.stack.tasm"
+        },
+        {
+          "comment": "Control registers (c0, c4, etc.)",
+          "match": "\\b(c[0-9]+)\\b",
+          "name": "variable.parameter.register.control.tasm"
+        }
+      ]
+    },
+    "code_block": {
+      "comment": "Code blocks { ... }",
+      "begin": "\\{",
+      "beginCaptures": {
+        "0": {"name": "punctuation.section.code.begin.tasm"}
+      },
+      "end": "\\}",
+      "endCaptures": {
+        "0": {"name": "punctuation.section.code.end.tasm"}
+      },
+      "name": "meta.code-block.tasm",
+      "patterns": [{"include": "$self"}]
+    },
+    "dictionary": {
+      "comment": "Dictionaries [ ... ]",
+      "begin": "\\[",
+      "beginCaptures": {
+        "0": {"name": "punctuation.section.dictionary.begin.tasm"}
+      },
+      "end": "\\]",
+      "endCaptures": {
+        "0": {"name": "punctuation.section.dictionary.end.tasm"}
+      },
+      "name": "meta.dictionary.tasm",
+      "patterns": [
+        {
+          "comment": "Dictionary key-value separator =>",
+          "match": "=>",
+          "name": "keyword.operator.mapsto.tasm"
+        },
+        {"include": "#literal"},
+        {"include": "#code_block"},
+        {"include": "#punctuation"}
+      ]
+    },
+    "punctuation": {
+      "patterns": [
+        {
+          "match": ",",
+          "name": "punctuation.comma.tasm"
+        },
+        {
+          "match": ";",
+          "name": "punctuation.semi.tasm"
+        },
+        {
+          "match": ":",
+          "name": "punctuation.colon.tasm"
+        }
+      ]
+    }
+  }
+}
diff --git a/resources/grammars/tlb.tmLanguage.json b/resources/grammars/tlb.tmLanguage.json
new file mode 100644
index 000000000..9ba17e334
--- /dev/null
+++ b/resources/grammars/tlb.tmLanguage.json
@@ -0,0 +1,206 @@
+{
+  "name": "tl-b",
+  "displayName": "TL-B",
+  "scopeName": "source.tlb",
+  "fileTypes": ["tlb"],
+  "patterns": [
+    {
+      "include": "#comment"
+    },
+    {
+      "include": "#constructors"
+    },
+    {
+      "include": "#typeDefinitions"
+    },
+    {
+      "include": "#typeParameters"
+    },
+    {
+      "include": "#fields"
+    },
+    {
+      "include": "#hashExpressions"
+    },
+    {
+      "include": "#operators"
+    },
+    {
+      "include": "#primitiveTypes"
+    },
+    {
+      "include": "#arrays"
+    },
+    {
+      "include": "#numbers"
+    },
+    {
+      "include": "#declarations"
+    }
+  ],
+  "repository": {
+    "comment": {
+      "patterns": [
+        {
+          "name": "comment.line.double-slash.tlb",
+          "begin": "//",
+          "beginCaptures": {
+            "0": {
+              "name": "punctuation.definition.comment.line.double-slash.tlb"
+            }
+          },
+          "end": "$"
+        },
+        {
+          "name": "comment.block.tlb",
+          "begin": "\\s*/\\*",
+          "beginCaptures": {
+            "0": {
+              "name": "comment.block.begin.tlb punctuation.definition.comment.begin.tlb"
+            }
+          },
+          "end": "\\*/",
+          "endCaptures": {
+            "0": {
+              "name": "comment.block.end.tlb punctuation.definition.comment.end.tlb"
+            }
+          }
+        }
+      ]
+    },
+    "constructors": {
+      "patterns": [
+        {
+          "match": "([a-zA-Z_][a-zA-Z0-9_]*)\\s*(\\$[01_]+|#[0-9a-fA-F_]*)",
+          "captures": {
+            "1": {"name": "entity.name.type.constructor.tlb"},
+            "2": {"name": "constant.numeric.constructor-tag.tlb"}
+          }
+        }
+      ]
+    },
+    "typeParameters": {
+      "patterns": [
+        {
+          "match": "\\{([A-Z][a-zA-Z0-9]*):Type\\}",
+          "captures": {
+            "1": {"name": "support.type.parameter.tlb"}
+          }
+        },
+        {
+          "match": "\\{([a-z][a-zA-Z0-9]*):([^}]+)\\}",
+          "captures": {
+            "1": {"name": "variable.parameter.tlb"},
+            "2": {"name": "support.type.parameter.tlb"}
+          }
+        }
+      ]
+    },
+    "fields": {
+      "patterns": [
+        {
+          "match": "([a-zA-Z_][a-zA-Z0-9_]*)\\s*(:)",
+          "captures": {
+            "1": {"name": "variable.other.property.tlb"},
+            "2": {"name": "keyword.operator.colon.tlb"}
+          }
+        },
+        {
+          "match": "\\^\\s*\\(([^)]+)\\)",
+          "captures": {
+            "1": {"patterns": [{"include": "#expressions"}]},
+            "0": {"name": "keyword.operator.reference.tlb"}
+          }
+        }
+      ]
+    },
+    "hashExpressions": {
+      "patterns": [
+        {
+          "match": "(##)\\s*\\(([^)]+)\\)",
+          "captures": {
+            "1": {"name": "entity.name.function.macro.tlb"},
+            "2": {"patterns": [{"include": "#expressions"}]}
+          }
+        },
+        {
+          "match": "(##|~)",
+          "name": "entity.name.function.macro.tlb"
+        }
+      ]
+    },
+    "operators": {
+      "patterns": [
+        {
+          "match": "(\\+|\\-|\\*|\\|<=|>=|!=|=|<|>|\\^|~|\\?)",
+          "name": "keyword.operator.tlb"
+        }
+      ]
+    },
+    "primitiveTypes": {
+      "patterns": [
+        {
+          "match": "\\b((u)?int\\d+|Type|Bit|Maybe)\\b",
+          "name": "support.type.primitive.tlb"
+        }
+      ]
+    },
+    "arrays": {
+      "patterns": [
+        {
+          "begin": "\\[",
+          "end": "\\]",
+          "patterns": [{"include": "#expressions"}],
+          "name": "meta.array.tlb"
+        }
+      ]
+    },
+    "numbers": {
+      "patterns": [
+        {
+          "match": "\\b\\d+\\b",
+          "name": "constant.numeric.decimal.tlb"
+        },
+        {
+          "match": "\\b0x[0-9a-fA-F]+\\b",
+          "name": "constant.numeric.hex.tlb"
+        }
+      ]
+    },
+    "expressions": {
+      "patterns": [
+        {"include": "#hashExpressions"},
+        {"include": "#operators"},
+        {"include": "#primitiveTypes"},
+        {"include": "#arrays"},
+        {"include": "#numbers"},
+        {
+          "match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b",
+          "name": "variable.other.tlb"
+        }
+      ]
+    },
+    "typeDefinitions": {
+      "patterns": [
+        {
+          "match": "=\\s*([A-Z][a-zA-Z0-9]*)(?:\\s+([a-zA-Z0-9_\\s]+))?\\s*(?:X)?\\s*;",
+          "captures": {
+            "1": {"name": "entity.name.class.tlb"},
+            "2": {"patterns": [{"include": "#expressions"}]}
+          }
+        }
+      ]
+    },
+    "declarations": {
+      "patterns": [
+        {
+          "match": "([a-zA-Z_][a-zA-Z0-9_]*)#([0-9a-fA-F]+)",
+          "captures": {
+            "1": {"name": "entity.name.type.tlb"},
+            "2": {"name": "constant.numeric.hex.tlb"}
+          }
+        }
+      ]
+    }
+  }
+}
diff --git a/resources/grammars/tolk.tmLanguage.json b/resources/grammars/tolk.tmLanguage.json
new file mode 100644
index 000000000..37fb1feb5
--- /dev/null
+++ b/resources/grammars/tolk.tmLanguage.json
@@ -0,0 +1,100 @@
+{
+  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+  "name": "tolk",
+  "scopeName": "source.tolk",
+  "foldingStartMarker": "\\{\\s*$",
+  "foldingStopMarker": "^\\s*\\}",
+  "fileTypes": ["tolk"],
+  "patterns": [
+    {
+      "name": "comment.line.double-slash",
+      "match": "//(.*)"
+    },
+    {
+      "name": "comment.block",
+      "begin": "/\\*",
+      "end": "\\*/"
+    },
+    {
+      "name": "string.quoted.triple.tolk",
+      "begin": "\"\"\"",
+      "end": "\"\"\"",
+      "patterns": [
+        {
+          "name": "constant.character.escape.tolk",
+          "match": "\\\\."
+        }
+      ]
+    },
+    {
+      "name": "string.quoted.double.tolk",
+      "begin": "\"",
+      "end": "\"",
+      "patterns": [
+        {
+          "name": "constant.character.escape.tolk",
+          "match": "\\\\([nrt0\\\\'\"u]|u[0-9a-fA-F]{4})"
+        }
+      ]
+    },
+    {
+      "name": "constant.numeric",
+      "match": "\\b(-?([\\d]+|0x[\\da-fA-F]+|0b[01]+))\\b"
+    },
+    {
+      "name": "keyword.control",
+      "match": "\\b(do|if|try|else|while|break|throw|catch|return|assert|repeat|continue|asm|builtin|match|lazy)\\b"
+    },
+    {
+      "name": "keyword.operator",
+      "match": "\\+|-|\\*|/|%|\\?|:|,|;|\\(|\\)|\\[|\\]|{|}|=|<|>|!|&|\\||\\^|==|!=|<=|>=|<<|>>|&&|\\|\\||~/|\\^/|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\^=|->|<=>|~>>|\\^>>|<<=|>>=|=>|\\?\\?"
+    },
+    {
+      "name": "keyword.other",
+      "match": "\\b(import|export|true|false|null|redef|mutate|tolk|as|is|!is|private|readonly|string|contract)\\b"
+    },
+    {
+      "name": "keyword.other",
+      "match": "\\bself\\b"
+    },
+    {
+      "name": "entity.name.type.parameter",
+      "match": "\\b[TU]\\b"
+    },
+    {
+      "match": "\\b(val|var)\\s+(?:type|enum|int|map|array|cell|Cell|void|dict|bool|any_address|slice|string|tuple|builder|continuation|never|coins|address|int\\d+|uint\\d+|bits\\d+|bytes\\d+)\\b",
+      "captures": {
+        "1": {"name": "storage.modifier"}
+      }
+    },
+    {
+      "name": "constant.other",
+      "match": "\\b[A-Z][A-Z0-9_]{2,}\\b"
+    },
+    {
+      "name": "storage.type",
+      "match": "\\b(type|enum|int|map|array|cell|Cell|void|dict|bool|any_address|slice|string|tuple|builder|continuation|never|coins|int\\d+|uint\\d+|bits\\d+|bytes\\d+)\\b"
+    },
+    {
+      "name": "storage.type",
+      "match": "(?]+>)?\\s*\\()"
+    },
+    {
+      "name": "entity.name.type",
+      "match": "\\b[A-Z][a-zA-Z0-9]*\\b"
+    }
+  ],
+  "repository": {}
+}