Blame | Letzte Änderung | Log anzeigen | RSS feed
// CodeMirror, copyright (c) by Marijn Haverbeke and others// Distributed under an MIT license: http://codemirror.net/LICENSE// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)(function(mod) {if (typeof exports == "object" && typeof module == "object") // CommonJSmod(require("../../lib/codemirror"));else if (typeof define == "function" && define.amd) // AMDdefine(["../../lib/codemirror"], mod);else // Plain browser envmod(CodeMirror);})(function(CodeMirror) {"use strict";CodeMirror.defineMode("perl",function(){// http://perldoc.perl.orgvar PERL={ // null - magic touch// 1 - keyword// 2 - def// 3 - atom// 4 - operator// 5 - variable-2 (predefined)// [x,y] - x=1,2,3; y=must be defined if x{...}// PERL operators'->' : 4,'++' : 4,'--' : 4,'**' : 4,// ! ~ \ and unary + and -'=~' : 4,'!~' : 4,'*' : 4,'/' : 4,'%' : 4,'x' : 4,'+' : 4,'-' : 4,'.' : 4,'<<' : 4,'>>' : 4,// named unary operators'<' : 4,'>' : 4,'<=' : 4,'>=' : 4,'lt' : 4,'gt' : 4,'le' : 4,'ge' : 4,'==' : 4,'!=' : 4,'<=>' : 4,'eq' : 4,'ne' : 4,'cmp' : 4,'~~' : 4,'&' : 4,'|' : 4,'^' : 4,'&&' : 4,'||' : 4,'//' : 4,'..' : 4,'...' : 4,'?' : 4,':' : 4,'=' : 4,'+=' : 4,'-=' : 4,'*=' : 4, // etc. ???',' : 4,'=>' : 4,'::' : 4,// list operators (rightward)'not' : 4,'and' : 4,'or' : 4,'xor' : 4,// 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?;)'BEGIN' : [5,1],'END' : [5,1],'PRINT' : [5,1],'PRINTF' : [5,1],'GETC' : [5,1],'READ' : [5,1],'READLINE' : [5,1],'DESTROY' : [5,1],'TIE' : [5,1],'TIEHANDLE' : [5,1],'UNTIE' : [5,1],'STDIN' : 5,'STDIN_TOP' : 5,'STDOUT' : 5,'STDOUT_TOP' : 5,'STDERR' : 5,'STDERR_TOP' : 5,'$ARG' : 5,'$_' : 5,'@ARG' : 5,'@_' : 5,'$LIST_SEPARATOR' : 5,'$"' : 5,'$PROCESS_ID' : 5,'$PID' : 5,'$$' : 5,'$REAL_GROUP_ID' : 5,'$GID' : 5,'$(' : 5,'$EFFECTIVE_GROUP_ID' : 5,'$EGID' : 5,'$)' : 5,'$PROGRAM_NAME' : 5,'$0' : 5,'$SUBSCRIPT_SEPARATOR' : 5,'$SUBSEP' : 5,'$;' : 5,'$REAL_USER_ID' : 5,'$UID' : 5,'$<' : 5,'$EFFECTIVE_USER_ID' : 5,'$EUID' : 5,'$>' : 5,'$a' : 5,'$b' : 5,'$COMPILING' : 5,'$^C' : 5,'$DEBUGGING' : 5,'$^D' : 5,'${^ENCODING}' : 5,'$ENV' : 5,'%ENV' : 5,'$SYSTEM_FD_MAX' : 5,'$^F' : 5,'@F' : 5,'${^GLOBAL_PHASE}' : 5,'$^H' : 5,'%^H' : 5,'@INC' : 5,'%INC' : 5,'$INPLACE_EDIT' : 5,'$^I' : 5,'$^M' : 5,'$OSNAME' : 5,'$^O' : 5,'${^OPEN}' : 5,'$PERLDB' : 5,'$^P' : 5,'$SIG' : 5,'%SIG' : 5,'$BASETIME' : 5,'$^T' : 5,'${^TAINT}' : 5,'${^UNICODE}' : 5,'${^UTF8CACHE}' : 5,'${^UTF8LOCALE}' : 5,'$PERL_VERSION' : 5,'$^V' : 5,'${^WIN32_SLOPPY_STAT}' : 5,'$EXECUTABLE_NAME' : 5,'$^X' : 5,'$1' : 5, // - regexp $1, $2...'$MATCH' : 5,'$&' : 5,'${^MATCH}' : 5,'$PREMATCH' : 5,'$`' : 5,'${^PREMATCH}' : 5,'$POSTMATCH' : 5,"$'" : 5,'${^POSTMATCH}' : 5,'$LAST_PAREN_MATCH' : 5,'$+' : 5,'$LAST_SUBMATCH_RESULT' : 5,'$^N' : 5,'@LAST_MATCH_END' : 5,'@+' : 5,'%LAST_PAREN_MATCH' : 5,'%+' : 5,'@LAST_MATCH_START' : 5,'@-' : 5,'%LAST_MATCH_START' : 5,'%-' : 5,'$LAST_REGEXP_CODE_RESULT' : 5,'$^R' : 5,'${^RE_DEBUG_FLAGS}' : 5,'${^RE_TRIE_MAXBUF}' : 5,'$ARGV' : 5,'@ARGV' : 5,'ARGV' : 5,'ARGVOUT' : 5,'$OUTPUT_FIELD_SEPARATOR' : 5,'$OFS' : 5,'$,' : 5,'$INPUT_LINE_NUMBER' : 5,'$NR' : 5,'$.' : 5,'$INPUT_RECORD_SEPARATOR' : 5,'$RS' : 5,'$/' : 5,'$OUTPUT_RECORD_SEPARATOR' : 5,'$ORS' : 5,'$\\' : 5,'$OUTPUT_AUTOFLUSH' : 5,'$|' : 5,'$ACCUMULATOR' : 5,'$^A' : 5,'$FORMAT_FORMFEED' : 5,'$^L' : 5,'$FORMAT_PAGE_NUMBER' : 5,'$%' : 5,'$FORMAT_LINES_LEFT' : 5,'$-' : 5,'$FORMAT_LINE_BREAK_CHARACTERS' : 5,'$:' : 5,'$FORMAT_LINES_PER_PAGE' : 5,'$=' : 5,'$FORMAT_TOP_NAME' : 5,'$^' : 5,'$FORMAT_NAME' : 5,'$~' : 5,'${^CHILD_ERROR_NATIVE}' : 5,'$EXTENDED_OS_ERROR' : 5,'$^E' : 5,'$EXCEPTIONS_BEING_CAUGHT' : 5,'$^S' : 5,'$WARNING' : 5,'$^W' : 5,'${^WARNING_BITS}' : 5,'$OS_ERROR' : 5,'$ERRNO' : 5,'$!' : 5,'%OS_ERROR' : 5,'%ERRNO' : 5,'%!' : 5,'$CHILD_ERROR' : 5,'$?' : 5,'$EVAL_ERROR' : 5,'$@' : 5,'$OFMT' : 5,'$#' : 5,'$*' : 5,'$ARRAY_BASE' : 5,'$[' : 5,'$OLD_PERL_VERSION' : 5,'$]' : 5,// PERL blocks'if' :[1,1],elsif :[1,1],'else' :[1,1],'while' :[1,1],unless :[1,1],'for' :[1,1],foreach :[1,1],// PERL functions'abs' :1, // - absolute value functionaccept :1, // - accept an incoming socket connectalarm :1, // - schedule a SIGALRM'atan2' :1, // - arctangent of Y/X in the range -PI to PIbind :1, // - binds an address to a socketbinmode :1, // - prepare binary files for I/Obless :1, // - create an objectbootstrap :1, //'break' :1, // - break out of a "given" blockcaller :1, // - get context of the current subroutine callchdir :1, // - change your current working directorychmod :1, // - changes the permissions on a list of fileschomp :1, // - remove a trailing record separator from a stringchop :1, // - remove the last character from a stringchown :1, // - change the owership on a list of fileschr :1, // - get character this number representschroot :1, // - make directory new root for path lookupsclose :1, // - close file (or pipe or socket) handleclosedir :1, // - close directory handleconnect :1, // - connect to a remote socket'continue' :[1,1], // - optional trailing block in a while or foreach'cos' :1, // - cosine functioncrypt :1, // - one-way passwd-style encryptiondbmclose :1, // - breaks binding on a tied dbm filedbmopen :1, // - create binding on a tied dbm file'default' :1, //defined :1, // - test whether a value, variable, or function is defined'delete' :1, // - deletes a value from a hashdie :1, // - raise an exception or bail out'do' :1, // - turn a BLOCK into a TERMdump :1, // - create an immediate core dumpeach :1, // - retrieve the next key/value pair from a hashendgrent :1, // - be done using group fileendhostent :1, // - be done using hosts fileendnetent :1, // - be done using networks fileendprotoent :1, // - be done using protocols fileendpwent :1, // - be done using passwd fileendservent :1, // - be done using services fileeof :1, // - test a filehandle for its end'eval' :1, // - catch exceptions or compile and run code'exec' :1, // - abandon this program to run anotherexists :1, // - test whether a hash key is presentexit :1, // - terminate this program'exp' :1, // - raise I to a powerfcntl :1, // - file control system callfileno :1, // - return file descriptor from filehandleflock :1, // - lock an entire file with an advisory lockfork :1, // - create a new process just like this oneformat :1, // - declare a picture format with use by the write() functionformline :1, // - internal function used for formatsgetc :1, // - get the next character from the filehandlegetgrent :1, // - get next group recordgetgrgid :1, // - get group record given group user IDgetgrnam :1, // - get group record given group namegethostbyaddr :1, // - get host record given its addressgethostbyname :1, // - get host record given namegethostent :1, // - get next hosts recordgetlogin :1, // - return who logged in at this ttygetnetbyaddr :1, // - get network record given its addressgetnetbyname :1, // - get networks record given namegetnetent :1, // - get next networks recordgetpeername :1, // - find the other end of a socket connectiongetpgrp :1, // - get process groupgetppid :1, // - get parent process IDgetpriority :1, // - get current nice valuegetprotobyname :1, // - get protocol record given namegetprotobynumber :1, // - get protocol record numeric protocolgetprotoent :1, // - get next protocols recordgetpwent :1, // - get next passwd recordgetpwnam :1, // - get passwd record given user login namegetpwuid :1, // - get passwd record given user IDgetservbyname :1, // - get services record given its namegetservbyport :1, // - get services record given numeric portgetservent :1, // - get next services recordgetsockname :1, // - retrieve the sockaddr for a given socketgetsockopt :1, // - get socket options on a given socketgiven :1, //glob :1, // - expand filenames using wildcardsgmtime :1, // - convert UNIX time into record or string using Greenwich time'goto' :1, // - create spaghetti codegrep :1, // - locate elements in a list test true against a given criterionhex :1, // - convert a string to a hexadecimal number'import' :1, // - patch a module's namespace into your ownindex :1, // - find a substring within a string'int' :1, // - get the integer portion of a numberioctl :1, // - system-dependent device control system call'join' :1, // - join a list into a string using a separatorkeys :1, // - retrieve list of indices from a hashkill :1, // - send a signal to a process or process grouplast :1, // - exit a block prematurelylc :1, // - return lower-case version of a stringlcfirst :1, // - return a string with just the next letter in lower caselength :1, // - return the number of bytes in a string'link' :1, // - create a hard link in the filesytemlisten :1, // - register your socket as a serverlocal : 2, // - create a temporary value for a global variable (dynamic scoping)localtime :1, // - convert UNIX time into record or string using local timelock :1, // - get a thread lock on a variable, subroutine, or method'log' :1, // - retrieve the natural logarithm for a numberlstat :1, // - stat a symbolic linkm :null, // - match a string with a regular expression patternmap :1, // - apply a change to a list to get back a new list with the changesmkdir :1, // - create a directorymsgctl :1, // - SysV IPC message control operationsmsgget :1, // - get SysV IPC message queuemsgrcv :1, // - receive a SysV IPC message from a message queuemsgsnd :1, // - send a SysV IPC message to a message queuemy : 2, // - declare and assign a local variable (lexical scoping)'new' :1, //next :1, // - iterate a block prematurelyno :1, // - unimport some module symbols or semantics at compile timeoct :1, // - convert a string to an octal numberopen :1, // - open a file, pipe, or descriptoropendir :1, // - open a directoryord :1, // - find a character's numeric representationour : 2, // - declare and assign a package variable (lexical scoping)pack :1, // - convert a list into a binary representation'package' :1, // - declare a separate global namespacepipe :1, // - open a pair of connected filehandlespop :1, // - remove the last element from an array and return itpos :1, // - find or set the offset for the last/next m//g searchprint :1, // - output a list to a filehandleprintf :1, // - output a formatted list to a filehandleprototype :1, // - get the prototype (if any) of a subroutinepush :1, // - append one or more elements to an arrayq :null, // - singly quote a stringqq :null, // - doubly quote a stringqr :null, // - Compile patternquotemeta :null, // - quote regular expression magic charactersqw :null, // - quote a list of wordsqx :null, // - backquote quote a stringrand :1, // - retrieve the next pseudorandom numberread :1, // - fixed-length buffered input from a filehandlereaddir :1, // - get a directory from a directory handlereadline :1, // - fetch a record from a filereadlink :1, // - determine where a symbolic link is pointingreadpipe :1, // - execute a system command and collect standard outputrecv :1, // - receive a message over a Socketredo :1, // - start this loop iteration over againref :1, // - find out the type of thing being referencedrename :1, // - change a filenamerequire :1, // - load in external functions from a library at runtimereset :1, // - clear all variables of a given name'return' :1, // - get out of a function earlyreverse :1, // - flip a string or a listrewinddir :1, // - reset directory handlerindex :1, // - right-to-left substring searchrmdir :1, // - remove a directorys :null, // - replace a pattern with a stringsay :1, // - print with newlinescalar :1, // - force a scalar contextseek :1, // - reposition file pointer for random-access I/Oseekdir :1, // - reposition directory pointerselect :1, // - reset default output or do I/O multiplexingsemctl :1, // - SysV semaphore control operationssemget :1, // - get set of SysV semaphoressemop :1, // - SysV semaphore operationssend :1, // - send a message over a socketsetgrent :1, // - prepare group file for usesethostent :1, // - prepare hosts file for usesetnetent :1, // - prepare networks file for usesetpgrp :1, // - set the process group of a processsetpriority :1, // - set a process's nice valuesetprotoent :1, // - prepare protocols file for usesetpwent :1, // - prepare passwd file for usesetservent :1, // - prepare services file for usesetsockopt :1, // - set some socket optionsshift :1, // - remove the first element of an array, and return itshmctl :1, // - SysV shared memory operationsshmget :1, // - get SysV shared memory segment identifiershmread :1, // - read SysV shared memoryshmwrite :1, // - write SysV shared memoryshutdown :1, // - close down just half of a socket connection'sin' :1, // - return the sine of a numbersleep :1, // - block for some number of secondssocket :1, // - create a socketsocketpair :1, // - create a pair of sockets'sort' :1, // - sort a list of valuessplice :1, // - add or remove elements anywhere in an array'split' :1, // - split up a string using a regexp delimitersprintf :1, // - formatted print into a string'sqrt' :1, // - square root functionsrand :1, // - seed the random number generatorstat :1, // - get a file's status informationstate :1, // - declare and assign a state variable (persistent lexical scoping)study :1, // - optimize input data for repeated searches'sub' :1, // - declare a subroutine, possibly anonymously'substr' :1, // - get or alter a portion of a stirngsymlink :1, // - create a symbolic link to a filesyscall :1, // - execute an arbitrary system callsysopen :1, // - open a file, pipe, or descriptorsysread :1, // - fixed-length unbuffered input from a filehandlesysseek :1, // - position I/O pointer on handle used with sysread and syswritesystem :1, // - run a separate programsyswrite :1, // - fixed-length unbuffered output to a filehandletell :1, // - get current seekpointer on a filehandletelldir :1, // - get current seekpointer on a directory handletie :1, // - bind a variable to an object classtied :1, // - get a reference to the object underlying a tied variabletime :1, // - return number of seconds since 1970times :1, // - return elapsed time for self and child processestr :null, // - transliterate a stringtruncate :1, // - shorten a fileuc :1, // - return upper-case version of a stringucfirst :1, // - return a string with just the next letter in upper caseumask :1, // - set file creation mode maskundef :1, // - remove a variable or function definitionunlink :1, // - remove one link to a fileunpack :1, // - convert binary structure into normal perl variablesunshift :1, // - prepend more elements to the beginning of a listuntie :1, // - break a tie binding to a variableuse :1, // - load in a module at compile timeutime :1, // - set a file's last access and modify timesvalues :1, // - return a list of the values in a hashvec :1, // - test or set particular bits in a stringwait :1, // - wait for any child process to diewaitpid :1, // - wait for a particular child process to diewantarray :1, // - get void vs scalar vs list context of current subroutine callwarn :1, // - print debugging infowhen :1, //write :1, // - print a picture recordy :null}; // - transliterate a stringvar RXstyle="string-2";var RXmodifiers=/[goseximacplud]/; // NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp typefunction tokenChain(stream,state,chain,style,tail){ // NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)state.chain=null; // 12 3tailstate.style=null;state.tail=null;state.tokenize=function(stream,state){var e=false,c,i=0;while(c=stream.next()){if(c===chain[i]&&!e){if(chain[++i]!==undefined){state.chain=chain[i];state.style=style;state.tail=tail;}else if(tail)stream.eatWhile(tail);state.tokenize=tokenPerl;return style;}e=!e&&c=="\\";}return style;};return state.tokenize(stream,state);}function tokenSOMETHING(stream,state,string){state.tokenize=function(stream,state){if(stream.string==string)state.tokenize=tokenPerl;stream.skipToEnd();return "string";};return state.tokenize(stream,state);}function tokenPerl(stream,state){if(stream.eatSpace())return null;if(state.chain)return tokenChain(stream,state,state.chain,state.style,state.tail);if(stream.match(/^\-?[\d\.]/,false))if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))return 'number';if(stream.match(/^<<(?=\w)/)){ // NOTE: <<SOMETHING\n...\nSOMETHING\nstream.eatWhile(/\w/);return tokenSOMETHING(stream,state,stream.current().substr(2));}if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\nreturn tokenSOMETHING(stream,state,'=cut');}var ch=stream.next();if(ch=='"'||ch=="'"){ // NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\nif(prefix(stream, 3)=="<<"+ch){var p=stream.pos;stream.eatWhile(/\w/);var n=stream.current().substr(1);if(n&&stream.eat(ch))return tokenSOMETHING(stream,state,n);stream.pos=p;}return tokenChain(stream,state,[ch],"string");}if(ch=="q"){var c=look(stream, -2);if(!(c&&/\w/.test(c))){c=look(stream, 0);if(c=="x"){c=look(stream, 1);if(c=="("){eatSuffix(stream, 2);return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}if(c=="["){eatSuffix(stream, 2);return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}if(c=="{"){eatSuffix(stream, 2);return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}if(c=="<"){eatSuffix(stream, 2);return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}if(/[\^'"!~\/]/.test(c)){eatSuffix(stream, 1);return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}else if(c=="q"){c=look(stream, 1);if(c=="("){eatSuffix(stream, 2);return tokenChain(stream,state,[")"],"string");}if(c=="["){eatSuffix(stream, 2);return tokenChain(stream,state,["]"],"string");}if(c=="{"){eatSuffix(stream, 2);return tokenChain(stream,state,["}"],"string");}if(c=="<"){eatSuffix(stream, 2);return tokenChain(stream,state,[">"],"string");}if(/[\^'"!~\/]/.test(c)){eatSuffix(stream, 1);return tokenChain(stream,state,[stream.eat(c)],"string");}}else if(c=="w"){c=look(stream, 1);if(c=="("){eatSuffix(stream, 2);return tokenChain(stream,state,[")"],"bracket");}if(c=="["){eatSuffix(stream, 2);return tokenChain(stream,state,["]"],"bracket");}if(c=="{"){eatSuffix(stream, 2);return tokenChain(stream,state,["}"],"bracket");}if(c=="<"){eatSuffix(stream, 2);return tokenChain(stream,state,[">"],"bracket");}if(/[\^'"!~\/]/.test(c)){eatSuffix(stream, 1);return tokenChain(stream,state,[stream.eat(c)],"bracket");}}else if(c=="r"){c=look(stream, 1);if(c=="("){eatSuffix(stream, 2);return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}if(c=="["){eatSuffix(stream, 2);return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}if(c=="{"){eatSuffix(stream, 2);return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}if(c=="<"){eatSuffix(stream, 2);return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}if(/[\^'"!~\/]/.test(c)){eatSuffix(stream, 1);return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers);}}else if(/[\^'"!~\/(\[{<]/.test(c)){if(c=="("){eatSuffix(stream, 1);return tokenChain(stream,state,[")"],"string");}if(c=="["){eatSuffix(stream, 1);return tokenChain(stream,state,["]"],"string");}if(c=="{"){eatSuffix(stream, 1);return tokenChain(stream,state,["}"],"string");}if(c=="<"){eatSuffix(stream, 1);return tokenChain(stream,state,[">"],"string");}if(/[\^'"!~\/]/.test(c)){return tokenChain(stream,state,[stream.eat(c)],"string");}}}}if(ch=="m"){var c=look(stream, -2);if(!(c&&/\w/.test(c))){c=stream.eat(/[(\[{<\^'"!~\/]/);if(c){if(/[\^'"!~\/]/.test(c)){return tokenChain(stream,state,[c],RXstyle,RXmodifiers);}if(c=="("){return tokenChain(stream,state,[")"],RXstyle,RXmodifiers);}if(c=="["){return tokenChain(stream,state,["]"],RXstyle,RXmodifiers);}if(c=="{"){return tokenChain(stream,state,["}"],RXstyle,RXmodifiers);}if(c=="<"){return tokenChain(stream,state,[">"],RXstyle,RXmodifiers);}}}}if(ch=="s"){var c=/[\/>\]})\w]/.test(look(stream, -2));if(!c){c=stream.eat(/[(\[{<\^'"!~\/]/);if(c){if(c=="[")return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);if(c=="{")return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);if(c=="<")return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);if(c=="(")return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}if(ch=="y"){var c=/[\/>\]})\w]/.test(look(stream, -2));if(!c){c=stream.eat(/[(\[{<\^'"!~\/]/);if(c){if(c=="[")return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);if(c=="{")return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);if(c=="<")return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);if(c=="(")return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}if(ch=="t"){var c=/[\/>\]})\w]/.test(look(stream, -2));if(!c){c=stream.eat("r");if(c){c=stream.eat(/[(\[{<\^'"!~\/]/);if(c){if(c=="[")return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);if(c=="{")return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);if(c=="<")return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);if(c=="(")return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers);}}}}if(ch=="`"){return tokenChain(stream,state,[ch],"variable-2");}if(ch=="/"){if(!/~\s*$/.test(prefix(stream)))return "operator";elsereturn tokenChain(stream,state,[ch],RXstyle,RXmodifiers);}if(ch=="$"){var p=stream.pos;if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))return "variable-2";elsestream.pos=p;}if(/[$@%]/.test(ch)){var p=stream.pos;if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(look(stream, -2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){var c=stream.current();if(PERL[c])return "variable-2";}stream.pos=p;}if(/[$@%&]/.test(ch)){if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){var c=stream.current();if(PERL[c])return "variable-2";elsereturn "variable";}}if(ch=="#"){if(look(stream, -2)!="$"){stream.skipToEnd();return "comment";}}if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){var p=stream.pos;stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);if(PERL[stream.current()])return "operator";elsestream.pos=p;}if(ch=="_"){if(stream.pos==1){if(suffix(stream, 6)=="_END__"){return tokenChain(stream,state,['\0'],"comment");}else if(suffix(stream, 7)=="_DATA__"){return tokenChain(stream,state,['\0'],"variable-2");}else if(suffix(stream, 7)=="_C__"){return tokenChain(stream,state,['\0'],"string");}}}if(/\w/.test(ch)){var p=stream.pos;if(look(stream, -2)=="{"&&(look(stream, 0)=="}"||stream.eatWhile(/\w/)&&look(stream, 0)=="}"))return "string";elsestream.pos=p;}if(/[A-Z]/.test(ch)){var l=look(stream, -2);var p=stream.pos;stream.eatWhile(/[A-Z_]/);if(/[\da-z]/.test(look(stream, 0))){stream.pos=p;}else{var c=PERL[stream.current()];if(!c)return "meta";if(c[1])c=c[0];if(l!=":"){if(c==1)return "keyword";else if(c==2)return "def";else if(c==3)return "atom";else if(c==4)return "operator";else if(c==5)return "variable-2";elsereturn "meta";}elsereturn "meta";}}if(/[a-zA-Z_]/.test(ch)){var l=look(stream, -2);stream.eatWhile(/\w/);var c=PERL[stream.current()];if(!c)return "meta";if(c[1])c=c[0];if(l!=":"){if(c==1)return "keyword";else if(c==2)return "def";else if(c==3)return "atom";else if(c==4)return "operator";else if(c==5)return "variable-2";elsereturn "meta";}elsereturn "meta";}return null;}return {startState: function() {return {tokenize: tokenPerl,chain: null,style: null,tail: null};},token: function(stream, state) {return (state.tokenize || tokenPerl)(stream, state);},lineComment: '#'};});CodeMirror.registerHelper("wordChars", "perl", /[\w$]/);CodeMirror.defineMIME("text/x-perl", "perl");// it's like "peek", but need for look-ahead or look-behind if index < 0function look(stream, c){return stream.string.charAt(stream.pos+(c||0));}// return a part of prefix of current stream from current positionfunction prefix(stream, c){if(c){var x=stream.pos-c;return stream.string.substr((x>=0?x:0),c);}else{return stream.string.substr(0,stream.pos-1);}}// return a part of suffix of current stream from current positionfunction suffix(stream, c){var y=stream.string.length;var x=y-stream.pos+1;return stream.string.substr(stream.pos,(c&&c<y?c:x));}// eating and vomiting a part of stream from current positionfunction eatSuffix(stream, c){var x=stream.pos+c;var y;if(x<=0)stream.pos=0;else if(x>=(y=stream.string.length-1))stream.pos=y;elsestream.pos=x;}});