gas.js 11 KB

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