[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs Makefile txl.c nim.c rebol.c elm.c jai.c...
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs Makefile txl.c nim.c rebol.c elm.c jai.c... |
Date: |
Fri, 2 Oct 2020 17:32:30 -0400 (EDT) |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 20/10/02 17:32:30
Modified files:
. : Makefile
Added files:
. : txl.c nim.c rebol.c elm.c jai.c ats.c
Log message:
add colorizers for txl, nim, rebol, elm, jai, ats
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/Makefile?cvsroot=qemacs&r1=1.107&r2=1.108
http://cvs.savannah.gnu.org/viewcvs/qemacs/txl.c?cvsroot=qemacs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qemacs/nim.c?cvsroot=qemacs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qemacs/rebol.c?cvsroot=qemacs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qemacs/elm.c?cvsroot=qemacs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qemacs/jai.c?cvsroot=qemacs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qemacs/ats.c?cvsroot=qemacs&rev=1.1
Patches:
Index: Makefile
===================================================================
RCS file: /sources/qemacs/qemacs/Makefile,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -b -r1.107 -r1.108
--- Makefile 27 Mar 2019 07:41:54 -0000 1.107
+++ Makefile 2 Oct 2020 21:32:29 -0000 1.108
@@ -39,6 +39,12 @@
#include local compiler configuration file
-include $(DEPTH)/cflags.mk
+ifdef CONFIG_DARWIN
+ CFLAGS += -Wno-string-plus-int
+else
+ CFLAGS += -Wno-unused-result
+endif
+
ifdef TARGET_GPROF
CFLAGS += -p
LDFLAGS += -p
@@ -125,7 +131,8 @@
ifdef CONFIG_ALL_MODES
OBJS+= unihex.o bufed.o clang.o xml.o htmlsrc.o forth.o arm.o \
lisp.o makemode.o markdown.o orgmode.o perl.o script.o \
- ebnf.o cobol.o rlang.o $(EXTRA_MODES) extra-modes.o
+ ebnf.o cobol.o rlang.o txl.o nim.o rebol.o elm.o jai.o ats.o \
+ $(EXTRA_MODES) extra-modes.o
ifndef CONFIG_WIN32
OBJS+= shell.o dired.o latex-mode.o archive.o
endif
Index: txl.c
===================================================================
RCS file: txl.c
diff -N txl.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ txl.c 2 Oct 2020 21:32:29 -0000 1.1
@@ -0,0 +1,166 @@
+/*
+ * TXL language mode for QEmacs.
+ *
+ * Copyright (c) 2015-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+/*---------------- TXL coloring ----------------*/
+
+#define MAX_KEYWORD_SIZE 16
+
+static char const txl_keywords[] = {
+ "|all|assert|attr|by|comments|compounds|construct|deconstruct"
+ "|define|each|end|export|external|function|import|include"
+ "|keys|list|match|not|opt|push|pop|redefine|repeat|replace"
+ "|rule|see|skipping|tokens|where"
+};
+
+static char const txl_types[] = {
+ "|"
+};
+
+enum {
+ TXL_STYLE_TEXT = QE_STYLE_DEFAULT,
+ TXL_STYLE_COMMENT = QE_STYLE_COMMENT,
+ TXL_STYLE_STRING = QE_STYLE_STRING,
+ TXL_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ TXL_STYLE_SYMBOL = QE_STYLE_NUMBER,
+ TXL_STYLE_TYPE = QE_STYLE_TYPE,
+ TXL_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
+ TXL_STYLE_IDENTIFIER = QE_STYLE_VARIABLE,
+};
+
+enum {
+ IN_TXL_COMMENT1 = 0x01,
+ IN_TXL_COMMENT2 = 0x02,
+};
+
+static void txl_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ char keyword[MAX_KEYWORD_SIZE];
+ int i = 0, start = 0, c, style, klen;
+ int colstate = cp->colorize_state;
+
+ if (colstate & IN_TXL_COMMENT1)
+ goto in_comment1;
+
+ if (colstate & IN_TXL_COMMENT2)
+ goto in_comment2;
+
+ style = 0;
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '%':
+ if (str[i] == '(') {
+ colstate = IN_TXL_COMMENT1;
+ i++;
+ in_comment1:
+ while (i < n) {
+ if (str[i++] == ')' && str[i] == '%') {
+ colstate = 0;
+ break;
+ }
+ }
+ } else
+ if (str[i] == '{') {
+ colstate = IN_TXL_COMMENT2;
+ i++;
+ in_comment2:
+ while (i < n) {
+ if (str[i++] == '}' && str[i] == '%') {
+ colstate = 0;
+ break;
+ }
+ }
+ } else {
+ i = n;
+ }
+ style = TXL_STYLE_COMMENT;
+ break;
+ case '\'':
+ /* parse quoted token */
+ for (; i < n && !qe_isblank(str[i]); i++)
+ continue;
+ style = TXL_STYLE_SYMBOL;
+ break;
+ default:
+ /* parse numbers */
+ if (qe_isdigit(c)) {
+ for (; i < n; i++) {
+ if (!qe_isalnum(str[i]) && str[i] != '.')
+ break;
+ }
+ style = TXL_STYLE_IDENTIFIER;
+ break;
+ }
+ /* parse identifiers and keywords */
+ if (qe_isalpha_(c)) {
+ klen = 0;
+ keyword[klen++] = qe_tolower(c);
+ for (; i < n; i++) {
+ if (qe_isalnum_(str[i])) {
+ if (klen < countof(keyword) - 1)
+ keyword[klen++] = qe_tolower(str[i]);
+ } else {
+ if (qe_findchar("$&!@%#", str[i]))
+ i++;
+ break;
+ }
+ }
+ keyword[klen] = '\0';
+ if (strfind(syn->keywords, keyword)) {
+ style = TXL_STYLE_KEYWORD;
+ break;
+ }
+ if (strfind(syn->types, keyword)) {
+ style = TXL_STYLE_TYPE;
+ break;
+ }
+ style = TXL_STYLE_IDENTIFIER;
+ break;
+ }
+ continue;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = 0;
+ }
+ }
+ cp->colorize_state = colstate;
+}
+
+static ModeDef txl_mode = {
+ .name = "Txl",
+ .extensions = "txl",
+ .keywords = txl_keywords,
+ .types = txl_types,
+ .colorize_func = txl_colorize_line,
+};
+
+static int txl_init(void)
+{
+ qe_register_mode(&txl_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(txl_init);
Index: nim.c
===================================================================
RCS file: nim.c
diff -N nim.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ nim.c 2 Oct 2020 21:32:30 -0000 1.1
@@ -0,0 +1,334 @@
+/*
+ * Nim mode for QEmacs.
+ *
+ * Copyright (c) 2015-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+#define MAX_KEYWORD_SIZE 16
+
+/*---------------- Nim coloring ----------------*/
+
+static char const nim_keywords[] = {
+ /* Nim keywords */
+ "addr|and|as|asm|atomic|bind|block|break|case|cast|concept|const|"
+ "continue|converter|defer|discard|distinct|div|do|elif|else|end|"
+ "enum|except|export|finally|for|from|func|generic|if|import|in|include|"
+ "interface|is|isnot|iterator|let|macro|method|mixin|mod|nil|not|notin|"
+ "object|of|or|out|proc|ptr|raise|ref|return|shl|shr|static|template|"
+ "try|tuple|type|using|var|when|while|with|without|xor|yield|"
+ /* predefined operators */
+ "inc|dec|"
+ /* predefined constants */
+ "true|false|"
+};
+
+static char const nim_types[] = {
+ "int|uint|cint|cuint|clong|cstring|string|char|byte|bool|"
+ "openArray|seq|array|void|pointer|float|csize|cdouble|"
+ "cchar|cschar|cshort|cu|nil|expr|stmt|typedesc|auto|any|"
+ "range|openarray|varargs|set|cfloat|"
+ "int8|int16|int32|int64|uint8|uint16|uint32|uint64|"
+};
+
+enum {
+ NIM_STYLE_TEXT = QE_STYLE_DEFAULT,
+ NIM_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
+ NIM_STYLE_COMMENT = QE_STYLE_COMMENT,
+ NIM_STYLE_STRING = QE_STYLE_STRING,
+ NIM_STYLE_NUMBER = QE_STYLE_NUMBER,
+ NIM_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ NIM_STYLE_TYPE = QE_STYLE_TYPE,
+ NIM_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+ NIM_STYLE_PRAGMA = QE_STYLE_PREPROCESS,
+};
+
+/* nim-mode colorization states */
+enum {
+ IN_NIM_COMMENT = 0x80,
+ IN_NIM_CHARLIT = 0x40,
+ IN_NIM_STRING = 0x20,
+ IN_NIM_LONG_STRING = 0x10,
+ IN_NIM_RAW_STRING = 0x08,
+ IN_NIM_STRING_BQ = 0x04,
+ IN_NIM_PRAGMA = 0x02,
+};
+
+static void nim_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ int i = 0, start = i, style = 0, c, sep = 0, klen;
+ int state = cp->colorize_state;
+ char kbuf[64];
+
+ if (state & IN_NIM_COMMENT) {
+ goto parse_comment;
+ }
+ if (state & IN_NIM_CHARLIT) {
+ sep = '\'';
+ goto parse_string;
+ }
+ if (state & IN_NIM_STRING) {
+ sep = '\"';
+ goto parse_string;
+ }
+ if (state & IN_NIM_LONG_STRING) {
+ sep = '\"';
+ goto parse_long_string;
+ }
+ if (state & IN_NIM_STRING_BQ) {
+ sep = '`';
+ goto parse_string;
+ }
+
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '#':
+ if (start == 0 && str[i] == '!') {
+ i = n;
+ style = NIM_STYLE_PREPROCESS;
+ break;
+ }
+
+ parse_comment:
+ state &= ~IN_NIM_COMMENT;
+ /* XXX: should handle trailing backslash more generically */
+ for (; i < n; i++) {
+ if (str[i] == '\\')
+ state |= IN_NIM_COMMENT;
+ else
+ if (!qe_isblank(str[i]))
+ state &= ~IN_NIM_COMMENT;
+ }
+ style = NIM_STYLE_COMMENT;
+ break;
+#if 0
+ case 'r':
+ case 'R':
+ if (str[i] == '\"') {
+ state |= IN_NIM_RAW_STRING;
+ goto has_quote;
+ }
+ goto has_alpha;
+#endif
+ case '`':
+ sep = c;
+ style = IN_NIM_STRING_BQ;
+ goto parse_string;
+
+ case '\'':
+ sep = c;
+ style = IN_NIM_CHARLIT;
+ goto parse_string;
+
+ case '\"':
+ /* parse string const */
+ i--;
+ has_quote:
+ sep = str[i++];
+ if (str[i] == (unsigned int)sep && str[i + 1] == (unsigned
int)sep) {
+ /* long string */
+ state |= IN_NIM_LONG_STRING | IN_NIM_RAW_STRING;
+ i += 2;
+ parse_long_string:
+ while (i < n) {
+ c = str[i++];
+ if (!(state & IN_NIM_RAW_STRING) && c == '\\') {
+ if (i < n) {
+ i += 1;
+ }
+ } else
+ if (c == sep && str[i] == (unsigned int)sep
+ && str[i + 1] == (unsigned int)sep && str[i + 2] !=
(unsigned int)sep) {
+ i += 2;
+ state &= ~(IN_NIM_LONG_STRING | IN_NIM_RAW_STRING);
+ break;
+ }
+ }
+ } else {
+ state = IN_NIM_STRING;
+ parse_string:
+ while (i < n) {
+ c = str[i++];
+ if (!(state & IN_NIM_RAW_STRING) && c == '\\') {
+ if (i < n) {
+ i += 1;
+ }
+ continue;
+ }
+ if (c == sep) {
+ if ((state & IN_NIM_RAW_STRING) && str[i] == '"') {
+ i += 1;
+ continue;
+ }
+ state &= ~(IN_NIM_STRING | IN_NIM_RAW_STRING);
+ break;
+ }
+ }
+ }
+ style = NIM_STYLE_STRING;
+ break;
+
+ case '.':
+ if (str[i] == '}') {
+ i += 1;
+ state &= ~IN_NIM_PRAGMA;
+ style = NIM_STYLE_PRAGMA;
+ break;
+ }
+ continue;
+
+ break;
+
+ // Handle ( ) { } [ ] (. .) {. .} [. .] : :: .. `
+
+ case '{':
+ if (str[i] == '.' && str[i + 1] != '.') {
+ /* Nim pragmas */
+ for (i++;; i++) {
+ if (qe_isalnum_(str[i]))
+ continue;
+ if (str[i] == '.' && str[i + 1] != '}')
+ continue;
+ break;
+ }
+ state |= IN_NIM_PRAGMA;
+ style = NIM_STYLE_PRAGMA;
+ break;
+ }
+ continue;
+
+ default:
+ if (qe_isdigit(c)) {
+ int j, k;
+ static const char * const suffixes[] = {
+ "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64",
+ "f32", "f64", "f128",
+ };
+
+ if (c == '0' && qe_match2(str[i], 'b', 'B')) {
+ /* binary numbers */
+ for (i += 1; qe_isbindigit_(str[i]); i++)
+ continue;
+ } else
+ if (c == '0' && (str[i] == 'o' || qe_match2(str[i], 'c',
'C'))) {
+ /* octal numbers */
+ for (i += 1; qe_isoctdigit_(str[i]); i++)
+ continue;
+ } else
+ if (c == '0' && qe_match2(str[i], 'x', 'X')) {
+ /* hexadecimal numbers */
+ for (i += 1; qe_isxdigit_(str[i]); i++)
+ continue;
+ } else {
+ /* decimal numbers */
+ for (; qe_isdigit_(str[i]); i++)
+ continue;
+ if (str[i] == '.' && qe_isdigit_(str[i + 1])) {
+ i++;
+ /* decimal floats require a digit after the '.' */
+ for (; qe_isdigit_(str[i]); i++)
+ continue;
+ }
+ if (qe_match2(str[i], 'e', 'E')) {
+ int k = i + 1;
+ if (qe_match2(str[i], '+', '-'))
+ k++;
+ if (qe_isdigit(str[k])) {
+ for (i = k + 1; qe_isdigit_(str[i]); i++)
+ continue;
+ }
+ }
+ }
+ /* handle optional ' and type suffix */
+ j = i;
+ if (str[j] == '\'')
+ j++;
+ if (qe_isalpha(str[j])) {
+ for (k = 0; k < countof(suffixes); k++) {
+ if (ustrstart(str + j, suffixes[k], &klen)
+ && !qe_isalnum_(str[j + klen])) {
+ i = j + klen;
+ break;
+ }
+ }
+ }
+ /* XXX: should detect malformed number constants */
+ style = NIM_STYLE_NUMBER;
+ break;
+ }
+ //has_alpha:
+ if (qe_isalpha_(c)) {
+ i += ustr_get_identifier(kbuf, countof(kbuf), c, str, i, n);
+ if (str[i] == '"') {
+ /* generalized raw string literal */
+ state |= IN_NIM_RAW_STRING;
+ goto has_quote;
+ }
+
+ if (strfind(syn->keywords, kbuf)) {
+ style = NIM_STYLE_KEYWORD;
+ break;
+ }
+ if ((start == 0 || str[start - 1] != '.')
+ && (str[i] != '.')) {
+ if (strfind(syn->types, kbuf)) {
+ //|| (qe_isupper(c) && haslower)
+ style = NIM_STYLE_TYPE;
+ break;
+ }
+ }
+ if (check_fcall(str, i)) {
+ style = NIM_STYLE_FUNCTION;
+ break;
+ }
+ continue;
+ }
+ continue;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = 0;
+ }
+ }
+ // XXX: should handle line continuation with trailing \\ followed
+ // by white space
+ SET_COLOR1(str, n, style); /* set style on eol char */
+
+ cp->colorize_state = state;
+}
+
+static ModeDef nim_mode = {
+ .name = "Nim",
+ .extensions = "nim",
+ .shell_handlers = "nim",
+ .keywords = nim_keywords,
+ .types = nim_types,
+ .colorize_func = nim_colorize_line,
+};
+
+static int nim_init(void)
+{
+ qe_register_mode(&nim_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(nim_init);
Index: rebol.c
===================================================================
RCS file: rebol.c
diff -N rebol.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ rebol.c 2 Oct 2020 21:32:30 -0000 1.1
@@ -0,0 +1,309 @@
+/*
+ * REBOL language mode for QEmacs.
+ *
+ * Copyright (c) 2015-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+/*---------------- REBOL coloring ----------------*/
+
+static char const rebol_keywords[] = {
+ /* Constants */
+ "none|true|false|on|off|yes|no|newline|tab|cr|lf|null|pi|"
+ /* Evalute */
+ "do|reduce|compose|"
+ /* Branch */
+ "if|either|all|any|case|switch|"
+ /* Loop */
+ "loop|repeat|foreach|while|remove-each|break|"
+ /* Function */
+ "function|funct|func|has|does|exit|return|"
+ /* Error */
+ "attempt|try|catch|throw|"
+ /* Help */
+ "help|what|docs|source|trace|probe|??|delta-time|"
+ /* Compare */
+ "<|>|<=|>=|=|==|<>|!=|!==|=?|same?|"
+ /* Math */
+ "+|-|*|/|**|remainder|negate|abs|absolute|round|min|max|"
+ "and|or|xor|not|random|shift|sine|log-e|to|"
+ /* Reflection */
+ "words-of|values-of|title-of|spec-of|body-of|"
+ /* Series */
+ "find|select|first|last|pick|length?|index?|next|back|skip|"
+ "make|copy|join|ajoin|rejoin|append|repend|insert|remove|"
+ "take|clear|change|replace|trim|split|sort|swap|"
+ /* Sets */
+ "unique|union|intersect|difference|exclude|"
+ /* Console */
+ "print|probe|input|ask|confirm|halt|quit|"
+ /* Output */
+ "mold|form|to|"
+ /* Files/Ports */
+ "read|write|load|save|open|close|delete|exists?|size?|"
+ "modified?|suffix?|dir?|split-path|dirize|to-local-file|"
+ /* Context */
+ "object|module|import|construct|bind|get|set|in|value?|use|"
+ /* Other */
+ "now|parse|secure|wait|browse|compress|decompress|"
+ "lowercase|uppercase|entab|detab|"
+ /* GUI/Graphics */
+ "view|unview|layout|alert|request|request-file|draw|show|"
+ "get-face|set-face|focus|"
+ //"then|forall|rebol|end|native|self|some|"
+};
+
+static char const rebol_types[] = {
+ "|"
+};
+
+enum {
+ REBOL_STYLE_TEXT = QE_STYLE_DEFAULT,
+ REBOL_STYLE_COMMENT = QE_STYLE_COMMENT,
+ REBOL_STYLE_STRING = QE_STYLE_STRING,
+ REBOL_STYLE_NUMBER = QE_STYLE_NUMBER,
+ REBOL_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ REBOL_STYLE_TYPE = QE_STYLE_TYPE,
+ REBOL_STYLE_BINARY = QE_STYLE_PREPROCESS,
+ REBOL_STYLE_DEFINITION = QE_STYLE_FUNCTION,
+ REBOL_STYLE_ERROR = QE_STYLE_ERROR,
+};
+
+enum {
+ IN_REBOL_STRING1 = 0x0F, /* allow embedded balanced { } */
+ IN_REBOL_STRING2 = 0x10,
+ IN_REBOL_BINARY = 0x20,
+ IN_REBOL_COMMENT = 0x40,
+};
+
+static void rebol_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ char keyword[64];
+ int i = 0, start = 0, c, style, style0 = 0, k, klen, level;
+ int colstate = cp->colorize_state;
+
+ level = colstate & IN_REBOL_STRING1;
+ if (level)
+ goto in_string1;
+
+ if (colstate & IN_REBOL_STRING2)
+ goto in_string2;
+
+ if (colstate & IN_REBOL_BINARY)
+ goto in_binary;
+
+ if (colstate & IN_REBOL_COMMENT)
+ style0 = REBOL_STYLE_COMMENT;
+
+ style = style0;
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case ';':
+ i = n;
+ style = REBOL_STYLE_COMMENT;
+ break;
+
+ case '{':
+ level++;
+ in_string1:
+ while (i < n) {
+ switch (str[i++]) {
+ case '^':
+ if (i < n)
+ i++;
+ continue;
+ case '{':
+ level++;
+ continue;
+ case '}':
+ --level;
+ if (!level)
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ colstate &= ~IN_REBOL_STRING1;
+ colstate |= level & IN_REBOL_STRING1;
+ style = REBOL_STYLE_STRING;
+ break;
+
+ case '"':
+ in_string2:
+ colstate |= IN_REBOL_STRING2;
+ while (i < n) {
+ c = str[i++];
+ if (c == '^' && i < n)
+ i++;
+ else
+ if (c == '"') {
+ colstate &= ~IN_REBOL_STRING2;
+ break;
+ }
+ }
+ if (colstate & IN_REBOL_STRING2) {
+ /* double quoted strings do not span lines */
+ colstate &= ~IN_REBOL_STRING2;
+ style = REBOL_STYLE_ERROR;
+ break;
+ }
+ style = REBOL_STYLE_STRING;
+ break;
+
+ case '[': /* start block */
+ break;
+ case ']': /* end block */
+ colstate &= ~IN_REBOL_COMMENT;
+ break;
+ case '(':
+ case ')':
+ break;
+
+ case '<':
+ /* XXX: should skip tag with embedded strings */
+ goto normal;
+
+ case '#':
+ if (str[i] == '"') {
+ /* character constant */
+ break; /* keep # in default color */
+ }
+ if (str[i] == '{') {
+ in_binary:
+ colstate |= IN_REBOL_BINARY;
+ while (i < n) {
+ if (str[i++] == '}') {
+ colstate &= ~IN_REBOL_BINARY;
+ break;
+ }
+ }
+ style = REBOL_STYLE_BINARY;
+ break;
+ }
+ goto normal;
+
+ case '6': /* 64#{ base64 encoded data } */
+ if (str[i] == '4' && str[i + 1] == '#' && str[i + 2] == '{')
+ goto in_binary;
+ goto normal;
+ case '1': /* 16#{ hex encoded data } */
+ if (str[i] == '6' && str[i + 1] == '#' && str[i + 2] == '{')
+ goto in_binary;
+ goto normal;
+ case '2': /* 2#{ binary encoded data } */
+ if (str[i] == '#' && str[i + 1] == '{')
+ goto in_binary;
+ goto normal;
+
+ default:
+ normal:
+ if (c <= ' ')
+ break;
+
+ /* parse words */
+ klen = 0;
+ keyword[klen++] = qe_tolower(c);
+ for (; i < n; i++) {
+ if (qe_findchar(" \t;()[]\"", str[i]))
+ break;
+ if (klen < countof(keyword) - 1)
+ keyword[klen++] = qe_tolower(str[i]);
+ }
+ keyword[klen] = '\0';
+ if (qe_isdigit(c) || c == '+' || c == '-') {
+ /* check numbers */
+ int dots = 0;
+ for (k = 1; k < klen; k++) {
+ if (qe_match2(keyword[k], '.', ',')) {
+ dots++;
+ } else
+ if (keyword[k] == 'e') {
+ if (qe_match2(keyword[k + 1], '+', '-'))
+ k++;
+ } else
+ if (!qe_match2(keyword[k], '\'', '%')
+ && !qe_isdigit(keyword[k]))
+ break;
+ }
+ if (k == klen && dots <= 1) {
+ style = REBOL_STYLE_NUMBER;
+ break;
+ }
+ }
+ if (qe_isalpha_(c)) {
+ /* check identifiers and keywords */
+ if (strequal(keyword, "comment")) {
+ colstate |= IN_REBOL_COMMENT;
+ style = style0 = REBOL_STYLE_COMMENT;
+ break;
+ }
+ if (strfind(syn->keywords, keyword)) {
+ style = REBOL_STYLE_KEYWORD;
+ break;
+ }
+ if (strfind(syn->types, keyword)) {
+ style = REBOL_STYLE_TYPE;
+ break;
+ }
+ }
+ if (klen > 1 && str[i - 1] == ':') {
+ i--;
+ style = REBOL_STYLE_DEFINITION;
+ break;
+ }
+ break;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = style0;
+ }
+ }
+ cp->colorize_state = colstate;
+}
+
+static int rebol_mode_probe(ModeDef *mode, ModeProbeData *p)
+{
+ /* trust the file extension and/or shell handler */
+ if (match_extension(p->filename, mode->extensions)
+ && !qe_memicmp(cs8(p->buf), "REBOL", 5)) {
+ return 81;
+ }
+ return 1;
+}
+
+static ModeDef rebol_mode = {
+ .name = "Rebol",
+ .extensions = "r",
+ .mode_probe = rebol_mode_probe,
+ .keywords = rebol_keywords,
+ .types = rebol_types,
+ .colorize_func = rebol_colorize_line,
+};
+
+static int rebol_init(void)
+{
+ qe_register_mode(&rebol_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(rebol_init);
Index: elm.c
===================================================================
RCS file: elm.c
diff -N elm.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ elm.c 2 Oct 2020 21:32:30 -0000 1.1
@@ -0,0 +1,267 @@
+/*
+ * Elm mode for QEmacs.
+ *
+ * Copyright (c) 2015-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+/*---------------- Elm coloring ----------------*/
+
+static char const elm_keywords[] = {
+ /* Elm keywords */
+ "if|then|else|case|of|let|in|type|"
+ "module|where|import|as|hiding|exposing|port|export|foreign|"
+ "perform|deriving|var|"
+ /* operators */
+ "not|"
+ /* predefined constants */
+ "False|True|_|"
+};
+
+static char const elm_types[] = {
+ "number|"
+ //"Bool|Char|String|Int|Float|" // matched generically
+};
+
+enum {
+ ELM_STYLE_DEFAULT = 0,
+ ELM_STYLE_COMMENT = QE_STYLE_COMMENT,
+ ELM_STYLE_PP_COMMENT = QE_STYLE_PREPROCESS,
+ ELM_STYLE_STRING = QE_STYLE_STRING,
+ ELM_STYLE_STRING_Q = QE_STYLE_STRING_Q,
+ ELM_STYLE_NUMBER = QE_STYLE_NUMBER,
+ ELM_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ ELM_STYLE_TYPE = QE_STYLE_TYPE,
+ ELM_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+};
+
+/* elm-mode colorization states */
+enum {
+ IN_ELM_COMMENT = 0x0F, /* multiline comment (nested) */
+ IN_ELM_COMMENT_SHIFT = 0,
+ IN_ELM_PP_COMMENT = 0x10, /* compiler directives {-# ... #-} */
+ IN_ELM_STRING = 0x20, /* double-quoted string */
+ IN_ELM_LONG_STRING = 0x40, /* double-quoted multiline string */
+ IN_ELM_STRING_Q = 0x80, /* single-quoted string */
+};
+
+static void elm_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ int i = 0, start = i, style = 0, c = 0, delim, level, klen;
+ int state = cp->colorize_state;
+ char kbuf[64];
+
+ if (state) {
+ /* if already in a state, go directly in the code parsing it */
+ if (state & IN_ELM_COMMENT)
+ goto parse_comment;
+ if (state & IN_ELM_STRING)
+ goto parse_string;
+ if (state & IN_ELM_LONG_STRING)
+ goto parse_long_string;
+ if (state & IN_ELM_STRING_Q)
+ goto parse_string_q;
+ }
+
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '-':
+ if (str[i] == '-') {
+ /* line comment */
+ i = n;
+ style = ELM_STYLE_COMMENT;
+ break;
+ }
+ continue;
+
+ case '{':
+ if (str[i] == '-') {
+ /* multi-line nested (!) comment */
+ state |= 1 << IN_ELM_COMMENT_SHIFT;
+ i++;
+ if (str[i] == '#') {
+ state |= IN_ELM_PP_COMMENT;
+ i++;
+ }
+ parse_comment:
+ level = (state & IN_ELM_COMMENT) >> IN_ELM_COMMENT_SHIFT;
+ style = ELM_STYLE_COMMENT;
+ if (state & IN_ELM_PP_COMMENT)
+ style = ELM_STYLE_PP_COMMENT;
+ while (i < n) {
+ c = str[i++];
+ if (c == '{' && str[i] == '-') {
+ level++;
+ i++;
+ continue;
+ }
+ if (c == '-' && str[i] == '}') {
+ i++;
+ level--;
+ if (level == 0) {
+ state &= ~IN_ELM_PP_COMMENT;
+ i++;
+ break;
+ }
+ }
+ }
+ state &= ~IN_ELM_COMMENT;
+ state |= level << IN_ELM_COMMENT_SHIFT;
+ break;
+ }
+ continue;
+
+ case '\'': /* character constant */
+ parse_string_q:
+ state |= IN_ELM_STRING_Q;
+ style = ELM_STYLE_STRING_Q;
+ delim = '\'';
+ goto string;
+
+ case '\"': /* string literal */
+ state |= IN_ELM_STRING;
+ if (str[i] == '"' && str[i + 1] == '"') {
+ state ^= IN_ELM_STRING | IN_ELM_LONG_STRING;
+ parse_long_string:
+ style = ELM_STYLE_STRING;
+ while (i < n) {
+ c = str[i++];
+ if (c == '\\') {
+ if (i >= n)
+ break;
+ i++;
+ } else
+ if (c == '"' && str[i] == '"' && str[i + 1] == '"') {
+ state &= ~IN_ELM_LONG_STRING;
+ break;
+ }
+ }
+ break;
+ }
+ parse_string:
+ style = ELM_STYLE_STRING;
+ delim = '\"';
+ string:
+ while (i < n) {
+ c = str[i++];
+ if (c == '\\') {
+ if (i >= n)
+ break;
+ i++;
+ } else
+ if (c == delim) {
+ state &= ~(IN_ELM_STRING | IN_ELM_STRING_Q);
+ break;
+ }
+ }
+ break;
+
+ default:
+ if (qe_isdigit(c)) {
+ int j;
+ // Integers:
+ // 0x[0-9a-fA-F]+
+ // [0-9]+
+ // Floats:
+ // [0-9]+\.[0-9]*([eE][-\+]?[0-9]+)?
+ // [0-9]+(\.[0-9]*)?[eE][-\+]?[0-9]+
+ if (c == '0' && str[i] == 'x' && qe_isxdigit(str[i + 1])) {
+ for (i += 3; qe_isxdigit(str[i]); i++)
+ continue;
+ } else {
+ while (qe_isdigit(str[i]))
+ i++;
+ if (str[i] == '.' && qe_isdigit(str[i + 1])) {
+ for (i += 2; qe_isdigit(str[i]); i++)
+ continue;
+ }
+ if (str[i] == 'e' || str[i] == 'E') {
+ j = i + 1;
+ if (str[j] == '+' || str[j] == '-')
+ j++;
+ if (qe_isdigit(str[j])) {
+ for (i = j + 1; qe_isdigit(str[i]); i++)
+ continue;
+ }
+ }
+ }
+ style = ELM_STYLE_NUMBER;
+ break;
+ }
+ if (qe_isalpha_(c)) {
+ int haslower = 0;
+ for (klen = 0, i--; qe_isalnum_(str[i]) || str[i] == '\'';
i++) {
+ haslower |= qe_islower(str[i]);
+ if (klen < countof(kbuf) - 1)
+ kbuf[klen++] = str[i];
+ }
+ kbuf[klen] = '\0';
+
+ if (strfind(syn->keywords, kbuf)) {
+ style = ELM_STYLE_KEYWORD;
+ break;
+ }
+
+ if ((start == 0 || str[start - 1] != '.')
+ && (str[i] != '.')) {
+ if (strfind(syn->types, kbuf)
+ || (qe_isupper(c) && haslower)) {
+ style = ELM_STYLE_TYPE;
+ break;
+ }
+ }
+#if 0
+ if (check_fcall(str, i)) {
+ style = ELM_STYLE_FUNCTION;
+ break;
+ }
+#endif
+ continue;
+ }
+ continue;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = 0;
+ }
+ }
+ /* set style on eol char */
+ SET_COLOR1(str, n, style); /* set style on eol char */
+
+ cp->colorize_state = state;
+}
+
+static ModeDef elm_mode = {
+ .name = "Elm",
+ .extensions = "elm",
+ .keywords = elm_keywords,
+ .types = elm_types,
+ .colorize_func = elm_colorize_line,
+};
+
+static int elm_init(void)
+{
+ qe_register_mode(&elm_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(elm_init);
Index: jai.c
===================================================================
RCS file: jai.c
diff -N jai.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ jai.c 2 Oct 2020 21:32:30 -0000 1.1
@@ -0,0 +1,247 @@
+/*
+ * Jai mode for QEmacs.
+ *
+ * Copyright (c) 2015-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+/*---------------- Jai coloring ----------------*/
+
+static char const jai_keywords[] = {
+ /* Jai keywords */
+ // #char #foreign #import #run
+ "using|new|remove|delete|cast|struct|enum|if|else|for|while|switch|"
+ "case|continue|break|return|defer|inline|"
+ /* predefined constants */
+ "false|true|null|it|void|"
+};
+
+static char const jai_types[] = {
+ "bool|string|int|float|float32|float64|"
+ "u8|u16|u32|u64|s8|s16|s32|s64|"
+};
+
+enum {
+ JAI_STYLE_DEFAULT = 0,
+ JAI_STYLE_DIRECTIVE = QE_STYLE_PREPROCESS,
+ JAI_STYLE_COMMENT = QE_STYLE_COMMENT,
+ JAI_STYLE_REGEX = QE_STYLE_STRING_Q,
+ JAI_STYLE_STRING = QE_STYLE_STRING,
+ JAI_STYLE_STRING_Q = QE_STYLE_STRING_Q,
+ JAI_STYLE_NUMBER = QE_STYLE_NUMBER,
+ JAI_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ JAI_STYLE_TYPE = QE_STYLE_TYPE,
+ JAI_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+ JAI_STYLE_VARIABLE = QE_STYLE_VARIABLE,
+};
+
+/* jai-mode colorization states */
+enum {
+ IN_JAI_COMMENT = 0x0F, /* multiline comment (nested) */
+ IN_JAI_COMMENT_SHIFT = 0,
+ IN_JAI_STRING = 0x10, /* double-quoted string */
+ IN_JAI_STRING_Q = 0x20, /* single-quoted string */
+};
+
+static void jai_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ int i = 0, start = i, style = 0, c = 0, i1, i2, delim, level;
+ int state = cp->colorize_state;
+ char kbuf[64];
+
+ if (state) {
+ /* if already in a state, go directly in the code parsing it */
+ if (state & IN_JAI_COMMENT)
+ goto parse_comment;
+ if (state & IN_JAI_STRING)
+ goto parse_string;
+ if (state & IN_JAI_STRING_Q)
+ goto parse_string_q;
+ }
+
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '/':
+ if (str[i] == '*') {
+ /* multi-line nested (!) comment */
+ state |= 1 << IN_JAI_COMMENT_SHIFT;
+ i++;
+ parse_comment:
+ level = (state & IN_JAI_COMMENT) >> IN_JAI_COMMENT_SHIFT;
+ while (i < n) {
+ c = str[i++];
+ if (c == '/' && str[i] == '*') {
+ level++;
+ i++;
+ continue;
+ }
+ if (c == '*' && str[i] == '/') {
+ i++;
+ level--;
+ if (level == 0)
+ break;
+ }
+ }
+ state &= ~IN_JAI_COMMENT;
+ state |= level << IN_JAI_COMMENT_SHIFT;
+ style = JAI_STYLE_COMMENT;
+ break;
+ } else
+ if (str[i] == '/') {
+ /* line comment */
+ style = JAI_STYLE_COMMENT;
+ i = n;
+ break;
+ }
+ break;
+ case '#': /* directive */
+ while (qe_isalnum(str[i])) {
+ i++;
+ }
+ style = JAI_STYLE_DIRECTIVE;
+ break;
+
+ case '\'': /* character constant */
+ /* jai accepts quoted characters and quoted symbols */
+ if (i + 1 < n && (str[i] == '\\' || str[i+1] == '\''))
+ goto parse_string_q;
+ else
+ goto normal;
+
+ parse_string_q:
+ state |= IN_JAI_STRING_Q;
+ style = JAI_STYLE_STRING_Q;
+ delim = '\'';
+ goto string;
+
+ case '\"': /* string literal */
+ parse_string:
+ state |= IN_JAI_STRING;
+ style = JAI_STYLE_STRING;
+ delim = '\"';
+ string:
+ while (i < n) {
+ c = str[i++];
+ if (c == '\\') {
+ if (i >= n)
+ break;
+ i++;
+ } else
+ if (c == delim) {
+ state &= ~(IN_JAI_STRING | IN_JAI_STRING_Q);
+ break;
+ }
+ }
+ break;
+ default:
+ normal:
+ if (qe_isdigit(c)) {
+ int j;
+ // Integers:
+ // 0x[0-9a-fA-F]+
+ // [0-9]+
+ // Floats:
+ // [0-9]+\.[0-9]+([eE][-\+]?[0-9]+)?
+ // [0-9]+(\.[0-9]+)?[eE][-\+]?[0-9]+
+ if (c == '0' && str[i] == 'x' && qe_isxdigit_(str[i + 1])) {
+ for (i += 3; qe_isxdigit_(str[i]); i++)
+ continue;
+ } else {
+ while (qe_isdigit_(str[i]))
+ i++;
+ if (str[i] == '.' && qe_isdigit_(str[i + 1])) {
+ for (i += 2; qe_isdigit_(str[i]); i++)
+ continue;
+ }
+ if (str[i] == 'e' || str[i] == 'E') {
+ j = i + 1;
+ if (str[j] == '+' || str[j] == '-')
+ j++;
+ if (qe_isdigit_(str[j])) {
+ for (i = j + 1; qe_isdigit_(str[i]); i++)
+ continue;
+ }
+ }
+ }
+ style = JAI_STYLE_NUMBER;
+ break;
+ }
+ if (qe_isalpha_(c)) {
+ i += ustr_get_identifier(kbuf, countof(kbuf), c, str, i, n);
+
+ if (strfind(syn->keywords, kbuf)) {
+ style = JAI_STYLE_KEYWORD;
+ break;
+ }
+
+ i1 = i;
+ while (qe_isblank(str[i1]))
+ i1++;
+ i2 = i1;
+ while (qe_isblank(str[i2]))
+ i2++;
+
+ if ((start == 0 || str[start - 1] != '.')
+ && !qe_findchar(".(:", str[i])
+ && strfind(syn->types, kbuf)) {
+ style = JAI_STYLE_TYPE;
+ break;
+ }
+ if (str[i1] == '(') {
+ /* function call */
+ /* XXX: different styles for call and definition */
+ style = JAI_STYLE_FUNCTION;
+ break;
+ }
+ break;
+ }
+ continue;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = 0;
+ }
+ }
+ /* set style on eol char */
+ SET_COLOR1(str, n, style);
+
+ cp->colorize_state = state;
+}
+
+static ModeDef jai_mode = {
+ .name = "Jai",
+ .extensions = "jai",
+ .keywords = jai_keywords,
+ .types = jai_types,
+ .colorize_func = jai_colorize_line,
+ //.indent_func = c_indent_line,
+ .auto_indent = 1,
+ .fallback = &c_mode,
+};
+
+static int jai_init(void)
+{
+ qe_register_mode(&jai_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(jai_init);
Index: ats.c
===================================================================
RCS file: ats.c
diff -N ats.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ats.c 2 Oct 2020 21:32:30 -0000 1.1
@@ -0,0 +1,232 @@
+/*
+ * ATS (Applied Type System) mode for QEmacs.
+ *
+ * Copyright (c) 2016-2017 Charlie Gordon.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "qe.h"
+
+/*---------------- ATS (Applied Type System) coloring ----------------*/
+
+static char const ats_keywords[] = {
+ "|extern|symintr|overload|exception|staload|dynload"
+ "|fun|prfun|fn|prfn|implement|fnx|castfn|praxi|val|prval"
+ "|abstype|absprop|absview|absviewtype|absvtype"
+ "|datatype|dataprop|dataview|dataviewtype|datavtype"
+ "|stadef|sortdef|typedef|propdef|viewdef|viewtypedef|vtypedef"
+ "|var|let|local|of|with|in|and|when|assume|macdef"
+ "|if|then|else|for|fix|where|while|case|end|try"
+ "|mod|true|false"
+ "|infix|infixl|infixr|prefix|postfix|nonfix|op|lam|rec"
+ "|"
+};
+
+static char const ats_types[] = {
+ "|bool|int|double|void|string|type|prop|view|viewtype|vtype|ptr|ref|nat"
+ "|"
+};
+
+/* XXX: should colorize $MACRO substitutions. */
+
+enum {
+ IN_ATS_COMMENT = 0x0F,
+ ATS_COMMENT_MAX_LEVEL = 0x0F,
+ ATS_COMMENT_SHIFT = 0,
+ IN_ATS_STRING = 0x10,
+ IN_ATS_CBLOCK = 0x8000,
+};
+
+enum {
+ ATS_STYLE_TEXT = QE_STYLE_DEFAULT,
+ ATS_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ ATS_STYLE_TYPE = QE_STYLE_TYPE,
+ ATS_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
+ ATS_STYLE_COMMENT = QE_STYLE_COMMENT,
+ ATS_STYLE_STRING = QE_STYLE_STRING,
+ ATS_STYLE_IDENTIFIER = QE_STYLE_DEFAULT,
+ ATS_STYLE_NUMBER = QE_STYLE_NUMBER,
+ ATS_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+};
+
+static void ats_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ char keyword[32];
+ int i = 0, start = i, c, k, style = 0, len, level;
+ int colstate = cp->colorize_state;
+
+ if (colstate & IN_ATS_CBLOCK) {
+ if (str[i] == '%' && str[i + 1] == '}') {
+ colstate = 0;
+ SET_COLOR(str, i, n, ATS_STYLE_PREPROCESS);
+ i = n;
+ } else {
+ ModeDef *md = &c_mode;
+ cp->colorize_state = colstate & ~IN_ATS_CBLOCK;
+ md->colorize_func(cp, str + i, n - i, md);
+ colstate = cp->colorize_state | IN_ATS_CBLOCK;
+ i = n;
+ }
+ } else {
+ level = (colstate & IN_ATS_COMMENT) >> ATS_COMMENT_SHIFT;
+ if (level > 0)
+ goto in_comment;
+ if (colstate & IN_ATS_STRING)
+ goto in_string;
+ }
+
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '/':
+ if (str[i] == '/') { /* C++ comments, recent extension */
+ i = n;
+ style = ATS_STYLE_COMMENT;
+ break;
+ }
+ continue;
+ case '%':
+ if (i == 1 && str[i] == '{') {
+ colstate = IN_ATS_CBLOCK;
+ i = n;
+ style = ATS_STYLE_PREPROCESS;
+ break;
+ }
+ continue;
+ case '(':
+ /* check for preprocessor */
+ if (str[i] == '*') {
+ /* regular comment (recursive?) */
+ i++;
+ level = 1;
+ in_comment:
+ while (i < n) {
+ c = str[i++];
+ if (c == '(' && str[i] == '*'
+ && level < ATS_COMMENT_MAX_LEVEL) {
+ i++;
+ level++;
+ } else
+ if (c == '*' && str[i] == ')') {
+ i++;
+ level--;
+ if (level <= 0)
+ break;
+ }
+ }
+ colstate &= ~(IN_ATS_COMMENT << ATS_COMMENT_SHIFT);
+ colstate |= level << ATS_COMMENT_SHIFT;
+ style = ATS_STYLE_COMMENT;
+ break;
+ }
+ continue;
+ case '"':
+ /* parse string or char const */
+ in_string:
+ colstate &= ~IN_ATS_STRING;
+ while (i < n) {
+ c = str[i++];
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (i == n) {
+ colstate |= IN_ATS_STRING;
+ break;
+ }
+ /* skip next character */
+ i++;
+ }
+ }
+ style = ATS_STYLE_STRING;
+ break;
+ case '#':
+ while (qe_isalpha(str[i]))
+ i++;
+ style = ATS_STYLE_PREPROCESS;
+ break;
+ case '~':
+ if (qe_isdigit(str[i]))
+ goto number;
+ continue;
+ default:
+ /* parse numbers */
+ if (qe_isdigit(c)) {
+ number:
+ for (; i < n; i++) {
+ if (!qe_isalnum(str[i]) && str[i] != '.')
+ break;
+ }
+ style = ATS_STYLE_NUMBER;
+ break;
+ }
+ /* parse identifiers and keywords */
+ if (qe_isalpha_(c) || c == '$') {
+ len = 0;
+ keyword[len++] = qe_tolower(c);
+ for (; qe_isalnum_(str[i]); i++) {
+ if (len < countof(keyword) - 1)
+ keyword[len++] = qe_tolower(str[i]);
+ }
+ if (str[i] == '!') {
+ if (len < countof(keyword) - 1)
+ keyword[len++] = str[i];
+ i++;
+ }
+ keyword[len] = '\0';
+ if (strfind(syn->keywords, keyword)) {
+ style = ATS_STYLE_KEYWORD;
+ } else
+ if (strfind(syn->types, keyword)) {
+ style = ATS_STYLE_TYPE;
+ } else {
+ k = i;
+ if (qe_isblank(str[k]))
+ k++;
+ if (str[k] == '(' && str[k + 1] != '*')
+ style = ATS_STYLE_FUNCTION;
+ else
+ style = ATS_STYLE_IDENTIFIER;
+ }
+ break;
+ }
+ continue;
+ }
+ if (style) {
+ SET_COLOR(str, start, i, style);
+ style = 0;
+ }
+ }
+ cp->colorize_state = colstate;
+}
+
+static ModeDef ats_mode = {
+ .name = "ATS",
+ .extensions = "dats|sats|hats", // dats for dynamic, sats for static files
+ .keywords = ats_keywords,
+ .types = ats_types,
+ .colorize_func = ats_colorize_line,
+};
+
+static int ats_init(void)
+{
+ qe_register_mode(&ats_mode, MODEF_SYNTAX);
+
+ return 0;
+}
+
+qe_module_init(ats_init);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs Makefile txl.c nim.c rebol.c elm.c jai.c...,
Charlie Gordon <=