mirror of
https://github.com/claudehohl/Stikked.git
synced 2025-04-25 04:21:17 -05:00
252 lines
6.6 KiB
JavaScript
252 lines
6.6 KiB
JavaScript
// erlang -> CodeMirror tag
|
|
//
|
|
// atom -> atom
|
|
// attribute -> attribute
|
|
// builtin -> builtin
|
|
// comment -> comment
|
|
// error -> error
|
|
// fun -> meta
|
|
// function -> tag
|
|
// guard -> property
|
|
// keyword -> keyword
|
|
// macro -> variable-2
|
|
// number -> number
|
|
// operator -> operator
|
|
// record -> bracket
|
|
// string -> string
|
|
// type -> def
|
|
// variable -> variable
|
|
|
|
CodeMirror.defineMIME("text/x-erlang", "erlang");
|
|
|
|
CodeMirror.defineMode("erlang", function(cmCfg, modeCfg) {
|
|
|
|
var typeWords = [
|
|
"-type", "-spec", "-export_type", "-opaque"];
|
|
|
|
var keywordWords = [
|
|
"after","begin","catch","case","cond","end","fun","if",
|
|
"let","of","query","receive","try","when"];
|
|
|
|
var operatorWords = [
|
|
"and","andalso","band","bnot","bor","bsl","bsr","bxor",
|
|
"div","not","or","orelse","rem","xor"];
|
|
|
|
var operatorSymbols = [
|
|
"+","-","*","/",">",">=","<","=<","=:=","==","=/=","/=","||","<-"];
|
|
|
|
var guardWords = [
|
|
"is_atom","is_binary","is_bitstring","is_boolean","is_float",
|
|
"is_function","is_integer","is_list","is_number","is_pid",
|
|
"is_port","is_record","is_reference","is_tuple",
|
|
"atom","binary","bitstring","boolean","function","integer","list",
|
|
"number","pid","port","record","reference","tuple"];
|
|
|
|
var bifWords = [
|
|
"abs","adler32","adler32_combine","alive","apply","atom_to_binary",
|
|
"atom_to_list","binary_to_atom","binary_to_existing_atom",
|
|
"binary_to_list","binary_to_term","bit_size","bitstring_to_list",
|
|
"byte_size","check_process_code","contact_binary","crc32",
|
|
"crc32_combine","date","decode_packet","delete_module",
|
|
"disconnect_node","element","erase","exit","float","float_to_list",
|
|
"garbage_collect","get","get_keys","group_leader","halt","hd",
|
|
"integer_to_list","internal_bif","iolist_size","iolist_to_binary",
|
|
"is_alive","is_atom","is_binary","is_bitstring","is_boolean",
|
|
"is_float","is_function","is_integer","is_list","is_number","is_pid",
|
|
"is_port","is_process_alive","is_record","is_reference","is_tuple",
|
|
"length","link","list_to_atom","list_to_binary","list_to_bitstring",
|
|
"list_to_existing_atom","list_to_float","list_to_integer",
|
|
"list_to_pid","list_to_tuple","load_module","make_ref","module_loaded",
|
|
"monitor_node","node","node_link","node_unlink","nodes","notalive",
|
|
"now","open_port","pid_to_list","port_close","port_command",
|
|
"port_connect","port_control","pre_loaded","process_flag",
|
|
"process_info","processes","purge_module","put","register",
|
|
"registered","round","self","setelement","size","spawn","spawn_link",
|
|
"spawn_monitor","spawn_opt","split_binary","statistics",
|
|
"term_to_binary","time","throw","tl","trunc","tuple_size",
|
|
"tuple_to_list","unlink","unregister","whereis"];
|
|
|
|
function isMember(element,list) {
|
|
return (-1 < list.indexOf(element));
|
|
}
|
|
|
|
function isPrev(stream,string) {
|
|
var start = stream.start;
|
|
var len = string.length;
|
|
if (len <= start) {
|
|
var word = stream.string.slice(start-len,start);
|
|
return word == string;
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var smallRE = /[a-z_]/;
|
|
var largeRE = /[A-Z_]/;
|
|
var digitRE = /[0-9]/;
|
|
var octitRE = /[0-7]/;
|
|
var idRE = /[a-z_A-Z0-9]/;
|
|
|
|
function tokenize(stream, state) {
|
|
if (stream.eatSpace()) {
|
|
return null;
|
|
}
|
|
|
|
// attributes and type specs
|
|
if (stream.sol() && stream.peek() == '-') {
|
|
stream.next();
|
|
if (stream.eat(smallRE) && stream.eatWhile(idRE)) {
|
|
if (stream.peek() == "(") {
|
|
return "attribute";
|
|
}else if (isMember(stream.current(),typeWords)) {
|
|
return "def";
|
|
}else{
|
|
return null;
|
|
}
|
|
}
|
|
stream.backUp(1);
|
|
}
|
|
|
|
var ch = stream.next();
|
|
|
|
// comment
|
|
if (ch == '%') {
|
|
stream.skipToEnd();
|
|
return "comment";
|
|
}
|
|
|
|
// macro
|
|
if (ch == '?') {
|
|
stream.eatWhile(idRE);
|
|
return "variable-2";
|
|
}
|
|
|
|
// record
|
|
if ( ch == "#") {
|
|
stream.eatWhile(idRE);
|
|
return "bracket";
|
|
}
|
|
|
|
// char
|
|
if ( ch == "$") {
|
|
if (stream.next() == "\\") {
|
|
if (!stream.eatWhile(octitRE)) {
|
|
stream.next();
|
|
}
|
|
}
|
|
return "string";
|
|
}
|
|
|
|
// quoted atom
|
|
if (ch == '\'') {
|
|
return singleQuote(stream);
|
|
}
|
|
|
|
// string
|
|
if (ch == '"') {
|
|
return doubleQuote(stream);
|
|
}
|
|
|
|
// variable
|
|
if (largeRE.test(ch)) {
|
|
stream.eatWhile(idRE);
|
|
return "variable";
|
|
}
|
|
|
|
// atom/keyword/BIF/function
|
|
if (smallRE.test(ch)) {
|
|
stream.eatWhile(idRE);
|
|
|
|
if (stream.peek() == "/") {
|
|
stream.next();
|
|
if (stream.eatWhile(digitRE)) {
|
|
return "meta"; // f/0 style fun
|
|
}else{
|
|
stream.backUp(1);
|
|
return "atom";
|
|
}
|
|
}
|
|
|
|
var w = stream.current();
|
|
|
|
if (isMember(w,keywordWords)) {
|
|
return "keyword"; // keyword
|
|
}
|
|
if (stream.peek() == "(") {
|
|
if (isMember(w,bifWords) &&
|
|
(!isPrev(stream,":") || isPrev(stream,"erlang:"))) {
|
|
return "builtin"; // BIF
|
|
}else{
|
|
return "tag"; // function
|
|
}
|
|
}
|
|
if (isMember(w,guardWords)) {
|
|
return "property"; // guard
|
|
}
|
|
if (isMember(w,operatorWords)) {
|
|
return "operator"; // operator
|
|
}
|
|
|
|
|
|
if (stream.peek() == ":") {
|
|
if (w == "erlang") { // f:now() is highlighted incorrectly
|
|
return "builtin";
|
|
} else {
|
|
return "tag"; // function application
|
|
}
|
|
}
|
|
|
|
return "atom";
|
|
}
|
|
|
|
// number
|
|
if (digitRE.test(ch)) {
|
|
stream.eatWhile(digitRE);
|
|
if (stream.eat('#')) {
|
|
stream.eatWhile(digitRE); // 16#10 style integer
|
|
} else {
|
|
if (stream.eat('.')) { // float
|
|
stream.eatWhile(digitRE);
|
|
}
|
|
if (stream.eat(/[eE]/)) {
|
|
stream.eat(/[-+]/); // float with exponent
|
|
stream.eatWhile(digitRE);
|
|
}
|
|
}
|
|
return "number"; // normal integer
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function doubleQuote(stream) {
|
|
return Quote(stream, '"', '\\', "string");
|
|
}
|
|
|
|
function singleQuote(stream) {
|
|
return Quote(stream,'\'','\\',"atom");
|
|
}
|
|
|
|
function Quote(stream,quoteChar,escapeChar,tag) {
|
|
while (!stream.eol()) {
|
|
var ch = stream.next();
|
|
if (ch == quoteChar) {
|
|
return tag;
|
|
}else if (ch == escapeChar) {
|
|
stream.next();
|
|
}
|
|
}
|
|
return "error";
|
|
}
|
|
|
|
return {
|
|
startState: function() {
|
|
return {};
|
|
},
|
|
|
|
token: function(stream, state) {
|
|
return tokenize(stream, state);
|
|
}
|
|
};
|
|
});
|