123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- const prefixRE = (words) => {
- return new RegExp("^(?:" + words.join("|") + ")", "i");
- }
- const wordRE = (words) => {
- return new RegExp("^(?:" + words.join("|") + ")$", "i");
- }
- const builtins = wordRE([
- // useful helpers
- "rep",
- // string manipulation
- "str/upper",
- "str/lower",
- "str/capitalize",
- "wd", "se",
- // arithmetic
- "add", "sub", "mul",
- // tuple stuff
- "tuple/len", "tuple/concat", "tuple/flatten", "tuple/join",
- "tuple/index", "tuple/rep", "tuple/replace", "tuple/fold",
- "tuple/map",
- ]);
- const keywords = wordRE([
- "puts",
- "case",
- "let",
- "in",
- "fix",
- "record",
- ]);
- const normal = (stream, state) => {
- let ch = stream.next();
- if (ch == "(") {
- if (stream.eat("*")) {
- comment(stream, state);
- return "comment";
- }
- }
- if (ch == "\"" || ch == "'")
- return (state.cur = string(ch))(stream, state);
- if (ch == "[" && /[\[=]/.test(stream.peek()))
- return (state.cur = bracketed(readBracket(stream), "string"))(stream, state);
- if (/\d/.test(ch)) {
- stream.eatWhile(/[\w.%]/);
- return "number";
- }
- if (/[\w_]/.test(ch)) {
- stream.eatWhile(/[\w\\\-_.]/);
- return "variable";
- }
- return null;
- }
- const comment = (stream, state) => {
- let ch;
- while (ch = stream.next()) {
- if (ch == "*" && stream.next() == ")") {
- state.cur = normal;
- return "comment";
- }
- }
- state.cur = comment;
- };
- const bracketed = (level, style) => {
- return (stream, state) => {
- let curlev = null, ch;
- while ((ch = stream.next()) != null) {
- if (curlev == null) {
- if (ch == "]") curlev = 0;
- } else if (ch == "=") {
- ++curlev;
- } else if (ch == "]" && curlev == level) {
- state.cur = normal;
- break;
- } else {
- curlev = null;
- }
- }
- return style;
- };
- }
- const string = (quote) => {
- return (stream, state) => {
- let escaped = false, ch;
- while ((ch = stream.next()) != null) {
- if (ch == quote && !escaped) break;
- escaped = !escaped && ch == "\\";
- }
- if (!escaped)
- state.cur = normal;
- return "string";
- };
- }
- export const matzoLang = {
- startState: (basecol) => {
- return {cur: normal};
- },
- token: (stream, state) => {
- if (stream.eatSpace())
- return null;
- let style = state.cur(stream, state);
- const word = stream.current();
- if (style == "variable") {
- if (keywords.test(word))
- style = "keyword";
- else if (builtins.test(word))
- style = "builtin";
- }
- return style;
- },
- languageData: {
- commentTokens: {block: {open: "(\*", close: "\*)"}}
- }
- };
|