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