wasm.js (6705B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // WebAssembly experimental syntax highlight add-on for CodeMirror. 6 7 (function (root, factory) { 8 if (typeof define === 'function' && define.amd) { 9 define(["../../lib/codemirror"], factory); 10 } else if (typeof exports !== 'undefined') { 11 factory(require("resource://devtools/client/shared/sourceeditor/codemirror/lib/codemirror.js")); 12 } else { 13 factory(root.CodeMirror); 14 } 15 }(this, function (CodeMirror) { 16 "use strict"; 17 18 var isWordChar = /[\w\$_\.\\\/@]/; 19 20 function createLookupTable(list) { 21 var obj = Object.create(null); 22 list.forEach(function (key) { 23 obj[key] = true; 24 }); 25 return obj; 26 } 27 28 CodeMirror.defineMode("wasm", function() { 29 var keywords = createLookupTable([ 30 "function", "import", "export", "table", "memory", "segment", "as", "type", 31 "of", "from", "typeof", "br", "br_if", "loop", "br_table", "if", "else", 32 "call", "call_import", "call_indirect", "nop", "unreachable", "var", 33 "align", "select", "return"]); 34 var builtins = createLookupTable([ 35 "i32:8", "i32:8u", "i32:8s", "i32:16", "i32:16u", "i32:16s", 36 "i64:8", "i64:8u", "i64:8s", "i64:16", "i64:16u", "i64:16s", 37 "i64:32", "i64:32u", "i64:32s", 38 "i32.add", "i32.sub", "i32.mul", "i32.div_s", "i32.div_u", 39 "i32.rem_s", "i32.rem_u", "i32.and", "i32.or", "i32.xor", 40 "i32.shl", "i32.shr_u", "i32.shr_s", "i32.rotr", "i32.rotl", 41 "i32.eq", "i32.ne", "i32.lt_s", "i32.le_s", "i32.lt_u", 42 "i32.le_u", "i32.gt_s", "i32.ge_s", "i32.gt_u", "i32.ge_u", 43 "i32.clz", "i32.ctz", "i32.popcnt", "i32.eqz", "i64.add", 44 "i64.sub", "i64.mul", "i64.div_s", "i64.div_u", "i64.rem_s", 45 "i64.rem_u", "i64.and", "i64.or", "i64.xor", "i64.shl", 46 "i64.shr_u", "i64.shr_s", "i64.rotr", "i64.rotl", "i64.eq", 47 "i64.ne", "i64.lt_s", "i64.le_s", "i64.lt_u", "i64.le_u", 48 "i64.gt_s", "i64.ge_s", "i64.gt_u", "i64.ge_u", "i64.clz", 49 "i64.ctz", "i64.popcnt", "i64.eqz", "f32.add", "f32.sub", 50 "f32.mul", "f32.div", "f32.min", "f32.max", "f32.abs", 51 "f32.neg", "f32.copysign", "f32.ceil", "f32.floor", "f32.trunc", 52 "f32.nearest", "f32.sqrt", "f32.eq", "f32.ne", "f32.lt", 53 "f32.le", "f32.gt", "f32.ge", "f64.add", "f64.sub", "f64.mul", 54 "f64.div", "f64.min", "f64.max", "f64.abs", "f64.neg", 55 "f64.copysign", "f64.ceil", "f64.floor", "f64.trunc", "f64.nearest", 56 "f64.sqrt", "f64.eq", "f64.ne", "f64.lt", "f64.le", "f64.gt", 57 "f64.ge", "i32.trunc_s/f32", "i32.trunc_s/f64", "i32.trunc_u/f32", 58 "i32.trunc_u/f64", "i32.wrap/i64", "i64.trunc_s/f32", 59 "i64.trunc_s/f64", "i64.trunc_u/f32", "i64.trunc_u/f64", 60 "i64.extend_s/i32", "i64.extend_u/i32", "f32.convert_s/i32", 61 "f32.convert_u/i32", "f32.convert_s/i64", "f32.convert_u/i64", 62 "f32.demote/f64", "f32.reinterpret/i32", "f64.convert_s/i32", 63 "f64.convert_u/i32", "f64.convert_s/i64", "f64.convert_u/i64", 64 "f64.promote/f32", "f64.reinterpret/i64", "i32.reinterpret/f32", 65 "i64.reinterpret/f64"]); 66 var dataTypes = createLookupTable(["i32", "i64", "f32", "f64"]); 67 var isUnaryOperator = /[\-!]/; 68 var operators = createLookupTable([ 69 "+", "-", "*", "/", "/s", "/u", "%", "%s", "%u", 70 "<<", ">>u", ">>s", ">=", "<=", "==", "!=", 71 "<s", "<u", "<=s", "<=u", ">=s", ">=u", ">s", ">u", 72 "<", ">", "=", "&", "|", "^", "!"]); 73 74 function tokenBase(stream, state) { 75 var ch = stream.next(); 76 if (ch === "$") { 77 stream.eatWhile(isWordChar); 78 return "variable"; 79 } 80 if (ch === "@") { 81 stream.eatWhile(isWordChar); 82 return "meta"; 83 } 84 if (ch === '"') { 85 state.tokenize = tokenString(ch); 86 return state.tokenize(stream, state); 87 } 88 if (ch == "/") { 89 if (stream.eat("*")) { 90 state.tokenize = tokenComment; 91 return tokenComment(stream, state); 92 } else if (stream.eat("/")) { 93 stream.skipToEnd(); 94 return "comment"; 95 } 96 } 97 if (/\d/.test(ch) || 98 ((ch === "-" || ch === "+") && /\d/.test(stream.peek()))) { 99 stream.eatWhile(/[\w\._\-+]/); 100 return "number"; 101 } 102 if (/[\[\]\(\)\{\},:]/.test(ch)) { 103 return null; 104 } 105 if (isUnaryOperator.test(ch)) { 106 return "operator"; 107 } 108 stream.eatWhile(isWordChar); 109 var word = stream.current(); 110 111 if (word in operators) { 112 return "operator"; 113 } 114 if (word in keywords){ 115 return "keyword"; 116 } 117 if (word in dataTypes) { 118 if (!stream.eat(":")) { 119 return "builtin"; 120 } 121 stream.eatWhile(isWordChar); 122 word = stream.current(); 123 // fall thru for "builtin" check 124 } 125 if (word in builtins) { 126 return "builtin"; 127 } 128 129 if (word === "Temporary") { 130 // Nightly has header with some text graphics -- skipping it. 131 state.tokenize = tokenTemporary; 132 return state.tokenize(stream, state); 133 } 134 return null; 135 } 136 137 function tokenComment(stream, state) { 138 state.commentDepth = 1; 139 var next; 140 while ((next = stream.next()) != null) { 141 if (next === "*" && stream.eat("/")) { 142 if (--state.commentDepth === 0) { 143 state.tokenize = null; 144 return "comment"; 145 } 146 } 147 if (next === "/" && stream.eat("*")) { 148 // Nested comment 149 state.commentDepth++; 150 } 151 } 152 return "comment"; 153 } 154 155 function tokenTemporary(stream, state) { 156 var next, endState = state.commentState; 157 // Skipping until "text support (Work In Progress):" is found. 158 while ((next = stream.next()) != null) { 159 if (endState === 0 && next === "t") { 160 endState = 1; 161 } else if (endState === 1 && next === ":") { 162 state.tokenize = null; 163 state.commentState = 0; 164 endState = 2; 165 return "comment"; 166 } 167 } 168 state.commentState = endState; 169 return "comment"; 170 } 171 172 function tokenString(quote) { 173 return function(stream, state) { 174 var escaped = false, next, end = false; 175 while ((next = stream.next()) != null) { 176 if (next == quote && !escaped) { 177 state.tokenize = null; 178 return "string"; 179 } 180 escaped = !escaped && next === "\\"; 181 } 182 return "string"; 183 }; 184 } 185 186 return { 187 startState: function() { 188 return {tokenize: null, commentState: 0, commentDepth: 0}; 189 }, 190 191 token: function(stream, state) { 192 if (stream.eatSpace()) return null; 193 var style = (state.tokenize || tokenBase)(stream, state); 194 return style; 195 } 196 }; 197 }); 198 199 CodeMirror.registerHelper("wordChars", "wasm", isWordChar); 200 201 CodeMirror.defineMIME("text/wasm", "wasm"); 202 203 }));