arduino.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. /**
  2. * @param {string} value
  3. * @returns {RegExp}
  4. * */
  5. /**
  6. * @param {RegExp | string } re
  7. * @returns {string}
  8. */
  9. function source(re) {
  10. if (!re) return null;
  11. if (typeof re === "string") return re;
  12. return re.source;
  13. }
  14. /**
  15. * @param {RegExp | string } re
  16. * @returns {string}
  17. */
  18. function lookahead(re) {
  19. return concat('(?=', re, ')');
  20. }
  21. /**
  22. * @param {RegExp | string } re
  23. * @returns {string}
  24. */
  25. function optional(re) {
  26. return concat('(', re, ')?');
  27. }
  28. /**
  29. * @param {...(RegExp | string) } args
  30. * @returns {string}
  31. */
  32. function concat(...args) {
  33. const joined = args.map((x) => source(x)).join("");
  34. return joined;
  35. }
  36. /*
  37. Language: C++
  38. Category: common, system
  39. Website: https://isocpp.org
  40. */
  41. /** @type LanguageFn */
  42. function cPlusPlus(hljs) {
  43. // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
  44. // not include such support nor can we be sure all the grammars depending
  45. // on it would desire this behavior
  46. const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', {
  47. contains: [
  48. {
  49. begin: /\\\n/
  50. }
  51. ]
  52. });
  53. const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
  54. const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
  55. const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
  56. const FUNCTION_TYPE_RE = '(' +
  57. DECLTYPE_AUTO_RE + '|' +
  58. optional(NAMESPACE_RE) +
  59. '[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) +
  60. ')';
  61. const CPP_PRIMITIVE_TYPES = {
  62. className: 'keyword',
  63. begin: '\\b[a-z\\d_]*_t\\b'
  64. };
  65. // https://en.cppreference.com/w/cpp/language/escape
  66. // \\ \x \xFF \u2837 \u00323747 \374
  67. const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
  68. const STRINGS = {
  69. className: 'string',
  70. variants: [
  71. {
  72. begin: '(u8?|U|L)?"',
  73. end: '"',
  74. illegal: '\\n',
  75. contains: [ hljs.BACKSLASH_ESCAPE ]
  76. },
  77. {
  78. begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
  79. end: '\'',
  80. illegal: '.'
  81. },
  82. hljs.END_SAME_AS_BEGIN({
  83. begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
  84. end: /\)([^()\\ ]{0,16})"/
  85. })
  86. ]
  87. };
  88. const NUMBERS = {
  89. className: 'number',
  90. variants: [
  91. {
  92. begin: '\\b(0b[01\']+)'
  93. },
  94. {
  95. begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)'
  96. },
  97. {
  98. begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)'
  99. }
  100. ],
  101. relevance: 0
  102. };
  103. const PREPROCESSOR = {
  104. className: 'meta',
  105. begin: /#\s*[a-z]+\b/,
  106. end: /$/,
  107. keywords: {
  108. 'meta-keyword':
  109. 'if else elif endif define undef warning error line ' +
  110. 'pragma _Pragma ifdef ifndef include'
  111. },
  112. contains: [
  113. {
  114. begin: /\\\n/,
  115. relevance: 0
  116. },
  117. hljs.inherit(STRINGS, {
  118. className: 'meta-string'
  119. }),
  120. {
  121. className: 'meta-string',
  122. begin: /<.*?>/
  123. },
  124. C_LINE_COMMENT_MODE,
  125. hljs.C_BLOCK_COMMENT_MODE
  126. ]
  127. };
  128. const TITLE_MODE = {
  129. className: 'title',
  130. begin: optional(NAMESPACE_RE) + hljs.IDENT_RE,
  131. relevance: 0
  132. };
  133. const FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
  134. const COMMON_CPP_HINTS = [
  135. 'asin',
  136. 'atan2',
  137. 'atan',
  138. 'calloc',
  139. 'ceil',
  140. 'cosh',
  141. 'cos',
  142. 'exit',
  143. 'exp',
  144. 'fabs',
  145. 'floor',
  146. 'fmod',
  147. 'fprintf',
  148. 'fputs',
  149. 'free',
  150. 'frexp',
  151. 'auto_ptr',
  152. 'deque',
  153. 'list',
  154. 'queue',
  155. 'stack',
  156. 'vector',
  157. 'map',
  158. 'set',
  159. 'pair',
  160. 'bitset',
  161. 'multiset',
  162. 'multimap',
  163. 'unordered_set',
  164. 'fscanf',
  165. 'future',
  166. 'isalnum',
  167. 'isalpha',
  168. 'iscntrl',
  169. 'isdigit',
  170. 'isgraph',
  171. 'islower',
  172. 'isprint',
  173. 'ispunct',
  174. 'isspace',
  175. 'isupper',
  176. 'isxdigit',
  177. 'tolower',
  178. 'toupper',
  179. 'labs',
  180. 'ldexp',
  181. 'log10',
  182. 'log',
  183. 'malloc',
  184. 'realloc',
  185. 'memchr',
  186. 'memcmp',
  187. 'memcpy',
  188. 'memset',
  189. 'modf',
  190. 'pow',
  191. 'printf',
  192. 'putchar',
  193. 'puts',
  194. 'scanf',
  195. 'sinh',
  196. 'sin',
  197. 'snprintf',
  198. 'sprintf',
  199. 'sqrt',
  200. 'sscanf',
  201. 'strcat',
  202. 'strchr',
  203. 'strcmp',
  204. 'strcpy',
  205. 'strcspn',
  206. 'strlen',
  207. 'strncat',
  208. 'strncmp',
  209. 'strncpy',
  210. 'strpbrk',
  211. 'strrchr',
  212. 'strspn',
  213. 'strstr',
  214. 'tanh',
  215. 'tan',
  216. 'unordered_map',
  217. 'unordered_multiset',
  218. 'unordered_multimap',
  219. 'priority_queue',
  220. 'make_pair',
  221. 'array',
  222. 'shared_ptr',
  223. 'abort',
  224. 'terminate',
  225. 'abs',
  226. 'acos',
  227. 'vfprintf',
  228. 'vprintf',
  229. 'vsprintf',
  230. 'endl',
  231. 'initializer_list',
  232. 'unique_ptr',
  233. 'complex',
  234. 'imaginary',
  235. 'std',
  236. 'string',
  237. 'wstring',
  238. 'cin',
  239. 'cout',
  240. 'cerr',
  241. 'clog',
  242. 'stdin',
  243. 'stdout',
  244. 'stderr',
  245. 'stringstream',
  246. 'istringstream',
  247. 'ostringstream'
  248. ];
  249. const CPP_KEYWORDS = {
  250. keyword: 'int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof ' +
  251. 'dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace ' +
  252. 'unsigned long volatile static protected bool template mutable if public friend ' +
  253. 'do goto auto void enum else break extern using asm case typeid wchar_t ' +
  254. 'short reinterpret_cast|10 default double register explicit signed typename try this ' +
  255. 'switch continue inline delete alignas alignof constexpr consteval constinit decltype ' +
  256. 'concept co_await co_return co_yield requires ' +
  257. 'noexcept static_assert thread_local restrict final override ' +
  258. 'atomic_bool atomic_char atomic_schar ' +
  259. 'atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong ' +
  260. 'atomic_ullong new throw return ' +
  261. 'and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq',
  262. built_in: '_Bool _Complex _Imaginary',
  263. _relevance_hints: COMMON_CPP_HINTS,
  264. literal: 'true false nullptr NULL'
  265. };
  266. const FUNCTION_DISPATCH = {
  267. className: "function.dispatch",
  268. relevance: 0,
  269. keywords: CPP_KEYWORDS,
  270. begin: concat(
  271. /\b/,
  272. /(?!decltype)/,
  273. /(?!if)/,
  274. /(?!for)/,
  275. /(?!while)/,
  276. hljs.IDENT_RE,
  277. lookahead(/\s*\(/))
  278. };
  279. const EXPRESSION_CONTAINS = [
  280. FUNCTION_DISPATCH,
  281. PREPROCESSOR,
  282. CPP_PRIMITIVE_TYPES,
  283. C_LINE_COMMENT_MODE,
  284. hljs.C_BLOCK_COMMENT_MODE,
  285. NUMBERS,
  286. STRINGS
  287. ];
  288. const EXPRESSION_CONTEXT = {
  289. // This mode covers expression context where we can't expect a function
  290. // definition and shouldn't highlight anything that looks like one:
  291. // `return some()`, `else if()`, `(x*sum(1, 2))`
  292. variants: [
  293. {
  294. begin: /=/,
  295. end: /;/
  296. },
  297. {
  298. begin: /\(/,
  299. end: /\)/
  300. },
  301. {
  302. beginKeywords: 'new throw return else',
  303. end: /;/
  304. }
  305. ],
  306. keywords: CPP_KEYWORDS,
  307. contains: EXPRESSION_CONTAINS.concat([
  308. {
  309. begin: /\(/,
  310. end: /\)/,
  311. keywords: CPP_KEYWORDS,
  312. contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
  313. relevance: 0
  314. }
  315. ]),
  316. relevance: 0
  317. };
  318. const FUNCTION_DECLARATION = {
  319. className: 'function',
  320. begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
  321. returnBegin: true,
  322. end: /[{;=]/,
  323. excludeEnd: true,
  324. keywords: CPP_KEYWORDS,
  325. illegal: /[^\w\s\*&:<>.]/,
  326. contains: [
  327. { // to prevent it from being confused as the function title
  328. begin: DECLTYPE_AUTO_RE,
  329. keywords: CPP_KEYWORDS,
  330. relevance: 0
  331. },
  332. {
  333. begin: FUNCTION_TITLE,
  334. returnBegin: true,
  335. contains: [ TITLE_MODE ],
  336. relevance: 0
  337. },
  338. // needed because we do not have look-behind on the below rule
  339. // to prevent it from grabbing the final : in a :: pair
  340. {
  341. begin: /::/,
  342. relevance: 0
  343. },
  344. // initializers
  345. {
  346. begin: /:/,
  347. endsWithParent: true,
  348. contains: [
  349. STRINGS,
  350. NUMBERS
  351. ]
  352. },
  353. {
  354. className: 'params',
  355. begin: /\(/,
  356. end: /\)/,
  357. keywords: CPP_KEYWORDS,
  358. relevance: 0,
  359. contains: [
  360. C_LINE_COMMENT_MODE,
  361. hljs.C_BLOCK_COMMENT_MODE,
  362. STRINGS,
  363. NUMBERS,
  364. CPP_PRIMITIVE_TYPES,
  365. // Count matching parentheses.
  366. {
  367. begin: /\(/,
  368. end: /\)/,
  369. keywords: CPP_KEYWORDS,
  370. relevance: 0,
  371. contains: [
  372. 'self',
  373. C_LINE_COMMENT_MODE,
  374. hljs.C_BLOCK_COMMENT_MODE,
  375. STRINGS,
  376. NUMBERS,
  377. CPP_PRIMITIVE_TYPES
  378. ]
  379. }
  380. ]
  381. },
  382. CPP_PRIMITIVE_TYPES,
  383. C_LINE_COMMENT_MODE,
  384. hljs.C_BLOCK_COMMENT_MODE,
  385. PREPROCESSOR
  386. ]
  387. };
  388. return {
  389. name: 'C++',
  390. aliases: [
  391. 'cc',
  392. 'c++',
  393. 'h++',
  394. 'hpp',
  395. 'hh',
  396. 'hxx',
  397. 'cxx'
  398. ],
  399. keywords: CPP_KEYWORDS,
  400. illegal: '</',
  401. classNameAliases: {
  402. "function.dispatch": "built_in"
  403. },
  404. contains: [].concat(
  405. EXPRESSION_CONTEXT,
  406. FUNCTION_DECLARATION,
  407. FUNCTION_DISPATCH,
  408. EXPRESSION_CONTAINS,
  409. [
  410. PREPROCESSOR,
  411. { // containers: ie, `vector <int> rooms (9);`
  412. begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<',
  413. end: '>',
  414. keywords: CPP_KEYWORDS,
  415. contains: [
  416. 'self',
  417. CPP_PRIMITIVE_TYPES
  418. ]
  419. },
  420. {
  421. begin: hljs.IDENT_RE + '::',
  422. keywords: CPP_KEYWORDS
  423. },
  424. {
  425. className: 'class',
  426. beginKeywords: 'enum class struct union',
  427. end: /[{;:<>=]/,
  428. contains: [
  429. {
  430. beginKeywords: "final class struct"
  431. },
  432. hljs.TITLE_MODE
  433. ]
  434. }
  435. ]),
  436. exports: {
  437. preprocessor: PREPROCESSOR,
  438. strings: STRINGS,
  439. keywords: CPP_KEYWORDS
  440. }
  441. };
  442. }
  443. /*
  444. Language: Arduino
  445. Author: Stefania Mellai <s.mellai@arduino.cc>
  446. Description: The Arduino® Language is a superset of C++. This rules are designed to highlight the Arduino® source code. For info about language see http://www.arduino.cc.
  447. Website: https://www.arduino.cc
  448. */
  449. /** @type LanguageFn */
  450. function arduino(hljs) {
  451. const ARDUINO_KW = {
  452. keyword:
  453. 'boolean byte word String',
  454. built_in:
  455. 'KeyboardController MouseController SoftwareSerial ' +
  456. 'EthernetServer EthernetClient LiquidCrystal ' +
  457. 'RobotControl GSMVoiceCall EthernetUDP EsploraTFT ' +
  458. 'HttpClient RobotMotor WiFiClient GSMScanner ' +
  459. 'FileSystem Scheduler GSMServer YunClient YunServer ' +
  460. 'IPAddress GSMClient GSMModem Keyboard Ethernet ' +
  461. 'Console GSMBand Esplora Stepper Process ' +
  462. 'WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage ' +
  463. 'Client Server GSMPIN FileIO Bridge Serial ' +
  464. 'EEPROM Stream Mouse Audio Servo File Task ' +
  465. 'GPRS WiFi Wire TFT GSM SPI SD ',
  466. _:
  467. 'setup loop ' +
  468. 'runShellCommandAsynchronously analogWriteResolution ' +
  469. 'retrieveCallingNumber printFirmwareVersion ' +
  470. 'analogReadResolution sendDigitalPortPair ' +
  471. 'noListenOnLocalhost readJoystickButton setFirmwareVersion ' +
  472. 'readJoystickSwitch scrollDisplayRight getVoiceCallStatus ' +
  473. 'scrollDisplayLeft writeMicroseconds delayMicroseconds ' +
  474. 'beginTransmission getSignalStrength runAsynchronously ' +
  475. 'getAsynchronously listenOnLocalhost getCurrentCarrier ' +
  476. 'readAccelerometer messageAvailable sendDigitalPorts ' +
  477. 'lineFollowConfig countryNameWrite runShellCommand ' +
  478. 'readStringUntil rewindDirectory readTemperature ' +
  479. 'setClockDivider readLightSensor endTransmission ' +
  480. 'analogReference detachInterrupt countryNameRead ' +
  481. 'attachInterrupt encryptionType readBytesUntil ' +
  482. 'robotNameWrite readMicrophone robotNameRead cityNameWrite ' +
  483. 'userNameWrite readJoystickY readJoystickX mouseReleased ' +
  484. 'openNextFile scanNetworks noInterrupts digitalWrite ' +
  485. 'beginSpeaker mousePressed isActionDone mouseDragged ' +
  486. 'displayLogos noAutoscroll addParameter remoteNumber ' +
  487. 'getModifiers keyboardRead userNameRead waitContinue ' +
  488. 'processInput parseCommand printVersion readNetworks ' +
  489. 'writeMessage blinkVersion cityNameRead readMessage ' +
  490. 'setDataMode parsePacket isListening setBitOrder ' +
  491. 'beginPacket isDirectory motorsWrite drawCompass ' +
  492. 'digitalRead clearScreen serialEvent rightToLeft ' +
  493. 'setTextSize leftToRight requestFrom keyReleased ' +
  494. 'compassRead analogWrite interrupts WiFiServer ' +
  495. 'disconnect playMelody parseFloat autoscroll ' +
  496. 'getPINUsed setPINUsed setTimeout sendAnalog ' +
  497. 'readSlider analogRead beginWrite createChar ' +
  498. 'motorsStop keyPressed tempoWrite readButton ' +
  499. 'subnetMask debugPrint macAddress writeGreen ' +
  500. 'randomSeed attachGPRS readString sendString ' +
  501. 'remotePort releaseAll mouseMoved background ' +
  502. 'getXChange getYChange answerCall getResult ' +
  503. 'voiceCall endPacket constrain getSocket writeJSON ' +
  504. 'getButton available connected findUntil readBytes ' +
  505. 'exitValue readGreen writeBlue startLoop IPAddress ' +
  506. 'isPressed sendSysex pauseMode gatewayIP setCursor ' +
  507. 'getOemKey tuneWrite noDisplay loadImage switchPIN ' +
  508. 'onRequest onReceive changePIN playFile noBuffer ' +
  509. 'parseInt overflow checkPIN knobRead beginTFT ' +
  510. 'bitClear updateIR bitWrite position writeRGB ' +
  511. 'highByte writeRed setSpeed readBlue noStroke ' +
  512. 'remoteIP transfer shutdown hangCall beginSMS ' +
  513. 'endWrite attached maintain noCursor checkReg ' +
  514. 'checkPUK shiftOut isValid shiftIn pulseIn ' +
  515. 'connect println localIP pinMode getIMEI ' +
  516. 'display noBlink process getBand running beginSD ' +
  517. 'drawBMP lowByte setBand release bitRead prepare ' +
  518. 'pointTo readRed setMode noFill remove listen ' +
  519. 'stroke detach attach noTone exists buffer ' +
  520. 'height bitSet circle config cursor random ' +
  521. 'IRread setDNS endSMS getKey micros ' +
  522. 'millis begin print write ready flush width ' +
  523. 'isPIN blink clear press mkdir rmdir close ' +
  524. 'point yield image BSSID click delay ' +
  525. 'read text move peek beep rect line open ' +
  526. 'seek fill size turn stop home find ' +
  527. 'step tone sqrt RSSI SSID ' +
  528. 'end bit tan cos sin pow map abs max ' +
  529. 'min get run put',
  530. literal:
  531. 'DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE ' +
  532. 'REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP ' +
  533. 'SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN ' +
  534. 'INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL ' +
  535. 'DEFAULT OUTPUT INPUT HIGH LOW'
  536. };
  537. const ARDUINO = cPlusPlus(hljs);
  538. const kws = /** @type {Record<string,any>} */ (ARDUINO.keywords);
  539. kws.keyword += ' ' + ARDUINO_KW.keyword;
  540. kws.literal += ' ' + ARDUINO_KW.literal;
  541. kws.built_in += ' ' + ARDUINO_KW.built_in;
  542. kws._ += ' ' + ARDUINO_KW._;
  543. ARDUINO.name = 'Arduino';
  544. ARDUINO.aliases = ['ino'];
  545. ARDUINO.supersetOf = "cpp";
  546. return ARDUINO;
  547. }
  548. module.exports = arduino;