gas.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. CodeMirror.defineMode("gas", function(_config, parserConfig) {
  2. 'use strict';
  3. // If an architecture is specified, its initialization function may
  4. // populate this array with custom parsing functions which will be
  5. // tried in the event that the standard functions do not find a match.
  6. var custom = [];
  7. // The symbol used to start a line comment changes based on the target
  8. // architecture.
  9. // If no architecture is pased in "parserConfig" then only multiline
  10. // comments will have syntax support.
  11. var lineCommentStartSymbol = "";
  12. // These directives are architecture independent.
  13. // Machine specific directives should go in their respective
  14. // architecture initialization function.
  15. // Reference:
  16. // http://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops
  17. var directives = {
  18. ".abort" : "builtin",
  19. ".align" : "builtin",
  20. ".altmacro" : "builtin",
  21. ".ascii" : "builtin",
  22. ".asciz" : "builtin",
  23. ".balign" : "builtin",
  24. ".balignw" : "builtin",
  25. ".balignl" : "builtin",
  26. ".bundle_align_mode" : "builtin",
  27. ".bundle_lock" : "builtin",
  28. ".bundle_unlock" : "builtin",
  29. ".byte" : "builtin",
  30. ".cfi_startproc" : "builtin",
  31. ".comm" : "builtin",
  32. ".data" : "builtin",
  33. ".def" : "builtin",
  34. ".desc" : "builtin",
  35. ".dim" : "builtin",
  36. ".double" : "builtin",
  37. ".eject" : "builtin",
  38. ".else" : "builtin",
  39. ".elseif" : "builtin",
  40. ".end" : "builtin",
  41. ".endef" : "builtin",
  42. ".endfunc" : "builtin",
  43. ".endif" : "builtin",
  44. ".equ" : "builtin",
  45. ".equiv" : "builtin",
  46. ".eqv" : "builtin",
  47. ".err" : "builtin",
  48. ".error" : "builtin",
  49. ".exitm" : "builtin",
  50. ".extern" : "builtin",
  51. ".fail" : "builtin",
  52. ".file" : "builtin",
  53. ".fill" : "builtin",
  54. ".float" : "builtin",
  55. ".func" : "builtin",
  56. ".global" : "builtin",
  57. ".gnu_attribute" : "builtin",
  58. ".hidden" : "builtin",
  59. ".hword" : "builtin",
  60. ".ident" : "builtin",
  61. ".if" : "builtin",
  62. ".incbin" : "builtin",
  63. ".include" : "builtin",
  64. ".int" : "builtin",
  65. ".internal" : "builtin",
  66. ".irp" : "builtin",
  67. ".irpc" : "builtin",
  68. ".lcomm" : "builtin",
  69. ".lflags" : "builtin",
  70. ".line" : "builtin",
  71. ".linkonce" : "builtin",
  72. ".list" : "builtin",
  73. ".ln" : "builtin",
  74. ".loc" : "builtin",
  75. ".loc_mark_labels" : "builtin",
  76. ".local" : "builtin",
  77. ".long" : "builtin",
  78. ".macro" : "builtin",
  79. ".mri" : "builtin",
  80. ".noaltmacro" : "builtin",
  81. ".nolist" : "builtin",
  82. ".octa" : "builtin",
  83. ".offset" : "builtin",
  84. ".org" : "builtin",
  85. ".p2align" : "builtin",
  86. ".popsection" : "builtin",
  87. ".previous" : "builtin",
  88. ".print" : "builtin",
  89. ".protected" : "builtin",
  90. ".psize" : "builtin",
  91. ".purgem" : "builtin",
  92. ".pushsection" : "builtin",
  93. ".quad" : "builtin",
  94. ".reloc" : "builtin",
  95. ".rept" : "builtin",
  96. ".sbttl" : "builtin",
  97. ".scl" : "builtin",
  98. ".section" : "builtin",
  99. ".set" : "builtin",
  100. ".short" : "builtin",
  101. ".single" : "builtin",
  102. ".size" : "builtin",
  103. ".skip" : "builtin",
  104. ".sleb128" : "builtin",
  105. ".space" : "builtin",
  106. ".stab" : "builtin",
  107. ".string" : "builtin",
  108. ".struct" : "builtin",
  109. ".subsection" : "builtin",
  110. ".symver" : "builtin",
  111. ".tag" : "builtin",
  112. ".text" : "builtin",
  113. ".title" : "builtin",
  114. ".type" : "builtin",
  115. ".uleb128" : "builtin",
  116. ".val" : "builtin",
  117. ".version" : "builtin",
  118. ".vtable_entry" : "builtin",
  119. ".vtable_inherit" : "builtin",
  120. ".warning" : "builtin",
  121. ".weak" : "builtin",
  122. ".weakref" : "builtin",
  123. ".word" : "builtin"
  124. };
  125. var registers = {};
  126. function x86(_parserConfig) {
  127. lineCommentStartSymbol = "#";
  128. registers.ax = "variable";
  129. registers.eax = "variable-2";
  130. registers.rax = "variable-3";
  131. registers.bx = "variable";
  132. registers.ebx = "variable-2";
  133. registers.rbx = "variable-3";
  134. registers.cx = "variable";
  135. registers.ecx = "variable-2";
  136. registers.rcx = "variable-3";
  137. registers.dx = "variable";
  138. registers.edx = "variable-2";
  139. registers.rdx = "variable-3";
  140. registers.si = "variable";
  141. registers.esi = "variable-2";
  142. registers.rsi = "variable-3";
  143. registers.di = "variable";
  144. registers.edi = "variable-2";
  145. registers.rdi = "variable-3";
  146. registers.sp = "variable";
  147. registers.esp = "variable-2";
  148. registers.rsp = "variable-3";
  149. registers.bp = "variable";
  150. registers.ebp = "variable-2";
  151. registers.rbp = "variable-3";
  152. registers.ip = "variable";
  153. registers.eip = "variable-2";
  154. registers.rip = "variable-3";
  155. registers.cs = "keyword";
  156. registers.ds = "keyword";
  157. registers.ss = "keyword";
  158. registers.es = "keyword";
  159. registers.fs = "keyword";
  160. registers.gs = "keyword";
  161. }
  162. function armv6(_parserConfig) {
  163. // Reference:
  164. // http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf
  165. // http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301h/DDI0301H_arm1176jzfs_r0p7_trm.pdf
  166. lineCommentStartSymbol = "@";
  167. directives.syntax = "builtin";
  168. registers.r0 = "variable";
  169. registers.r1 = "variable";
  170. registers.r2 = "variable";
  171. registers.r3 = "variable";
  172. registers.r4 = "variable";
  173. registers.r5 = "variable";
  174. registers.r6 = "variable";
  175. registers.r7 = "variable";
  176. registers.r8 = "variable";
  177. registers.r9 = "variable";
  178. registers.r10 = "variable";
  179. registers.r11 = "variable";
  180. registers.r12 = "variable";
  181. registers.sp = "variable-2";
  182. registers.lr = "variable-2";
  183. registers.pc = "variable-2";
  184. registers.r13 = registers.sp;
  185. registers.r14 = registers.lr;
  186. registers.r15 = registers.pc;
  187. custom.push(function(ch, stream) {
  188. if (ch === '#') {
  189. stream.eatWhile(/\w/);
  190. return "number";
  191. }
  192. });
  193. }
  194. var arch = parserConfig.architecture.toLowerCase();
  195. if (arch === "x86") {
  196. x86(parserConfig);
  197. } else if (arch === "arm" || arch === "armv6") {
  198. armv6(parserConfig);
  199. }
  200. function nextUntilUnescaped(stream, end) {
  201. var escaped = false, next;
  202. while ((next = stream.next()) != null) {
  203. if (next === end && !escaped) {
  204. return false;
  205. }
  206. escaped = !escaped && next === "\\";
  207. }
  208. return escaped;
  209. }
  210. function clikeComment(stream, state) {
  211. var maybeEnd = false, ch;
  212. while ((ch = stream.next()) != null) {
  213. if (ch === "/" && maybeEnd) {
  214. state.tokenize = null;
  215. break;
  216. }
  217. maybeEnd = (ch === "*");
  218. }
  219. return "comment";
  220. }
  221. return {
  222. startState: function() {
  223. return {
  224. tokenize: null
  225. };
  226. },
  227. token: function(stream, state) {
  228. if (state.tokenize) {
  229. return state.tokenize(stream, state);
  230. }
  231. if (stream.eatSpace()) {
  232. return null;
  233. }
  234. var style, cur, ch = stream.next();
  235. if (ch === "/") {
  236. if (stream.eat("*")) {
  237. state.tokenize = clikeComment;
  238. return clikeComment(stream, state);
  239. }
  240. }
  241. if (ch === lineCommentStartSymbol) {
  242. stream.skipToEnd();
  243. return "comment";
  244. }
  245. if (ch === '"') {
  246. nextUntilUnescaped(stream, '"');
  247. return "string";
  248. }
  249. if (ch === '.') {
  250. stream.eatWhile(/\w/);
  251. cur = stream.current().toLowerCase();
  252. style = directives[cur];
  253. return style || null;
  254. }
  255. if (ch === '=') {
  256. stream.eatWhile(/\w/);
  257. return "tag";
  258. }
  259. if (ch === '{') {
  260. return "braket";
  261. }
  262. if (ch === '}') {
  263. return "braket";
  264. }
  265. if (/\d/.test(ch)) {
  266. if (ch === "0" && stream.eat("x")) {
  267. stream.eatWhile(/[0-9a-fA-F]/);
  268. return "number";
  269. }
  270. stream.eatWhile(/\d/);
  271. return "number";
  272. }
  273. if (/\w/.test(ch)) {
  274. stream.eatWhile(/\w/);
  275. if (stream.eat(":")) {
  276. return 'tag';
  277. }
  278. cur = stream.current().toLowerCase();
  279. style = registers[cur];
  280. return style || null;
  281. }
  282. for (var i = 0; i < custom.length; i++) {
  283. style = custom[i](ch, stream, state);
  284. if (style) {
  285. return style;
  286. }
  287. }
  288. },
  289. lineComment: lineCommentStartSymbol,
  290. blockCommentStart: "/*",
  291. blockCommentEnd: "*/"
  292. };
  293. });