apl.js
174 lines
| 4.6 KiB
| application/javascript
|
JavascriptLexer
r1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others | |||
r4105 | // Distributed under an MIT license: https://codemirror.net/LICENSE | |||
r1 | ||||
(function(mod) { | ||||
if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
mod(require("../../lib/codemirror")); | ||||
else if (typeof define == "function" && define.amd) // AMD | ||||
define(["../../lib/codemirror"], mod); | ||||
else // Plain browser env | ||||
mod(CodeMirror); | ||||
})(function(CodeMirror) { | ||||
"use strict"; | ||||
CodeMirror.defineMode("apl", function() { | ||||
var builtInOps = { | ||||
".": "innerProduct", | ||||
"\\": "scan", | ||||
"/": "reduce", | ||||
"⌿": "reduce1Axis", | ||||
"⍀": "scan1Axis", | ||||
"¨": "each", | ||||
"⍣": "power" | ||||
}; | ||||
var builtInFuncs = { | ||||
"+": ["conjugate", "add"], | ||||
"−": ["negate", "subtract"], | ||||
"×": ["signOf", "multiply"], | ||||
"÷": ["reciprocal", "divide"], | ||||
"⌈": ["ceiling", "greaterOf"], | ||||
"⌊": ["floor", "lesserOf"], | ||||
"∣": ["absolute", "residue"], | ||||
"⍳": ["indexGenerate", "indexOf"], | ||||
"?": ["roll", "deal"], | ||||
"⋆": ["exponentiate", "toThePowerOf"], | ||||
"⍟": ["naturalLog", "logToTheBase"], | ||||
"○": ["piTimes", "circularFuncs"], | ||||
"!": ["factorial", "binomial"], | ||||
"⌹": ["matrixInverse", "matrixDivide"], | ||||
"<": [null, "lessThan"], | ||||
"≤": [null, "lessThanOrEqual"], | ||||
"=": [null, "equals"], | ||||
">": [null, "greaterThan"], | ||||
"≥": [null, "greaterThanOrEqual"], | ||||
"≠": [null, "notEqual"], | ||||
"≡": ["depth", "match"], | ||||
"≢": [null, "notMatch"], | ||||
"∈": ["enlist", "membership"], | ||||
"⍷": [null, "find"], | ||||
"∪": ["unique", "union"], | ||||
"∩": [null, "intersection"], | ||||
"∼": ["not", "without"], | ||||
"∨": [null, "or"], | ||||
"∧": [null, "and"], | ||||
"⍱": [null, "nor"], | ||||
"⍲": [null, "nand"], | ||||
"⍴": ["shapeOf", "reshape"], | ||||
",": ["ravel", "catenate"], | ||||
"⍪": [null, "firstAxisCatenate"], | ||||
"⌽": ["reverse", "rotate"], | ||||
"⊖": ["axis1Reverse", "axis1Rotate"], | ||||
"⍉": ["transpose", null], | ||||
"↑": ["first", "take"], | ||||
"↓": [null, "drop"], | ||||
"⊂": ["enclose", "partitionWithAxis"], | ||||
"⊃": ["diclose", "pick"], | ||||
"⌷": [null, "index"], | ||||
"⍋": ["gradeUp", null], | ||||
"⍒": ["gradeDown", null], | ||||
"⊤": ["encode", null], | ||||
"⊥": ["decode", null], | ||||
"⍕": ["format", "formatByExample"], | ||||
"⍎": ["execute", null], | ||||
"⊣": ["stop", "left"], | ||||
"⊢": ["pass", "right"] | ||||
}; | ||||
var isOperator = /[\.\/⌿⍀¨⍣]/; | ||||
var isNiladic = /⍬/; | ||||
var isFunction = /[\+−×÷⌈⌊∣⍳\?⋆⍟○!⌹<≤=>≥≠≡≢∈⍷∪∩∼∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢]/; | ||||
var isArrow = /←/; | ||||
var isComment = /[⍝#].*$/; | ||||
var stringEater = function(type) { | ||||
var prev; | ||||
prev = false; | ||||
return function(c) { | ||||
prev = c; | ||||
if (c === type) { | ||||
return prev === "\\"; | ||||
} | ||||
return true; | ||||
}; | ||||
}; | ||||
return { | ||||
startState: function() { | ||||
return { | ||||
prev: false, | ||||
func: false, | ||||
op: false, | ||||
string: false, | ||||
escape: false | ||||
}; | ||||
}, | ||||
token: function(stream, state) { | ||||
var ch, funcName; | ||||
if (stream.eatSpace()) { | ||||
return null; | ||||
} | ||||
ch = stream.next(); | ||||
if (ch === '"' || ch === "'") { | ||||
stream.eatWhile(stringEater(ch)); | ||||
stream.next(); | ||||
state.prev = true; | ||||
return "string"; | ||||
} | ||||
if (/[\[{\(]/.test(ch)) { | ||||
state.prev = false; | ||||
return null; | ||||
} | ||||
if (/[\]}\)]/.test(ch)) { | ||||
state.prev = true; | ||||
return null; | ||||
} | ||||
if (isNiladic.test(ch)) { | ||||
state.prev = false; | ||||
return "niladic"; | ||||
} | ||||
if (/[¯\d]/.test(ch)) { | ||||
if (state.func) { | ||||
state.func = false; | ||||
state.prev = false; | ||||
} else { | ||||
state.prev = true; | ||||
} | ||||
stream.eatWhile(/[\w\.]/); | ||||
return "number"; | ||||
} | ||||
if (isOperator.test(ch)) { | ||||
return "operator apl-" + builtInOps[ch]; | ||||
} | ||||
if (isArrow.test(ch)) { | ||||
return "apl-arrow"; | ||||
} | ||||
if (isFunction.test(ch)) { | ||||
funcName = "apl-"; | ||||
if (builtInFuncs[ch] != null) { | ||||
if (state.prev) { | ||||
funcName += builtInFuncs[ch][1]; | ||||
} else { | ||||
funcName += builtInFuncs[ch][0]; | ||||
} | ||||
} | ||||
state.func = true; | ||||
state.prev = false; | ||||
return "function " + funcName; | ||||
} | ||||
if (isComment.test(ch)) { | ||||
stream.skipToEnd(); | ||||
return "comment"; | ||||
} | ||||
if (ch === "∘" && stream.peek() === ".") { | ||||
stream.next(); | ||||
return "function jot-dot"; | ||||
} | ||||
stream.eatWhile(/[\w\$_]/); | ||||
state.prev = true; | ||||
return "keyword"; | ||||
} | ||||
}; | ||||
}); | ||||
CodeMirror.defineMIME("text/apl", "apl"); | ||||
}); | ||||