# Helper to generate core library mappings for janet # Used to help build the tmLanguage grammar. Emits # the entire .tmLanguage file for janet. # Use dynamic binding and make this the first # expression in the file to not pollute (all-bindings) (setdyn :allsyms (array/concat @["break" "def" "do" "var" "set" "fn" "while" "if" "quote" "quasiquote" "unquote" "upscope" "splice"] (all-bindings))) (def allsyms (dyn :allsyms)) (def grammar-template ````` fileTypes janet foldingStartMarker \{ foldingStopMarker \} foldingStartMarker \[ foldingStopMarker \] foldingStartMarker \( foldingStopMarker \) keyEquivalent ^~L name Janet patterns include #all repository all patterns include #comment include #parens include #brackets include #braces include #readermac include #string include #longstring include #literal include #corelib include #r-number include #dec-number include #hex-number include #keysym include #symbol comment captures 1 name punctuation.definition.comment.janet match (#).*$ name comment.line.janet braces begin (@?{) captures 1 name punctuation.definition.braces.begin.janet end (}) captures 1 name punctuation.definition.braces.end.janet patterns include #all brackets begin (@?\[) captures 1 name punctuation.definition.brackets.begin.janet end (\]) captures 1 name punctuation.definition.brackets.end.janet patterns include #all parens begin (@?\() captures 1 name punctuation.definition.parens.begin.janet end (\)) captures 1 name punctuation.definition.parens.end.janet patterns include #all readermac match [\'\~\;\,] name punctuation.other.janet literal match (?<![\.:\w_\-=!@\$%^&?/<>*])(true|false|nil)(?![\.:\w_\-=!@\$%^&?/<>*]) name constant.language.janet corelib match (?<![\.:\w_\-=!@\$%^&?/<>*])(%ALLSYMBOLS%)(?![\.:\w_\-=!@\$%^&?/<>*]) name keyword.control.janet keysym match (?<![\.:\w_\-=!@\$%^&?/<>*]):[\.:\w_\-=!@\$%^&?/<>*]* name constant.keyword.janet symbol match (?<![\.:\w_\-=!@\$%^&?/<>*])[\.a-zA-Z_\-=!@\$%^&?/<>*][\.:\w_\-=!@\$%^&?/<>*]* name variable.other.janet hex-number match (?<![\.:\w_\-=!@\$%^&?/<>*])[-+]?0x([_\da-fA-F]+|[_\da-fA-F]+\.[_\da-fA-F]*|\.[_\da-fA-F]+)(&[+-]?[\da-fA-F]+)?(?![\.:\w_\-=!@\$%^&?/<>*]) name constant.numeric.hex.janet dec-number match (?<![\.:\w_\-=!@\$%^&?/<>*])[-+]?([_\d]+|[_\d]+\.[_\d]*|\.[_\d]+)([eE&][+-]?[\d]+)?(?![\.:\w_\-=!@\$%^&?/<>*]) name constant.numeric.decimal.janet r-number match (?<![\.:\w_\-=!@\$%^&?/<>*])[-+]?\d\d?r([_\w]+|[_\w]+\.[_\w]*|\.[_\w]+)(&[+-]?[\w]+)?(?![\.:\w_\-=!@\$%^&?/<>*]) name constant.numeric.decimal.janet string begin (@?") beginCaptures 1 name punctuation.definition.string.begin.janet end (") endCaptures 1 name punctuation.definition.string.end.janet name string.quoted.double.janet patterns match (\\[nevr0zft"\\']|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{6}) name constant.character.escape.janet longstring begin (@?)(`+) beginCaptures 1 name punctuation.definition.string.begin.janet 2 name punctuation.definition.string.begin.janet end \2 endCaptures 1 name punctuation.definition.string.end.janet name string.quoted.triple.janet nomatch match \S+ name invalid.illegal.janet scopeName source.janet uuid 3743190f-20c4-44d0-8640-6611a983296b `````) # Now we generate the bindings in the language. (def- escapes {(get "|" 0) `\|` (get "-" 0) `\-` (get "+" 0) `\+` (get "*" 0) `\*` (get "^" 0) `\^` (get "$" 0) `\$` (get "?" 0) `\?` 38 "&" 60 "<" 62 ">" 34 """ 39 "'" 47 "/"}) (defn- escape "Escape special characters for HTML and regex encoding." [str] (def buf @"") (loop [byte :in str] (if-let [rep (get escapes byte)] (buffer/push-string buf rep) (buffer/push-byte buf byte))) buf) (def pattern (string/join (map escape allsyms) "|")) (print (string/replace "%ALLSYMBOLS%" pattern grammar-template))