From d24f3cd3a6af283dbcd27f5ee66d6275f1dfba8f Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 6 May 2013 23:16:18 -0400 Subject: [PATCH] Add CodeMirror styles for basic --- README.md | 1 - cm2/mode/basic/basic.css | 46 ++++++++ cm2/mode/basic/basic.js | 222 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 cm2/mode/basic/basic.css create mode 100644 cm2/mode/basic/basic.js diff --git a/README.md b/README.md index fcb47d2..f2358b4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ You can run your basic programs from the command line (with only basic text inpu To Do ----- -* Upload the CodeMirror styles * Snapshot and/or link sensibly to the polyfills * Implement DOS functionality for consoles diff --git a/cm2/mode/basic/basic.css b/cm2/mode/basic/basic.css new file mode 100644 index 0000000..a8c786e --- /dev/null +++ b/cm2/mode/basic/basic.css @@ -0,0 +1,46 @@ +.cm-s-default span.cm-basic-statement { + color: #00007f; +} + +.cm-s-default span.cm-basic-unsupported { + color: #00007f; + background-color: #ff7f7f +} + +.cm-s-default span.cm-basic-function { + color: teal; +} + +.cm-s-default span.cm-basic-identifier { + color: #7f7f00; +} + +.cm-s-default span.cm-basic-string { + color: #007f00; +} + +.cm-s-default span.cm-basic-number { + color: #0000ff; +} + +.cm-s-default span.cm-basic-operator { + color: #7f007f; +} + +.cm-s-default span.cm-basic-separator { + color: #7f7f7f; +} + +.cm-s-default span.cm-basic-linenumber { + color: orange; +} + +.cm-s-default span.cm-basic-comment { + color: #cc00ff; + font-style: italic; +} + +.cm-s-default span.cm-basic-error { + color: black; + background-color: red; +} diff --git a/cm2/mode/basic/basic.js b/cm2/mode/basic/basic.js new file mode 100644 index 0000000..90479aa --- /dev/null +++ b/cm2/mode/basic/basic.js @@ -0,0 +1,222 @@ + +// Really just a lexer + +CodeMirror.defineMode('basic', function(config, parserConfig) { + + var STATEMENT = 'basic-statement', + OPERATOR = 'basic-operator', + FUNCTION = 'basic-function', + UNSUPPORTED = 'basic-unsupported'; + + var reserved = { + "ABS": FUNCTION, + "AND": OPERATOR, + "ASC": FUNCTION, + "ATN": FUNCTION, + "AT": STATEMENT, + "CALL": STATEMENT, + "CHR$": FUNCTION, + "CLEAR": STATEMENT, + "COLOR=": STATEMENT, + "CONT": UNSUPPORTED, + "COS": FUNCTION, + "DATA": STATEMENT, + "DEF": STATEMENT, + "DEL": UNSUPPORTED, + "DIM": STATEMENT, + "DRAW": UNSUPPORTED, + "END": STATEMENT, + "EXP": FUNCTION, + "FLASH": STATEMENT, + "FN": STATEMENT, + "FOR": STATEMENT, + "FRE": FUNCTION, + "GET": STATEMENT, + "GOSUB": STATEMENT, + "GOTO": STATEMENT, + "GR": STATEMENT, + "HCOLOR=": STATEMENT, + "HGR2": STATEMENT, + "HGR": STATEMENT, + "HIMEM:": UNSUPPORTED, + "HLIN": STATEMENT, + "HOME": STATEMENT, + "HPLOT": STATEMENT, + "HTAB": STATEMENT, + "IF": STATEMENT, + "IN#": UNSUPPORTED, + "INPUT": STATEMENT, + "INT": FUNCTION, + "INVERSE": STATEMENT, + "LEFT$": FUNCTION, + "LEN": FUNCTION, + "LET": STATEMENT, + "LIST": UNSUPPORTED, + "LOAD": UNSUPPORTED, + "LOG": FUNCTION, + "LOMEM:": UNSUPPORTED, + "MID$": FUNCTION, + "NEW": UNSUPPORTED, + "NEXT": STATEMENT, + "NORMAL": STATEMENT, + "NOTRACE": STATEMENT, + "NOT": OPERATOR, + "ONERR": STATEMENT, + "ON": STATEMENT, + "OR": OPERATOR, + "PDL": FUNCTION, + "PEEK": FUNCTION, + "PLOT": STATEMENT, + "POKE": STATEMENT, + "POP": STATEMENT, + "POS": FUNCTION, + "PRINT": STATEMENT, + "PR#": STATEMENT, + "READ": STATEMENT, + "RECALL": UNSUPPORTED, + "REM": STATEMENT, + "RESTORE": STATEMENT, + "RESUME": STATEMENT, + "RETURN": STATEMENT, + "RIGHT$": FUNCTION, + "RND": FUNCTION, + "ROT=": UNSUPPORTED, + "RUN": UNSUPPORTED, + "SAVE": UNSUPPORTED, + "SCALE=": UNSUPPORTED, + "SCRN": FUNCTION, + "SGN": FUNCTION, + "SHLOAD": UNSUPPORTED, + "SIN": FUNCTION, + "SPC": FUNCTION, + "SPEED=": STATEMENT, + "SQR": FUNCTION, + "STEP": STATEMENT, + "STOP": STATEMENT, + "STORE": UNSUPPORTED, + "STR$": FUNCTION, + "TAB": FUNCTION, + "TAN": FUNCTION, + "TEXT": STATEMENT, + "THEN": STATEMENT, + "TO": STATEMENT, + "TRACE": STATEMENT, + "USR": FUNCTION, + "VAL": FUNCTION, + "VLIN": STATEMENT, + "VTAB": STATEMENT, + "WAIT": UNSUPPORTED, + "XDRAW": UNSUPPORTED, + "&": UNSUPPORTED, + "?": STATEMENT + }; + var reservedKeys = (function() { + // Need longer stems first: ATN/AT, ONERR/ON, NOTRACE/NOT + var keys = [], name; + for (name in reserved) { + if (Object.prototype.hasOwnProperty.call(reserved, name)) { + keys.push(name); + } + } + keys.sort(); + keys.reverse(); + return keys; + } ()); + + // states are 'normal' and 'comment' + + return { + startState: function() { + return { + state: 'normal' + }; + }, + + token: function(stream, state) { + var name, i; + + if (state.state === 'normal') { + if (stream.eatSpace()) { + return null; + } + else if (/[0-9.]/.test(stream.peek())) { + stream.eatWhile(/[0-9]/); + if (stream.peek() === '.') { + stream.next(); + stream.eatWhile(/[0-9]/); + } + if (/[eE]/.test(stream.peek())) { + stream.next(); + stream.eatWhile(/[ \u00a0]/); + if (stream.peek() === '-' || stream.peek() === '+') { + stream.next(); + } + stream.eatWhile(/[ \u00a0]/); + stream.eatWhile(/[0-9]/); + } + return 'basic-number'; + } + else if (stream.peek() === '"') { + stream.next(); + while (!stream.eol()) { + if (stream.next() === '"') { + break; + } + } + return 'basic-string'; + } + else if (/[;=<>+\-*\/\^(),]/.test(stream.peek())) { + stream.next(); + return 'basic-operator'; + } + else if (stream.peek() === ':') { + stream.next(); + return 'basic-separator'; + } + else if (stream.match('REM', true, true)) { + stream.eatWhile(/[ \u00a0]/); + if (!stream.eol()) { + state.state = 'comment'; + } + return 'basic-statement'; + } + + // TODO: Applesoft-style space ignoring within reserved words + + for (i = 0; i < reservedKeys.length; i += 1) { + name = reservedKeys[i]; + if (stream.match(name, true, true)) { + return reserved[name]; + } + } + + if (/[A-Za-z]/.test(stream.peek())) { + stream.next(); + stream.eatWhile(/[A-Za-z0-9]/); + if (stream.peek() === '$' || stream.peek() === '%') { + stream.next(); + } + return 'basic-identifier'; + } + + stream.next(); + return 'basic-error'; + } + else if (state.state === 'comment') { + while (!stream.eol()) { + stream.next(); + } + state.state = 'normal'; + return 'basic-comment'; + } + else { + throw 'WTF!?'; + } + + + } + }; +}); + +CodeMirror.defineMIME("text/x-basic", "basic"); +CodeMirror.defineMIME("text/x-applesoft", "basic");