all repos — NoPaste @ 29b774f090102303e43cf939b38ac2083e62d9f1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/CodeMirror/mode/apl/apl.js (view raw)

  1// CodeMirror, copyright (c) by Marijn Haverbeke and others
  2// Distributed under an MIT license: https://codemirror.net/LICENSE
  3
  4(function(mod) {
  5  if (typeof exports == "object" && typeof module == "object") // CommonJS
  6    mod(require("../../lib/codemirror"));
  7  else if (typeof define == "function" && define.amd) // AMD
  8    define(["../../lib/codemirror"], mod);
  9  else // Plain browser env
 10    mod(CodeMirror);
 11})(function(CodeMirror) {
 12"use strict";
 13
 14CodeMirror.defineMode("apl", function() {
 15  var builtInOps = {
 16    ".": "innerProduct",
 17    "\\": "scan",
 18    "/": "reduce",
 19    "⌿": "reduce1Axis",
 20    "⍀": "scan1Axis",
 21    "¨": "each",
 22    "⍣": "power"
 23  };
 24  var builtInFuncs = {
 25    "+": ["conjugate", "add"],
 26    "−": ["negate", "subtract"],
 27    "×": ["signOf", "multiply"],
 28    "÷": ["reciprocal", "divide"],
 29    "⌈": ["ceiling", "greaterOf"],
 30    "⌊": ["floor", "lesserOf"],
 31    "∣": ["absolute", "residue"],
 32    "⍳": ["indexGenerate", "indexOf"],
 33    "?": ["roll", "deal"],
 34    "⋆": ["exponentiate", "toThePowerOf"],
 35    "⍟": ["naturalLog", "logToTheBase"],
 36    "○": ["piTimes", "circularFuncs"],
 37    "!": ["factorial", "binomial"],
 38    "⌹": ["matrixInverse", "matrixDivide"],
 39    "<": [null, "lessThan"],
 40    "≤": [null, "lessThanOrEqual"],
 41    "=": [null, "equals"],
 42    ">": [null, "greaterThan"],
 43    "≥": [null, "greaterThanOrEqual"],
 44    "≠": [null, "notEqual"],
 45    "≡": ["depth", "match"],
 46    "≢": [null, "notMatch"],
 47    "∈": ["enlist", "membership"],
 48    "⍷": [null, "find"],
 49    "∪": ["unique", "union"],
 50    "∩": [null, "intersection"],
 51    "∼": ["not", "without"],
 52    "∨": [null, "or"],
 53    "∧": [null, "and"],
 54    "⍱": [null, "nor"],
 55    "⍲": [null, "nand"],
 56    "⍴": ["shapeOf", "reshape"],
 57    ",": ["ravel", "catenate"],
 58    "⍪": [null, "firstAxisCatenate"],
 59    "⌽": ["reverse", "rotate"],
 60    "⊖": ["axis1Reverse", "axis1Rotate"],
 61    "⍉": ["transpose", null],
 62    "↑": ["first", "take"],
 63    "↓": [null, "drop"],
 64    "⊂": ["enclose", "partitionWithAxis"],
 65    "⊃": ["diclose", "pick"],
 66    "⌷": [null, "index"],
 67    "⍋": ["gradeUp", null],
 68    "⍒": ["gradeDown", null],
 69    "⊤": ["encode", null],
 70    "⊥": ["decode", null],
 71    "⍕": ["format", "formatByExample"],
 72    "⍎": ["execute", null],
 73    "⊣": ["stop", "left"],
 74    "⊢": ["pass", "right"]
 75  };
 76
 77  var isOperator = /[\.\/⌿⍀¨⍣]/;
 78  var isNiladic = /⍬/;
 79  var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/;
 80  var isArrow = /←/;
 81  var isComment = /[⍝#].*$/;
 82
 83  var stringEater = function(type) {
 84    var prev;
 85    prev = false;
 86    return function(c) {
 87      prev = c;
 88      if (c === type) {
 89        return prev === "\\";
 90      }
 91      return true;
 92    };
 93  };
 94  return {
 95    startState: function() {
 96      return {
 97        prev: false,
 98        func: false,
 99        op: false,
100        string: false,
101        escape: false
102      };
103    },
104    token: function(stream, state) {
105      var ch, funcName;
106      if (stream.eatSpace()) {
107        return null;
108      }
109      ch = stream.next();
110      if (ch === '"' || ch === "'") {
111        stream.eatWhile(stringEater(ch));
112        stream.next();
113        state.prev = true;
114        return "string";
115      }
116      if (/[\[{\(]/.test(ch)) {
117        state.prev = false;
118        return null;
119      }
120      if (/[\]}\)]/.test(ch)) {
121        state.prev = true;
122        return null;
123      }
124      if (isNiladic.test(ch)) {
125        state.prev = false;
126        return "niladic";
127      }
128      if (/[¯\d]/.test(ch)) {
129        if (state.func) {
130          state.func = false;
131          state.prev = false;
132        } else {
133          state.prev = true;
134        }
135        stream.eatWhile(/[\w\.]/);
136        return "number";
137      }
138      if (isOperator.test(ch)) {
139        return "operator apl-" + builtInOps[ch];
140      }
141      if (isArrow.test(ch)) {
142        return "apl-arrow";
143      }
144      if (isFunction.test(ch)) {
145        funcName = "apl-";
146        if (builtInFuncs[ch] != null) {
147          if (state.prev) {
148            funcName += builtInFuncs[ch][1];
149          } else {
150            funcName += builtInFuncs[ch][0];
151          }
152        }
153        state.func = true;
154        state.prev = false;
155        return "function " + funcName;
156      }
157      if (isComment.test(ch)) {
158        stream.skipToEnd();
159        return "comment";
160      }
161      if (ch === "∘" && stream.peek() === ".") {
162        stream.next();
163        return "function jot-dot";
164      }
165      stream.eatWhile(/[\w\$_]/);
166      state.prev = true;
167      return "keyword";
168    }
169  };
170});
171
172CodeMirror.defineMIME("text/apl", "apl");
173
174});