perl.js 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. // CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
  2. // This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)
  3. CodeMirror.defineMode("perl",function(){
  4. // http://perldoc.perl.org
  5. var PERL={ // null - magic touch
  6. // 1 - keyword
  7. // 2 - def
  8. // 3 - atom
  9. // 4 - operator
  10. // 5 - variable-2 (predefined)
  11. // [x,y] - x=1,2,3; y=must be defined if x{...}
  12. // PERL operators
  13. '->' : 4,
  14. '++' : 4,
  15. '--' : 4,
  16. '**' : 4,
  17. // ! ~ \ and unary + and -
  18. '=~' : 4,
  19. '!~' : 4,
  20. '*' : 4,
  21. '/' : 4,
  22. '%' : 4,
  23. 'x' : 4,
  24. '+' : 4,
  25. '-' : 4,
  26. '.' : 4,
  27. '<<' : 4,
  28. '>>' : 4,
  29. // named unary operators
  30. '<' : 4,
  31. '>' : 4,
  32. '<=' : 4,
  33. '>=' : 4,
  34. 'lt' : 4,
  35. 'gt' : 4,
  36. 'le' : 4,
  37. 'ge' : 4,
  38. '==' : 4,
  39. '!=' : 4,
  40. '<=>' : 4,
  41. 'eq' : 4,
  42. 'ne' : 4,
  43. 'cmp' : 4,
  44. '~~' : 4,
  45. '&' : 4,
  46. '|' : 4,
  47. '^' : 4,
  48. '&&' : 4,
  49. '||' : 4,
  50. '//' : 4,
  51. '..' : 4,
  52. '...' : 4,
  53. '?' : 4,
  54. ':' : 4,
  55. '=' : 4,
  56. '+=' : 4,
  57. '-=' : 4,
  58. '*=' : 4, // etc. ???
  59. ',' : 4,
  60. '=>' : 4,
  61. '::' : 4,
  62. // list operators (rightward)
  63. 'not' : 4,
  64. 'and' : 4,
  65. 'or' : 4,
  66. 'xor' : 4,
  67. // PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;)
  68. 'BEGIN' : [5,1],
  69. 'END' : [5,1],
  70. 'PRINT' : [5,1],
  71. 'PRINTF' : [5,1],
  72. 'GETC' : [5,1],
  73. 'READ' : [5,1],
  74. 'READLINE' : [5,1],
  75. 'DESTROY' : [5,1],
  76. 'TIE' : [5,1],
  77. 'TIEHANDLE' : [5,1],
  78. 'UNTIE' : [5,1],
  79. 'STDIN' : 5,
  80. 'STDIN_TOP' : 5,
  81. 'STDOUT' : 5,
  82. 'STDOUT_TOP' : 5,
  83. 'STDERR' : 5,
  84. 'STDERR_TOP' : 5,
  85. '$ARG' : 5,
  86. '$_' : 5,
  87. '@ARG' : 5,
  88. '@_' : 5,
  89. '$LIST_SEPARATOR' : 5,
  90. '$"' : 5,
  91. '$PROCESS_ID' : 5,
  92. '$PID' : 5,
  93. '$$' : 5,
  94. '$REAL_GROUP_ID' : 5,
  95. '$GID' : 5,
  96. '$(' : 5,
  97. '$EFFECTIVE_GROUP_ID' : 5,
  98. '$EGID' : 5,
  99. '$)' : 5,
  100. '$PROGRAM_NAME' : 5,
  101. '$0' : 5,
  102. '$SUBSCRIPT_SEPARATOR' : 5,
  103. '$SUBSEP' : 5,
  104. '$;' : 5,
  105. '$REAL_USER_ID' : 5,
  106. '$UID' : 5,
  107. '$<' : 5,
  108. '$EFFECTIVE_USER_ID' : 5,
  109. '$EUID' : 5,
  110. '$>' : 5,
  111. '$a' : 5,
  112. '$b' : 5,
  113. '$COMPILING' : 5,
  114. '$^C' : 5,
  115. '$DEBUGGING' : 5,
  116. '$^D' : 5,
  117. '${^ENCODING}' : 5,
  118. '$ENV' : 5,
  119. '%ENV' : 5,
  120. '$SYSTEM_FD_MAX' : 5,
  121. '$^F' : 5,
  122. '@F' : 5,
  123. '${^GLOBAL_PHASE}' : 5,
  124. '$^H' : 5,
  125. '%^H' : 5,
  126. '@INC' : 5,
  127. '%INC' : 5,
  128. '$INPLACE_EDIT' : 5,
  129. '$^I' : 5,
  130. '$^M' : 5,
  131. '$OSNAME' : 5,
  132. '$^O' : 5,
  133. '${^OPEN}' : 5,
  134. '$PERLDB' : 5,
  135. '$^P' : 5,
  136. '$SIG' : 5,
  137. '%SIG' : 5,
  138. '$BASETIME' : 5,
  139. '$^T' : 5,
  140. '${^TAINT}' : 5,
  141. '${^UNICODE}' : 5,
  142. '${^UTF8CACHE}' : 5,
  143. '${^UTF8LOCALE}' : 5,
  144. '$PERL_VERSION' : 5,
  145. '$^V' : 5,
  146. '${^WIN32_SLOPPY_STAT}' : 5,
  147. '$EXECUTABLE_NAME' : 5,
  148. '$^X' : 5,
  149. '$1' : 5, // - regexp $1, $2...
  150. '$MATCH' : 5,
  151. '$&' : 5,
  152. '${^MATCH}' : 5,
  153. '$PREMATCH' : 5,
  154. '$`' : 5,
  155. '${^PREMATCH}' : 5,
  156. '$POSTMATCH' : 5,
  157. "$'" : 5,
  158. '${^POSTMATCH}' : 5,
  159. '$LAST_PAREN_MATCH' : 5,
  160. '$+' : 5,
  161. '$LAST_SUBMATCH_RESULT' : 5,
  162. '$^N' : 5,
  163. '@LAST_MATCH_END' : 5,
  164. '@+' : 5,
  165. '%LAST_PAREN_MATCH' : 5,
  166. '%+' : 5,
  167. '@LAST_MATCH_START' : 5,
  168. '@-' : 5,
  169. '%LAST_MATCH_START' : 5,
  170. '%-' : 5,
  171. '$LAST_REGEXP_CODE_RESULT' : 5,
  172. '$^R' : 5,
  173. '${^RE_DEBUG_FLAGS}' : 5,
  174. '${^RE_TRIE_MAXBUF}' : 5,
  175. '$ARGV' : 5,
  176. '@ARGV' : 5,
  177. 'ARGV' : 5,
  178. 'ARGVOUT' : 5,
  179. '$OUTPUT_FIELD_SEPARATOR' : 5,
  180. '$OFS' : 5,
  181. '$,' : 5,
  182. '$INPUT_LINE_NUMBER' : 5,
  183. '$NR' : 5,
  184. '$.' : 5,
  185. '$INPUT_RECORD_SEPARATOR' : 5,
  186. '$RS' : 5,
  187. '$/' : 5,
  188. '$OUTPUT_RECORD_SEPARATOR' : 5,
  189. '$ORS' : 5,
  190. '$\\' : 5,
  191. '$OUTPUT_AUTOFLUSH' : 5,
  192. '$|' : 5,
  193. '$ACCUMULATOR' : 5,
  194. '$^A' : 5,
  195. '$FORMAT_FORMFEED' : 5,
  196. '$^L' : 5,
  197. '$FORMAT_PAGE_NUMBER' : 5,
  198. '$%' : 5,
  199. '$FORMAT_LINES_LEFT' : 5,
  200. '$-' : 5,
  201. '$FORMAT_LINE_BREAK_CHARACTERS' : 5,
  202. '$:' : 5,
  203. '$FORMAT_LINES_PER_PAGE' : 5,
  204. '$=' : 5,
  205. '$FORMAT_TOP_NAME' : 5,
  206. '$^' : 5,
  207. '$FORMAT_NAME' : 5,
  208. '$~' : 5,
  209. '${^CHILD_ERROR_NATIVE}' : 5,
  210. '$EXTENDED_OS_ERROR' : 5,
  211. '$^E' : 5,
  212. '$EXCEPTIONS_BEING_CAUGHT' : 5,
  213. '$^S' : 5,
  214. '$WARNING' : 5,
  215. '$^W' : 5,
  216. '${^WARNING_BITS}' : 5,
  217. '$OS_ERROR' : 5,
  218. '$ERRNO' : 5,
  219. '$!' : 5,
  220. '%OS_ERROR' : 5,
  221. '%ERRNO' : 5,
  222. '%!' : 5,
  223. '$CHILD_ERROR' : 5,
  224. '$?' : 5,
  225. '$EVAL_ERROR' : 5,
  226. '$@' : 5,
  227. '$OFMT' : 5,
  228. '$#' : 5,
  229. '$*' : 5,
  230. '$ARRAY_BASE' : 5,
  231. '$[' : 5,
  232. '$OLD_PERL_VERSION' : 5,
  233. '$]' : 5,
  234. // PERL blocks
  235. 'if' :[1,1],
  236. elsif :[1,1],
  237. 'else' :[1,1],
  238. 'while' :[1,1],
  239. unless :[1,1],
  240. 'for' :[1,1],
  241. foreach :[1,1],
  242. // PERL functions
  243. 'abs' :1, // - absolute value function
  244. accept :1, // - accept an incoming socket connect
  245. alarm :1, // - schedule a SIGALRM
  246. 'atan2' :1, // - arctangent of Y/X in the range -PI to PI
  247. bind :1, // - binds an address to a socket
  248. binmode :1, // - prepare binary files for I/O
  249. bless :1, // - create an object
  250. bootstrap :1, //
  251. 'break' :1, // - break out of a "given" block
  252. caller :1, // - get context of the current subroutine call
  253. chdir :1, // - change your current working directory
  254. chmod :1, // - changes the permissions on a list of files
  255. chomp :1, // - remove a trailing record separator from a string
  256. chop :1, // - remove the last character from a string
  257. chown :1, // - change the owership on a list of files
  258. chr :1, // - get character this number represents
  259. chroot :1, // - make directory new root for path lookups
  260. close :1, // - close file (or pipe or socket) handle
  261. closedir :1, // - close directory handle
  262. connect :1, // - connect to a remote socket
  263. 'continue' :[1,1], // - optional trailing block in a while or foreach
  264. 'cos' :1, // - cosine function
  265. crypt :1, // - one-way passwd-style encryption
  266. dbmclose :1, // - breaks binding on a tied dbm file
  267. dbmopen :1, // - create binding on a tied dbm file
  268. 'default' :1, //
  269. defined :1, // - test whether a value, variable, or function is defined
  270. 'delete' :1, // - deletes a value from a hash
  271. die :1, // - raise an exception or bail out
  272. 'do' :1, // - turn a BLOCK into a TERM
  273. dump :1, // - create an immediate core dump
  274. each :1, // - retrieve the next key/value pair from a hash
  275. endgrent :1, // - be done using group file
  276. endhostent :1, // - be done using hosts file
  277. endnetent :1, // - be done using networks file
  278. endprotoent :1, // - be done using protocols file
  279. endpwent :1, // - be done using passwd file
  280. endservent :1, // - be done using services file
  281. eof :1, // - test a filehandle for its end
  282. 'eval' :1, // - catch exceptions or compile and run code
  283. 'exec' :1, // - abandon this program to run another
  284. exists :1, // - test whether a hash key is present
  285. exit :1, // - terminate this program
  286. 'exp' :1, // - raise I to a power
  287. fcntl :1, // - file control system call
  288. fileno :1, // - return file descriptor from filehandle
  289. flock :1, // - lock an entire file with an advisory lock
  290. fork :1, // - create a new process just like this one
  291. format :1, // - declare a picture format with use by the write() function
  292. formline :1, // - internal function used for formats
  293. getc :1, // - get the next character from the filehandle
  294. getgrent :1, // - get next group record
  295. getgrgid :1, // - get group record given group user ID
  296. getgrnam :1, // - get group record given group name
  297. gethostbyaddr :1, // - get host record given its address
  298. gethostbyname :1, // - get host record given name
  299. gethostent :1, // - get next hosts record
  300. getlogin :1, // - return who logged in at this tty
  301. getnetbyaddr :1, // - get network record given its address
  302. getnetbyname :1, // - get networks record given name
  303. getnetent :1, // - get next networks record
  304. getpeername :1, // - find the other end of a socket connection
  305. getpgrp :1, // - get process group
  306. getppid :1, // - get parent process ID
  307. getpriority :1, // - get current nice value
  308. getprotobyname :1, // - get protocol record given name
  309. getprotobynumber :1, // - get protocol record numeric protocol
  310. getprotoent :1, // - get next protocols record
  311. getpwent :1, // - get next passwd record
  312. getpwnam :1, // - get passwd record given user login name
  313. getpwuid :1, // - get passwd record given user ID
  314. getservbyname :1, // - get services record given its name
  315. getservbyport :1, // - get services record given numeric port
  316. getservent :1, // - get next services record
  317. getsockname :1, // - retrieve the sockaddr for a given socket
  318. getsockopt :1, // - get socket options on a given socket
  319. given :1, //
  320. glob :1, // - expand filenames using wildcards
  321. gmtime :1, // - convert UNIX time into record or string using Greenwich time
  322. 'goto' :1, // - create spaghetti code
  323. grep :1, // - locate elements in a list test true against a given criterion
  324. hex :1, // - convert a string to a hexadecimal number
  325. 'import' :1, // - patch a module's namespace into your own
  326. index :1, // - find a substring within a string
  327. 'int' :1, // - get the integer portion of a number
  328. ioctl :1, // - system-dependent device control system call
  329. 'join' :1, // - join a list into a string using a separator
  330. keys :1, // - retrieve list of indices from a hash
  331. kill :1, // - send a signal to a process or process group
  332. last :1, // - exit a block prematurely
  333. lc :1, // - return lower-case version of a string
  334. lcfirst :1, // - return a string with just the next letter in lower case
  335. length :1, // - return the number of bytes in a string
  336. 'link' :1, // - create a hard link in the filesytem
  337. listen :1, // - register your socket as a server
  338. local : 2, // - create a temporary value for a global variable (dynamic scoping)
  339. localtime :1, // - convert UNIX time into record or string using local time
  340. lock :1, // - get a thread lock on a variable, subroutine, or method
  341. 'log' :1, // - retrieve the natural logarithm for a number
  342. lstat :1, // - stat a symbolic link
  343. m :null, // - match a string with a regular expression pattern
  344. map :1, // - apply a change to a list to get back a new list with the changes
  345. mkdir :1, // - create a directory
  346. msgctl :1, // - SysV IPC message control operations
  347. msgget :1, // - get SysV IPC message queue
  348. msgrcv :1, // - receive a SysV IPC message from a message queue
  349. msgsnd :1, // - send a SysV IPC message to a message queue
  350. my : 2, // - declare and assign a local variable (lexical scoping)
  351. 'new' :1, //
  352. next :1, // - iterate a block prematurely
  353. no :1, // - unimport some module symbols or semantics at compile time
  354. oct :1, // - convert a string to an octal number
  355. open :1, // - open a file, pipe, or descriptor
  356. opendir :1, // - open a directory
  357. ord :1, // - find a character's numeric representation
  358. our : 2, // - declare and assign a package variable (lexical scoping)
  359. pack :1, // - convert a list into a binary representation
  360. 'package' :1, // - declare a separate global namespace
  361. pipe :1, // - open a pair of connected filehandles
  362. pop :1, // - remove the last element from an array and return it
  363. pos :1, // - find or set the offset for the last/next m//g search
  364. print :1, // - output a list to a filehandle
  365. printf :1, // - output a formatted list to a filehandle
  366. prototype :1, // - get the prototype (if any) of a subroutine
  367. push :1, // - append one or more elements to an array
  368. q :null, // - singly quote a string
  369. qq :null, // - doubly quote a string
  370. qr :null, // - Compile pattern
  371. quotemeta :null, // - quote regular expression magic characters
  372. qw :null, // - quote a list of words
  373. qx :null, // - backquote quote a string
  374. rand :1, // - retrieve the next pseudorandom number
  375. read :1, // - fixed-length buffered input from a filehandle
  376. readdir :1, // - get a directory from a directory handle
  377. readline :1, // - fetch a record from a file
  378. readlink :1, // - determine where a symbolic link is pointing
  379. readpipe :1, // - execute a system command and collect standard output
  380. recv :1, // - receive a message over a Socket
  381. redo :1, // - start this loop iteration over again
  382. ref :1, // - find out the type of thing being referenced
  383. rename :1, // - change a filename
  384. require :1, // - load in external functions from a library at runtime
  385. reset :1, // - clear all variables of a given name
  386. 'return' :1, // - get out of a function early
  387. reverse :1, // - flip a string or a list
  388. rewinddir :1, // - reset directory handle
  389. rindex :1, // - right-to-left substring search
  390. rmdir :1, // - remove a directory
  391. s :null, // - replace a pattern with a string
  392. say :1, // - print with newline
  393. scalar :1, // - force a scalar context
  394. seek :1, // - reposition file pointer for random-access I/O
  395. seekdir :1, // - reposition directory pointer
  396. select :1, // - reset default output or do I/O multiplexing
  397. semctl :1, // - SysV semaphore control operations
  398. semget :1, // - get set of SysV semaphores
  399. semop :1, // - SysV semaphore operations
  400. send :1, // - send a message over a socket
  401. setgrent :1, // - prepare group file for use
  402. sethostent :1, // - prepare hosts file for use
  403. setnetent :1, // - prepare networks file for use
  404. setpgrp :1, // - set the process group of a process
  405. setpriority :1, // - set a process's nice value
  406. setprotoent :1, // - prepare protocols file for use
  407. setpwent :1, // - prepare passwd file for use
  408. setservent :1, // - prepare services file for use
  409. setsockopt :1, // - set some socket options
  410. shift :1, // - remove the first element of an array, and return it
  411. shmctl :1, // - SysV shared memory operations
  412. shmget :1, // - get SysV shared memory segment identifier
  413. shmread :1, // - read SysV shared memory
  414. shmwrite :1, // - write SysV shared memory
  415. shutdown :1, // - close down just half of a socket connection
  416. 'sin' :1, // - return the sine of a number
  417. sleep :1, // - block for some number of seconds
  418. socket :1, // - create a socket
  419. socketpair :1, // - create a pair of sockets
  420. 'sort' :1, // - sort a list of values
  421. splice :1, // - add or remove elements anywhere in an array
  422. 'split' :1, // - split up a string using a regexp delimiter
  423. sprintf :1, // - formatted print into a string
  424. 'sqrt' :1, // - square root function
  425. srand :1, // - seed the random number generator
  426. stat :1, // - get a file's status information
  427. state :1, // - declare and assign a state variable (persistent lexical scoping)
  428. study :1, // - optimize input data for repeated searches
  429. 'sub' :1, // - declare a subroutine, possibly anonymously
  430. 'substr' :1, // - get or alter a portion of a stirng
  431. symlink :1, // - create a symbolic link to a file
  432. syscall :1, // - execute an arbitrary system call
  433. sysopen :1, // - open a file, pipe, or descriptor
  434. sysread :1, // - fixed-length unbuffered input from a filehandle
  435. sysseek :1, // - position I/O pointer on handle used with sysread and syswrite
  436. system :1, // - run a separate program
  437. syswrite :1, // - fixed-length unbuffered output to a filehandle
  438. tell :1, // - get current seekpointer on a filehandle
  439. telldir :1, // - get current seekpointer on a directory handle
  440. tie :1, // - bind a variable to an object class
  441. tied :1, // - get a reference to the object underlying a tied variable
  442. time :1, // - return number of seconds since 1970
  443. times :1, // - return elapsed time for self and child processes
  444. tr :null, // - transliterate a string
  445. truncate :1, // - shorten a file
  446. uc :1, // - return upper-case version of a string
  447. ucfirst :1, // - return a string with just the next letter in upper case
  448. umask :1, // - set file creation mode mask
  449. undef :1, // - remove a variable or function definition
  450. unlink :1, // - remove one link to a file
  451. unpack :1, // - convert binary structure into normal perl variables
  452. unshift :1, // - prepend more elements to the beginning of a list
  453. untie :1, // - break a tie binding to a variable
  454. use :1, // - load in a module at compile time
  455. utime :1, // - set a file's last access and modify times
  456. values :1, // - return a list of the values in a hash
  457. vec :1, // - test or set particular bits in a string
  458. wait :1, // - wait for any child process to die
  459. waitpid :1, // - wait for a particular child process to die
  460. wantarray :1, // - get void vs scalar vs list context of current subroutine call
  461. warn :1, // - print debugging info
  462. when :1, //
  463. write :1, // - print a picture record
  464. y :null}; // - transliterate a string
  465. var RXstyle="string-2";
  466. var RXmodifiers=/[goseximacplud]/; // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type
  467. function tokenChain(stream,state,chain,style,tail){ // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)
  468. state.chain=null; // 12 3tail
  469. state.style=null;
  470. state.tail=null;
  471. state.tokenize=function(stream,state){
  472. var e=false,c,i=0;
  473. while(c=stream.next()){
  474. if(c===chain[i]&&!e){
  475. if(chain[++i]!==undefined){
  476. state.chain=chain[i];
  477. state.style=style;
  478. state.tail=tail;}
  479. else if(tail)
  480. stream.eatWhile(tail);
  481. state.tokenize=tokenPerl;
  482. return style;}
  483. e=!e&&c=="\\";}
  484. return style;};
  485. return state.tokenize(stream,state);}
  486. function tokenSOMETHING(stream,state,string){
  487. state.tokenize=function(stream,state){
  488. if(stream.string==string)
  489. state.tokenize=tokenPerl;
  490. stream.skipToEnd();
  491. return "string";};
  492. return state.tokenize(stream,state);}
  493. function tokenPerl(stream,state){
  494. if(stream.eatSpace())
  495. return null;
  496. if(state.chain)
  497. return tokenChain(stream,state,state.chain,state.style,state.tail);
  498. if(stream.match(/^\-?[\d\.]/,false))
  499. if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
  500. return 'number';
  501. if(stream.match(/^<<(?=\w)/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\n
  502. stream.eatWhile(/\w/);
  503. return tokenSOMETHING(stream,state,stream.current().substr(2));}
  504. if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
  505. return tokenSOMETHING(stream,state,'=cut');}
  506. var ch=stream.next();
  507. if(ch=='"'||ch=="'"){ // NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\n
  508. if(stream.prefix(3)=="<<"+ch){
  509. var p=stream.pos;
  510. stream.eatWhile(/\w/);
  511. var n=stream.current().substr(1);
  512. if(n&&stream.eat(ch))
  513. return tokenSOMETHING(stream,state,n);
  514. stream.pos=p;}
  515. return tokenChain(stream,state,[ch],"string");}
  516. if(ch=="q"){
  517. var c=stream.look(-2);
  518. if(!(c&&/\w/.test(c))){
  519. c=stream.look(0);
  520. if(c=="x"){
  521. c=stream.look(1);
  522. if(c=="("){
  523. stream.eatSuffix(2);
  524. return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
  525. if(c=="["){
  526. stream.eatSuffix(2);
  527. return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
  528. if(c=="{"){
  529. stream.eatSuffix(2);
  530. return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
  531. if(c=="<"){
  532. stream.eatSuffix(2);
  533. return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
  534. if(/[\^'"!~\/]/.test(c)){
  535. stream.eatSuffix(1);
  536. return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
  537. else if(c=="q"){
  538. c=stream.look(1);
  539. if(c=="("){
  540. stream.eatSuffix(2);
  541. return tokenChain(stream,state,[")"],"string");}
  542. if(c=="["){
  543. stream.eatSuffix(2);
  544. return tokenChain(stream,state,["]"],"string");}
  545. if(c=="{"){
  546. stream.eatSuffix(2);
  547. return tokenChain(stream,state,["}"],"string");}
  548. if(c=="<"){
  549. stream.eatSuffix(2);
  550. return tokenChain(stream,state,[">"],"string");}
  551. if(/[\^'"!~\/]/.test(c)){
  552. stream.eatSuffix(1);
  553. return tokenChain(stream,state,[stream.eat(c)],"string");}}
  554. else if(c=="w"){
  555. c=stream.look(1);
  556. if(c=="("){
  557. stream.eatSuffix(2);
  558. return tokenChain(stream,state,[")"],"bracket");}
  559. if(c=="["){
  560. stream.eatSuffix(2);
  561. return tokenChain(stream,state,["]"],"bracket");}
  562. if(c=="{"){
  563. stream.eatSuffix(2);
  564. return tokenChain(stream,state,["}"],"bracket");}
  565. if(c=="<"){
  566. stream.eatSuffix(2);
  567. return tokenChain(stream,state,[">"],"bracket");}
  568. if(/[\^'"!~\/]/.test(c)){
  569. stream.eatSuffix(1);
  570. return tokenChain(stream,state,[stream.eat(c)],"bracket");}}
  571. else if(c=="r"){
  572. c=stream.look(1);
  573. if(c=="("){
  574. stream.eatSuffix(2);
  575. return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
  576. if(c=="["){
  577. stream.eatSuffix(2);
  578. return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
  579. if(c=="{"){
  580. stream.eatSuffix(2);
  581. return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
  582. if(c=="<"){
  583. stream.eatSuffix(2);
  584. return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}
  585. if(/[\^'"!~\/]/.test(c)){
  586. stream.eatSuffix(1);
  587. return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}
  588. else if(/[\^'"!~\/(\[{<]/.test(c)){
  589. if(c=="("){
  590. stream.eatSuffix(1);
  591. return tokenChain(stream,state,[")"],"string");}
  592. if(c=="["){
  593. stream.eatSuffix(1);
  594. return tokenChain(stream,state,["]"],"string");}
  595. if(c=="{"){
  596. stream.eatSuffix(1);
  597. return tokenChain(stream,state,["}"],"string");}
  598. if(c=="<"){
  599. stream.eatSuffix(1);
  600. return tokenChain(stream,state,[">"],"string");}
  601. if(/[\^'"!~\/]/.test(c)){
  602. return tokenChain(stream,state,[stream.eat(c)],"string");}}}}
  603. if(ch=="m"){
  604. var c=stream.look(-2);
  605. if(!(c&&/\w/.test(c))){
  606. c=stream.eat(/[(\[{<\^'"!~\/]/);
  607. if(c){
  608. if(/[\^'"!~\/]/.test(c)){
  609. return tokenChain(stream,state,[c],RXstyle,RXmodifiers);}
  610. if(c=="("){
  611. return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}
  612. if(c=="["){
  613. return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}
  614. if(c=="{"){
  615. return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}
  616. if(c=="<"){
  617. return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}}
  618. if(ch=="s"){
  619. var c=/[\/>\]})\w]/.test(stream.look(-2));
  620. if(!c){
  621. c=stream.eat(/[(\[{<\^'"!~\/]/);
  622. if(c){
  623. if(c=="[")
  624. return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
  625. if(c=="{")
  626. return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
  627. if(c=="<")
  628. return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
  629. if(c=="(")
  630. return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
  631. return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
  632. if(ch=="y"){
  633. var c=/[\/>\]})\w]/.test(stream.look(-2));
  634. if(!c){
  635. c=stream.eat(/[(\[{<\^'"!~\/]/);
  636. if(c){
  637. if(c=="[")
  638. return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
  639. if(c=="{")
  640. return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
  641. if(c=="<")
  642. return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
  643. if(c=="(")
  644. return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
  645. return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}
  646. if(ch=="t"){
  647. var c=/[\/>\]})\w]/.test(stream.look(-2));
  648. if(!c){
  649. c=stream.eat("r");if(c){
  650. c=stream.eat(/[(\[{<\^'"!~\/]/);
  651. if(c){
  652. if(c=="[")
  653. return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
  654. if(c=="{")
  655. return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
  656. if(c=="<")
  657. return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
  658. if(c=="(")
  659. return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
  660. return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}}
  661. if(ch=="`"){
  662. return tokenChain(stream,state,[ch],"variable-2");}
  663. if(ch=="/"){
  664. if(!/~\s*$/.test(stream.prefix()))
  665. return "operator";
  666. else
  667. return tokenChain(stream,state,[ch],RXstyle,RXmodifiers);}
  668. if(ch=="$"){
  669. var p=stream.pos;
  670. if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))
  671. return "variable-2";
  672. else
  673. stream.pos=p;}
  674. if(/[$@%]/.test(ch)){
  675. var p=stream.pos;
  676. if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(stream.look(-2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){
  677. var c=stream.current();
  678. if(PERL[c])
  679. return "variable-2";}
  680. stream.pos=p;}
  681. if(/[$@%&]/.test(ch)){
  682. if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
  683. var c=stream.current();
  684. if(PERL[c])
  685. return "variable-2";
  686. else
  687. return "variable";}}
  688. if(ch=="#"){
  689. if(stream.look(-2)!="$"){
  690. stream.skipToEnd();
  691. return "comment";}}
  692. if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){
  693. var p=stream.pos;
  694. stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);
  695. if(PERL[stream.current()])
  696. return "operator";
  697. else
  698. stream.pos=p;}
  699. if(ch=="_"){
  700. if(stream.pos==1){
  701. if(stream.suffix(6)=="_END__"){
  702. return tokenChain(stream,state,['\0'],"comment");}
  703. else if(stream.suffix(7)=="_DATA__"){
  704. return tokenChain(stream,state,['\0'],"variable-2");}
  705. else if(stream.suffix(7)=="_C__"){
  706. return tokenChain(stream,state,['\0'],"string");}}}
  707. if(/\w/.test(ch)){
  708. var p=stream.pos;
  709. if(stream.look(-2)=="{"&&(stream.look(0)=="}"||stream.eatWhile(/\w/)&&stream.look(0)=="}"))
  710. return "string";
  711. else
  712. stream.pos=p;}
  713. if(/[A-Z]/.test(ch)){
  714. var l=stream.look(-2);
  715. var p=stream.pos;
  716. stream.eatWhile(/[A-Z_]/);
  717. if(/[\da-z]/.test(stream.look(0))){
  718. stream.pos=p;}
  719. else{
  720. var c=PERL[stream.current()];
  721. if(!c)
  722. return "meta";
  723. if(c[1])
  724. c=c[0];
  725. if(l!=":"){
  726. if(c==1)
  727. return "keyword";
  728. else if(c==2)
  729. return "def";
  730. else if(c==3)
  731. return "atom";
  732. else if(c==4)
  733. return "operator";
  734. else if(c==5)
  735. return "variable-2";
  736. else
  737. return "meta";}
  738. else
  739. return "meta";}}
  740. if(/[a-zA-Z_]/.test(ch)){
  741. var l=stream.look(-2);
  742. stream.eatWhile(/\w/);
  743. var c=PERL[stream.current()];
  744. if(!c)
  745. return "meta";
  746. if(c[1])
  747. c=c[0];
  748. if(l!=":"){
  749. if(c==1)
  750. return "keyword";
  751. else if(c==2)
  752. return "def";
  753. else if(c==3)
  754. return "atom";
  755. else if(c==4)
  756. return "operator";
  757. else if(c==5)
  758. return "variable-2";
  759. else
  760. return "meta";}
  761. else
  762. return "meta";}
  763. return null;}
  764. return{
  765. startState:function(){
  766. return{
  767. tokenize:tokenPerl,
  768. chain:null,
  769. style:null,
  770. tail:null};},
  771. token:function(stream,state){
  772. return (state.tokenize||tokenPerl)(stream,state);},
  773. electricChars:"{}"};});
  774. CodeMirror.defineMIME("text/x-perl", "perl");
  775. // it's like "peek", but need for look-ahead or look-behind if index < 0
  776. CodeMirror.StringStream.prototype.look=function(c){
  777. return this.string.charAt(this.pos+(c||0));};
  778. // return a part of prefix of current stream from current position
  779. CodeMirror.StringStream.prototype.prefix=function(c){
  780. if(c){
  781. var x=this.pos-c;
  782. return this.string.substr((x>=0?x:0),c);}
  783. else{
  784. return this.string.substr(0,this.pos-1);}};
  785. // return a part of suffix of current stream from current position
  786. CodeMirror.StringStream.prototype.suffix=function(c){
  787. var y=this.string.length;
  788. var x=y-this.pos+1;
  789. return this.string.substr(this.pos,(c&&c<y?c:x));};
  790. // return a part of suffix of current stream from current position and change current position
  791. CodeMirror.StringStream.prototype.nsuffix=function(c){
  792. var p=this.pos;
  793. var l=c||(this.string.length-this.pos+1);
  794. this.pos+=l;
  795. return this.string.substr(p,l);};
  796. // eating and vomiting a part of stream from current position
  797. CodeMirror.StringStream.prototype.eatSuffix=function(c){
  798. var x=this.pos+c;
  799. var y;
  800. if(x<=0)
  801. this.pos=0;
  802. else if(x>=(y=this.string.length-1))
  803. this.pos=y;
  804. else
  805. this.pos=x;};