topical media & game development
mobile-query-three-www-vendor-CodeMirror2-mode-perl-perl.js / js
// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
// This is a part of CodeMirror from github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)
CodeMirror.defineMode("perl",function(config,parserConfig){
// http://perldoc.perl.org
var 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,
'_' : 5,
'@ARG' : 5,
'@_' : 5,
'"' : 5,
'PID' : 5,
'$$' : 5,
'GID' : 5,
'$(' : 5,
'EGID' : 5,
'PROGRAM_NAME' : 5,
'$0' : 5,
'SUBSEP' : 5,
'REAL_USER_ID' : 5,
'<' : 5,
'EUID' : 5,
'a' : 5,
'COMPILING' : 5,
'DEBUGGING' : 5,
'{^ENCODING}' : 5,
'SYSTEM_FD_MAX' : 5,
'{^GLOBAL_PHASE}' : 5,
'INPLACE_EDIT' : 5,
'^M' : 5,
'^O' : 5,
'PERLDB' : 5,
'SIG' : 5,
'\%SIG' : 5,
'^T' : 5,
'{^UNICODE}' : 5,
'{^UTF8LOCALE}' : 5,
'^V' : 5,
'EXECUTABLE_NAME' : 5,
'MATCH' : 5,
'{^MATCH}' : 5,
'`' : 5,
'POSTMATCH' : 5,
"{^POSTMATCH}' : 5,
'+' : 5,
'^N' : 5,
'@LAST_MATCH_END' : 5,
'@+' : 5,
'\%LAST_PAREN_MATCH' : 5,
'%+' : 5,
'@LAST_MATCH_START' : 5,
'@-' : 5,
'\%LAST_MATCH_START' : 5,
'%-' : 5,
'^R' : 5,
'{^RE_TRIE_MAXBUF}' : 5,
'OUTPUT_FIELD_SEPARATOR' : 5,
',' : 5,
'NR' : 5,
'INPUT_RECORD_SEPARATOR' : 5,
'/' : 5,
'ORS' : 5,
'OUTPUT_AUTOFLUSH' : 5,
'ACCUMULATOR' : 5,
'FORMAT_FORMFEED' : 5,
'FORMAT_PAGE_NUMBER' : 5,
'FORMAT_LINES_LEFT' : 5,
'FORMAT_LINE_BREAK_CHARACTERS' : 5,
'FORMAT_LINES_PER_PAGE' : 5,
'FORMAT_TOP_NAME' : 5,
'FORMAT_NAME' : 5,
'{^CHILD_ERROR_NATIVE}' : 5,
'^E' : 5,
'^S' : 5,
'^W' : 5,
'OS_ERROR' : 5,
'!' : 5,
'\%OS_ERROR' : 5,
'\%ERRNO' : 5,
'%!' : 5,
'?' : 5,
'@' : 5,
'#' : 5,
'ARRAY_BASE' : 5,
'OLD_PERL_VERSION' : 5,
'/.test(stream.prefix()))
return "operator";
else
return tokenChain(stream,state,[ch],RXstyle,RXmodifiers)}
if(ch=="@%]/.test(ch)){
var p=stream.pos;
if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@+.,\/<>()]/)){
var c=stream.current();
if(PERL[c])
return "variable-2"}
stream.pos=p}
if(/[\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w"){
stream.skipToEnd();
return "comment"}}
if(/[:+\-^*&%@=<>!?|\/~\.]/);
if(PERL[stream.current()])
return "operator";
else
stream.pos=p}
if(ch=="_"){
if(stream.pos==1){
if(stream.suffix(6)=="_END__"){
return tokenChain(stream,state,['\0'],"comment")}
else if(stream.suffix(7)=="_DATA__"){
return tokenChain(stream,state,['\0'],"variable-2")}
else if(stream.suffix(7)=="_C__"){
return tokenChain(stream,state,['\0'],"string")}}}
if(/\w/.test(ch)){
var p=stream.pos;
if(stream.look(-2)=="{"&&(stream.look(0)=="}"||stream.eatWhile(/\w/)&&stream.look(0)=="}"))
return "string";
else
stream.pos=p}
if(/[A-Z]/.test(ch)){
var l=stream.look(-2);
var p=stream.pos;
stream.eatWhile(/[A-Z_]/);
if(/[\da-z]/.test(stream.look(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";
else
return "meta"}
else
return "meta"}}
if(/[a-zA-Z_]/.test(ch)){
var l=stream.look(-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";
else
return "meta"}
else
return "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)},
electricChars:"{}"}});
CodeMirror.defineMIME("text/x-perl", "perl");
// it's like "peek", but need for look-ahead or look-behind if index < 0
CodeMirror.StringStream.prototype.look=function(c){
return this.string.charAt(this.pos+(c||0))};
// return a part of prefix of current stream from current position
CodeMirror.StringStream.prototype.prefix=function(c){
if(c){
var x=this.pos-c;
return this.string.substr((x>=0?x:0),c)}
else{
return this.string.substr(0,this.pos-1)}};
// return a part of suffix of current stream from current position
CodeMirror.StringStream.prototype.suffix=function(c){
var y=this.string.length;
var x=y-this.pos+1;
return this.string.substr(this.pos,(c&&c<y?c:x))};
// return a part of suffix of current stream from current position and change current position
CodeMirror.StringStream.prototype.nsuffix=function(c){
var p=this.pos;
var l=c||(this.string.length-this.pos+1);
this.pos+=l;
return this.string.substr(p,l)};
// eating and vomiting a part of stream from current position
CodeMirror.StringStream.prototype.eatSuffix=function(c){
var x=this.pos+c;
var y;
if(x<=0)
this.pos=0;
else if(x>=(y=this.string.length-1))
this.pos=y;
else
this.pos=x};
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.