annotate .cms/lib/codemirror/mode/sas/sas.js @ 1:1d486627aa1e draft default tip

24.10
author Coffee CMS <info@coffee-cms.ru>
date Sat, 12 Oct 2024 02:51:39 +0000
parents 78edf6b517a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 // SAS mode copyright (c) 2016 Jared Dean, SAS Institute
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6 // Created by Jared Dean
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 // TODO
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 // indent and de-indent
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10 // identify macro variables
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 //Definitions
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14 // comment -- text within * ; or /* */
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 // keyword -- SAS language variable
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 // variable -- macro variables starts with '&' or variable formats
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17 // variable-2 -- DATA Step, proc, or macro names
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18 // string -- text within ' ' or " "
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19 // operator -- numeric operator + / - * ** le eq ge ... and so on
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20 // builtin -- proc %macro data run mend
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 // atom
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 // def
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 (function(mod) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 if (typeof exports == "object" && typeof module == "object") // CommonJS
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 mod(require("../../lib/codemirror"));
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27 else if (typeof define == "function" && define.amd) // AMD
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 define(["../../lib/codemirror"], mod);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29 else // Plain browser env
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 mod(CodeMirror);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 })(function(CodeMirror) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 "use strict";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 CodeMirror.defineMode("sas", function () {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 var words = {};
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36 var isDoubleOperatorSym = {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 eq: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 lt: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 le: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 gt: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41 ge: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 "in": 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 ne: 'operator',
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 or: 'operator'
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 };
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 var isDoubleOperatorChar = /(<=|>=|!=|<>)/;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 var isSingleOperatorChar = /[=\(:\),{}.*<>+\-\/^\[\]]/;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 // Takes a string of words separated by spaces and adds them as
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 // keys with the value of the first argument 'style'
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 function define(style, string, context) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 if (context) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53 var split = string.split(' ');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 for (var i = 0; i < split.length; i++) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 words[split[i]] = {style: style, state: context};
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 //datastep
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 define('def', 'stack pgm view source debug nesting nolist', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61 define('def', 'if while until for do do; end end; then else cancel', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 define('def', 'label format _n_ _error_', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 define('def', 'ALTER BUFNO BUFSIZE CNTLLEV COMPRESS DLDMGACTION ENCRYPT ENCRYPTKEY EXTENDOBSCOUNTER GENMAX GENNUM INDEX LABEL OBSBUF OUTREP PW PWREQ READ REPEMPTY REPLACE REUSE ROLE SORTEDBY SPILL TOBSNO TYPE WRITE FILECLOSE FIRSTOBS IN OBS POINTOBS WHERE WHEREUP IDXNAME IDXWHERE DROP KEEP RENAME', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 define('def', 'filevar finfo finv fipname fipnamel fipstate first firstobs floor', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65 define('def', 'varfmt varinfmt varlabel varlen varname varnum varray varrayx vartype verify vformat vformatd vformatdx vformatn vformatnx vformatw vformatwx vformatx vinarray vinarrayx vinformat vinformatd vinformatdx vinformatn vinformatnx vinformatw vinformatwx vinformatx vlabel vlabelx vlength vlengthx vname vnamex vnferr vtype vtypex weekday', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 define('def', 'zipfips zipname zipnamel zipstate', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67 define('def', 'put putc putn', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 define('builtin', 'data run', ['inDataStep']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 //proc
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 define('def', 'data', ['inProc']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 // flow control for macros
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 define('def', '%if %end %end; %else %else; %do %do; %then', ['inMacro']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 //everywhere
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 define('builtin', 'proc run; quit; libname filename %macro %mend option options', ['ALL']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
79
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
80 define('def', 'footnote title libname ods', ['ALL']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
81 define('def', '%let %put %global %sysfunc %eval ', ['ALL']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
82 // automatic macro variables http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a003167023.htm
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
83 define('variable', '&sysbuffr &syscc &syscharwidth &syscmd &sysdate &sysdate9 &sysday &sysdevic &sysdmg &sysdsn &sysencoding &sysenv &syserr &syserrortext &sysfilrc &syshostname &sysindex &sysinfo &sysjobid &syslast &syslckrc &syslibrc &syslogapplname &sysmacroname &sysmenv &sysmsg &sysncpu &sysodspath &sysparm &syspbuff &sysprocessid &sysprocessname &sysprocname &sysrc &sysscp &sysscpl &sysscpl &syssite &sysstartid &sysstartname &systcpiphostname &systime &sysuserid &sysver &sysvlong &sysvlong4 &syswarningtext', ['ALL']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
84
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
85 //footnote[1-9]? title[1-9]?
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
86
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
87 //options statement
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
88 define('def', 'source2 nosource2 page pageno pagesize', ['ALL']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
89
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
90 //proc and datastep
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
91 define('def', '_all_ _character_ _cmd_ _freq_ _i_ _infile_ _last_ _msg_ _null_ _numeric_ _temporary_ _type_ abort abs addr adjrsq airy alpha alter altlog altprint and arcos array arsin as atan attrc attrib attrn authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward band base betainv between blocksize blshift bnot bor brshift bufno bufsize bxor by byerr byline byte calculated call cards cards4 catcache cbufno cdf ceil center cexist change chisq cinv class cleanup close cnonct cntllev coalesce codegen col collate collin column comamid comaux1 comaux2 comdef compbl compound compress config continue convert cos cosh cpuid create cross crosstab css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy datalines datalines4 datejul datepart datetime day dbcslang dbcstype dclose ddfm ddm delete delimiter depdb depdbsl depsl depsyd deptab dequote descending descript design= device dflang dhms dif digamma dim dinfo display distinct dkricond dkrocond dlm dnum do dopen doptname doptnum dread drop dropnote dsname dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov erf erfc error errorcheck errors exist exp fappend fclose fcol fdelete feedback fetch fetchobs fexist fget file fileclose fileexist filefmt filename fileref fmterr fmtsearch fnonct fnote font fontalias fopen foptname foptnum force formatted formchar formdelim formdlim forward fpoint fpos fput fread frewind frlen from fsep fuzz fwrite gaminv gamma getoption getvarc getvarn go goto group gwindow hbar hbound helpenv helploc hms honorappearance hosthelp hostprint hour hpct html hvar ibessel ibr id if index indexc indexw initcmd initstmt inner input inputc inputn inr insert int intck intnx into intrr invaliddata irr is jbessel join juldate keep kentb kurtosis label lag last lbound leave left length levels lgamma lib library libref line linesize link list log log10 log2 logpdf logpmf logsdf lostcard lowcase lrecl ls macro macrogen maps mautosource max maxdec maxr mdy mean measures median memtype merge merror min minute missing missover mlogic mod mode model modify month mopen mort mprint mrecall msglevel msymtabmax mvarsize myy n nest netpv new news nmiss no nobatch nobs nocaps nocardimage nocenter nocharcode nocmdmac nocol nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad nopercent noprint noprintinit normal norow norsasuser nosetinit nosplash nosymbolgen note notes notitle notitles notsorted noverbose noxsync noxwait npv null number numkeys nummousekeys nway obs on open order ordinal otherwise out outer outp= output over ovp p(1 5 10 25 50 75 90 95 99) pad pad2 paired parm parmcards path pathdll pathname pdf peek peekc pfkey pmf point poisson poke position printer probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probsig probt procleave prt ps pw pwreq qtr quote r ranbin rancau random ranexp rangam range ranks rannor ranpoi rantbl rantri ranuni rcorr read recfm register regr remote remove rename repeat repeated replace resolve retain return reuse reverse rewind right round rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sasmsg sasmstore sasscript sasuser saving scan sdf second select selection separated seq serror set setcomm setot sign simple sin sinh siteinfo skewness skip sle sls sortedby sortpgm sortseq sortsize soundex spedis splashlocation split spool sqrt start std stderr stdin stfips stimer stname stnamel stop stopover sub subgroup subpopn substr sum sumwgt symbol symbolgen symget symput sysget sysin sysleave sysmsg sysparm sysprint sysprintfont sysprod sysrc system t table tables tan tanh tapeclose tbufsize terminal test then timepart tinv tnonct to today tol tooldef totper transformout translate trantab tranwrd trigamma trim trimn trunc truncover type unformatted uniform union until upcase update user usericon uss validate value var weight when where while wincharset window work workinit workterm write wsum xsync xwait yearcutoff yes yyq min max', ['inDataStep', 'inProc']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
92 define('operator', 'and not ', ['inDataStep', 'inProc']);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
93
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
94 // Main function
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
95 function tokenize(stream, state) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
96 // Finally advance the stream
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
97 var ch = stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
98
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
99 // BLOCKCOMMENT
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
100 if (ch === '/' && stream.eat('*')) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
101 state.continueComment = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
102 return "comment";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
103 } else if (state.continueComment === true) { // in comment block
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
104 //comment ends at the beginning of the line
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
105 if (ch === '*' && stream.peek() === '/') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
106 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
107 state.continueComment = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
108 } else if (stream.skipTo('*')) { //comment is potentially later in line
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
109 stream.skipTo('*');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
110 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
111 if (stream.eat('/'))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
112 state.continueComment = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
113 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
114 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
115 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
116 return "comment";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
117 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
118
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
119 if (ch == "*" && stream.column() == stream.indentation()) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
120 stream.skipToEnd()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
121 return "comment"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
122 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
123
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
124 // DoubleOperator match
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
125 var doubleOperator = ch + stream.peek();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
126
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
127 if ((ch === '"' || ch === "'") && !state.continueString) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
128 state.continueString = ch
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
129 return "string"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
130 } else if (state.continueString) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
131 if (state.continueString == ch) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
132 state.continueString = null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
133 } else if (stream.skipTo(state.continueString)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
134 // quote found on this line
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
135 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
136 state.continueString = null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
137 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
138 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
139 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
140 return "string";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
141 } else if (state.continueString !== null && stream.eol()) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
142 stream.skipTo(state.continueString) || stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
143 return "string";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
144 } else if (/[\d\.]/.test(ch)) { //find numbers
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
145 if (ch === ".")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
146 stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
147 else if (ch === "0")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
148 stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
149 else
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
150 stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
151 return "number";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
152 } else if (isDoubleOperatorChar.test(ch + stream.peek())) { // TWO SYMBOL TOKENS
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
153 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
154 return "operator";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
155 } else if (isDoubleOperatorSym.hasOwnProperty(doubleOperator)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
156 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
157 if (stream.peek() === ' ')
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
158 return isDoubleOperatorSym[doubleOperator.toLowerCase()];
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
159 } else if (isSingleOperatorChar.test(ch)) { // SINGLE SYMBOL TOKENS
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
160 return "operator";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
161 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
162
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
163 // Matches one whole word -- even if the word is a character
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
164 var word;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
165 if (stream.match(/[%&;\w]+/, false) != null) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
166 word = ch + stream.match(/[%&;\w]+/, true);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
167 if (/&/.test(word)) return 'variable'
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
168 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
169 word = ch;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
170 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
171 // the word after DATA PROC or MACRO
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
172 if (state.nextword) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
173 stream.match(/[\w]+/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
174 // match memname.libname
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
175 if (stream.peek() === '.') stream.skipTo(' ');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
176 state.nextword = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
177 return 'variable-2';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
178 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
179
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
180 word = word.toLowerCase()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
181 // Are we in a DATA Step?
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
182 if (state.inDataStep) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
183 if (word === 'run;' || stream.match(/run\s;/)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
184 state.inDataStep = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
185 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
186 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
187 // variable formats
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
188 if ((word) && stream.next() === '.') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
189 //either a format or libname.memname
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
190 if (/\w/.test(stream.peek())) return 'variable-2';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
191 else return 'variable';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
192 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
193 // do we have a DATA Step keyword
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
194 if (word && words.hasOwnProperty(word) &&
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
195 (words[word].state.indexOf("inDataStep") !== -1 ||
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
196 words[word].state.indexOf("ALL") !== -1)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
197 //backup to the start of the word
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
198 if (stream.start < stream.pos)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
199 stream.backUp(stream.pos - stream.start);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
200 //advance the length of the word and return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
201 for (var i = 0; i < word.length; ++i) stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
202 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
203 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
204 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
205 // Are we in an Proc statement?
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
206 if (state.inProc) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
207 if (word === 'run;' || word === 'quit;') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
208 state.inProc = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
209 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
210 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
211 // do we have a proc keyword
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
212 if (word && words.hasOwnProperty(word) &&
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
213 (words[word].state.indexOf("inProc") !== -1 ||
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
214 words[word].state.indexOf("ALL") !== -1)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
215 stream.match(/[\w]+/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
216 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
217 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
218 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
219 // Are we in a Macro statement?
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
220 if (state.inMacro) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
221 if (word === '%mend') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
222 if (stream.peek() === ';') stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
223 state.inMacro = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
224 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
225 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
226 if (word && words.hasOwnProperty(word) &&
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
227 (words[word].state.indexOf("inMacro") !== -1 ||
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
228 words[word].state.indexOf("ALL") !== -1)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
229 stream.match(/[\w]+/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
230 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
231 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
232
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
233 return 'atom';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
234 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
235 // Do we have Keywords specific words?
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
236 if (word && words.hasOwnProperty(word)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
237 // Negates the initial next()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
238 stream.backUp(1);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
239 // Actually move the stream
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
240 stream.match(/[\w]+/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
241 if (word === 'data' && /=/.test(stream.peek()) === false) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
242 state.inDataStep = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
243 state.nextword = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
244 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
245 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
246 if (word === 'proc') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
247 state.inProc = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
248 state.nextword = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
249 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
250 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
251 if (word === '%macro') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
252 state.inMacro = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
253 state.nextword = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
254 return 'builtin';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
255 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
256 if (/title[1-9]/.test(word)) return 'def';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
257
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
258 if (word === 'footnote') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
259 stream.eat(/[1-9]/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
260 return 'def';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
261 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
262
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
263 // Returns their value as state in the prior define methods
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
264 if (state.inDataStep === true && words[word].state.indexOf("inDataStep") !== -1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
265 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
266 if (state.inProc === true && words[word].state.indexOf("inProc") !== -1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
267 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
268 if (state.inMacro === true && words[word].state.indexOf("inMacro") !== -1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
269 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
270 if (words[word].state.indexOf("ALL") !== -1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
271 return words[word].style;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
272 return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
273 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
274 // Unrecognized syntax
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
275 return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
276 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
277
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
278 return {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
279 startState: function () {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
280 return {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
281 inDataStep: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
282 inProc: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
283 inMacro: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
284 nextword: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
285 continueString: null,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
286 continueComment: false
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
287 };
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
288 },
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
289 token: function (stream, state) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
290 // Strip the spaces, but regex will account for them either way
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
291 if (stream.eatSpace()) return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
292 // Go through the main process
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
293 return tokenize(stream, state);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
294 },
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
295
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
296 blockCommentStart: "/*",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
297 blockCommentEnd: "*/"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
298 };
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
299
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
300 });
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
301
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
302 CodeMirror.defineMIME("text/x-sas", "sas");
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
303 });