[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs Makefile .cvsignore virgil.c
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs Makefile .cvsignore virgil.c |
Date: |
Sat, 26 Nov 2016 11:00:42 +0000 (UTC) |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 16/11/26 11:00:42
Modified files:
. : Makefile .cvsignore
Added files:
. : virgil.c
Log message:
add virgil language colorizer
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/Makefile?cvsroot=qemacs&r1=1.89&r2=1.90
http://cvs.savannah.gnu.org/viewcvs/qemacs/.cvsignore?cvsroot=qemacs&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/qemacs/virgil.c?cvsroot=qemacs&rev=1.1
Patches:
Index: Makefile
===================================================================
RCS file: /sources/qemacs/qemacs/Makefile,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- Makefile 11 Jun 2016 15:55:46 -0000 1.89
+++ Makefile 26 Nov 2016 11:00:42 -0000 1.90
@@ -285,7 +285,7 @@
$(OBJS_DIR)/fbfrender.o: fbfrender.c fbfrender.h libfbf.h
$(OBJS_DIR)/qe.o: qe.c parser.c qeconfig.h qfribidi.h variables.h
$(OBJS_DIR)/qfribidi.o: qfribidi.c qfribidi.h
-$(OBJS_DIR)/clang.o: clang.c rust.c swift.c icon.c groovy.c
+$(OBJS_DIR)/clang.o: clang.c rust.c swift.c icon.c groovy.c virgil.c
$(TOBJS_DIR)/cfb.o: cfb.c cfb.h fbfrender.h
$(TOBJS_DIR)/charsetjis.o: charsetjis.c charsetjis.def
Index: .cvsignore
===================================================================
RCS file: /sources/qemacs/qemacs/.cvsignore,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- .cvsignore 14 Oct 2015 09:32:07 -0000 1.14
+++ .cvsignore 26 Nov 2016 11:00:42 -0000 1.15
@@ -47,3 +47,4 @@
txl.c
elm.c
jai.c
+ats.c
Index: virgil.c
===================================================================
RCS file: virgil.c
diff -N virgil.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ virgil.c 26 Nov 2016 11:00:42 -0000 1.1
@@ -0,0 +1,462 @@
+/*
+ * Virgil mode for QEmacs.
+ *
+ * Copyright (c) 2016 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
+ */
+
+static const char virgil_keywords[] = {
+ /* operators */
+ "instanceof|new|and|or|"
+ /* expressions */
+ "this|true|false|null|"
+ /* statements */
+ "atomic|break|continue|case|default|do|else|for|if|return|super|switch|"
+ "while|"
+ /* declarators */
+ "class|component|constructor|extends|field|function|local|method|private|"
+ "program|module|components|"
+ /* other, for files in virgil/aeneas/src/ */
+ "type|def|var|void|"
+};
+
+static const char virgil_types[] = {
+ "boolean|char|int|string|"
+ /* other, for files in virgil/aeneas/src/ */
+ "bool|"
+};
+
+enum {
+ IN_VIRGIL_COMMENT = 0x01,
+ IN_VIRGIL_STRING = 0x02,
+ IN_VIRGIL_STRING2 = 0x04,
+ IN_VIRGIL_LONG_STRING = 0x08,
+ IN_VIRGIL_LONG_STRING2 = 0x10,
+ IN_VIRGIL_DOLLAR_STRING = 0x20,
+};
+
+enum {
+ VIRGIL_STYLE_TEXT = QE_STYLE_DEFAULT,
+ VIRGIL_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
+ VIRGIL_STYLE_COMMENT = QE_STYLE_COMMENT,
+ VIRGIL_STYLE_STRING = QE_STYLE_STRING,
+ VIRGIL_STYLE_DOLLAR_STRING = QE_STYLE_STRING,
+ VIRGIL_STYLE_REGEX = QE_STYLE_STRING_Q,
+ VIRGIL_STYLE_NUMBER = QE_STYLE_NUMBER,
+ VIRGIL_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ VIRGIL_STYLE_TYPE = QE_STYLE_TYPE,
+ VIRGIL_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+ VIRGIL_STYLE_ERROR = QE_STYLE_ERROR,
+};
+
+static int qe_is_virgil_letter(int c) {
+ return qe_isalpha_(c) ||
+ (qe_inrange(c, 0x00C0, 0xFFFE) && c != 0x00D7 && c != 0x00F7);
+}
+
+static int java_scan_number(unsigned int *str0, int flavor)
+{
+ unsigned int *str = str0;
+ int c = *str++;
+ int octal = 0, nonoctal = 0, isfloat = 0;
+
+ /* Number types:
+ * binary integers: 0[bB][01]([01_]*[01])?[gliGLI]?
+ * octal integers: 0([0-7_]*[0-7])?[gliGLI]?
+ * hex integers: 0[xX][0-9a-zA-Z]([0-9a-zA-Z_]*[0-9a-zA-Z])?
+ * [gliGLI]?
+ * decimal integers: [1-9]([0-9_]*[0-9])?[gliGLI]?
+ * decimal floats: [0-9]([0-9_]*[0-9])?
+ * [.]([0-9]([0-9_]*[0-9])?)?
+ * ([eE][-+]?[0-9]([0-9_]*[0-9])?)?[dfDF]?
+ * [.][0-9]([0-9_]*[0-9])?
+ * ([eE][-+]?[0-9]([0-9_]*[0-9])?)?[dfDF]?
+ * [0-9]([0-9_]*[0-9])?
+ * [eE][-+]?[0-9]([0-9_]*[0-9])?[dfDF]?
+ * [0-9]([0-9_]*[0-9])?[dfDF]
+ * hex floats: 0[xX][0-9a-zA-Z]([0-9a-zA-Z_]*[0-9a-zA-Z])?
+ * ([.]([0-9a-zA-Z]([0-9a-zA-Z_]*[0-9a-zA-Z])?)?)?
+ * [pP][-+]?[0-9]([0-9_]*[0-9])?[dfDF]?
+ * 0[xX][.][0-9a-zA-Z]([0-9a-zA-Z_]*[0-9a-zA-Z])?
+ * [pP][-+]?[0-9]([0-9_]*[0-9])?[dfDF]?
+ *
+ * Virgil requires a digit after the decimal point.
+ *
+ * This scanner is relaxed to allow for partial numbers at end of
+ * line to avoid showing errors as numbers are typed.
+ */
+ if (c == '0') {
+ if (qe_match2(*str, 'b', 'B')) {
+ /* binary numbers */
+ str++;
+ if (!*str) goto done;
+ if (!qe_isbindigit(*str)) goto error;
+ for (str += 1; qe_isbindigit_(*str); str++)
+ continue;
+ if (!*str) goto done;
+ if (str[-1] == '_') goto error;
+ if (qe_findchar("gliGLI", *str))
+ str++;
+ goto done;
+ }
+ if (qe_match2(*str, 'x', 'X')) {
+ /* hexadecimal numbers */
+ str++;
+ if (!*str) goto done;
+ if (*str != '.') {
+ if (!qe_isxdigit(*str)) goto error;
+ for (str += 1; qe_isxdigit_(*str); str++)
+ continue;
+ if (!*str) goto done;
+ if (str[-1] == '_') goto error;
+ if (qe_findchar("gliGLI", *str)) {
+ str++;
+ goto done;
+ }
+ }
+ if (qe_findchar(".pP", *str)) {
+ isfloat = 1;
+ if (*str == '.') {
+ if (str == str0 + 2 && !qe_isxdigit(str[1])) goto error;
+ if (flavor == CLANG_VIRGIL && !qe_isxdigit(str[1])) goto
done;
+ for (str += 1; qe_isxdigit_(*str); str++)
+ continue;
+ }
+ if (!*str) goto done;
+ if (!qe_match2(*str, 'p', 'P')) goto error;
+ str++;
+ if (qe_match2(*str, '+', '-'))
+ str++;
+ if (!*str) goto done;
+ if (!qe_isdigit(*str)) goto error;
+ for (str += 1; qe_isdigit_(*str); str++)
+ continue;
+ if (str[-1] == '_') goto error;
+ }
+ if (qe_findchar("dfDF", *str))
+ str++;
+ goto done;
+ }
+ octal = 1;
+ } else
+ if (c == '.')
+ str--;
+
+ /* decimal and octal numbers */
+ for (; qe_isdigit_(*str); str++) {
+ nonoctal |= qe_match2(*str, '8', '9');
+ }
+ if (!*str) goto done;
+ if (str[-1] == '_') goto error;
+ if (*str == '.') {
+ if (str == str0 && !qe_isdigit(str[1])) goto done;
+ if (flavor == CLANG_VIRGIL && !qe_isdigit(str[1])) goto done;
+ str++;
+ isfloat = 1;
+ if (!*str) goto done;
+ if (qe_isdigit(*str)) {
+ for (str += 1; qe_isdigit_(*str); str++)
+ continue;
+ if (!*str) goto done;
+ if (str[-1] == '_') goto error;
+ }
+ }
+ if (qe_match2(*str, 'e', 'E')) {
+ str++;
+ isfloat = 1;
+ if (qe_match2(*str, '+', '-'))
+ str++;
+ if (!*str) goto done;
+ if (!qe_isdigit(*str)) goto error;
+ for (str += 1; qe_isdigit_(*str); str++)
+ continue;
+ if (!*str) goto done;
+ if (str[-1] == '_') goto error;
+ }
+ if (qe_findchar("dfDF", *str)) {
+ str++;
+ isfloat = 1;
+ goto done;
+ }
+ if (!*str) goto done;
+ if (!isfloat) {
+ if (octal && nonoctal) goto error;
+ if (qe_findchar("gliGLI", *str)) {
+ str++;
+ goto done;
+ }
+ }
+
+done:
+ if (!qe_isalnum_(*str)) {
+ return str - str0;
+ }
+
+error:
+ while (qe_isalnum_(*str))
+ str++;
+ return -(str - str0);
+}
+
+static void virgil_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, ModeDef *syn)
+{
+ int i = 0, start = i, c, style, sep = 0, klen, haslower;
+ int state = cp->colorize_state;
+ char kbuf[32];
+
+ /* all these states are exclusive */
+ if (state & IN_VIRGIL_COMMENT) {
+ goto parse_comment;
+ }
+ if (state & IN_VIRGIL_STRING) {
+ sep = '\'';
+ goto parse_string;
+ }
+ if (state & IN_VIRGIL_STRING2) {
+ sep = '\"';
+ goto parse_string;
+ }
+ if (state & IN_VIRGIL_LONG_STRING) {
+ sep = '\'';
+ goto parse_long_string;
+ }
+ if (state & IN_VIRGIL_LONG_STRING2) {
+ sep = '\"';
+ goto parse_long_string;
+ }
+ if (state & IN_VIRGIL_DOLLAR_STRING) {
+ goto parse_dollar_string;
+ }
+
+ style = 0;
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '#':
+ if (start == 0 && str[i] == '!') {
+ /* shebang line (should do this generically) */
+ i = n;
+ style = VIRGIL_STYLE_PREPROCESS;
+ break;
+ }
+ continue;
+
+ case '~':
+ while (qe_isblank(str[i]))
+ i++;
+ if (str[i] == '/') {
+ /* parse slashy string as regex */
+ sep = '/';
+ start = i++;
+ goto parse_string;
+ }
+ continue;
+
+ case '/':
+ if (str[i] == '*') {
+ /* normal comment */
+ i++;
+ parse_comment:
+ state |= IN_VIRGIL_COMMENT;
+ for (; i < n; i++) {
+ if (str[i] == '*' && str[i + 1] == '/') {
+ i += 2;
+ state &= ~IN_VIRGIL_COMMENT;
+ break;
+ }
+ }
+ style = VIRGIL_STYLE_COMMENT;
+ break;
+ } else
+ if (str[i] == '/') {
+ /* line comment */
+ i = n;
+ style = VIRGIL_STYLE_COMMENT;
+ break;
+ }
+ /* XXX: should handle slashy strings */
+ continue;
+
+ case '\'':
+ case '\"':
+ /* parse string const */
+ i--;
+ sep = str[i++];
+ /* XXX: should colorize interpolated strings */
+ if (str[i] == (unsigned int)sep && str[i + 1] == (unsigned
int)sep) {
+ /* long string */
+ state |= (sep == '\"') ? IN_VIRGIL_LONG_STRING2 :
+ IN_VIRGIL_LONG_STRING;
+ i += 2;
+ parse_long_string:
+ while (i < n) {
+ c = str[i++];
+ if (c == '\\') {
+ if (i < n) {
+ i += 1;
+ }
+ } else
+ if (c == sep && str[i] == (unsigned int)sep && str[i + 1]
== (unsigned int)sep) {
+ i += 2;
+ state &= (sep == '\"') ? ~IN_VIRGIL_LONG_STRING2 :
+ ~IN_VIRGIL_LONG_STRING;
+ break;
+ }
+ }
+ } else {
+ state |= (sep == '\"') ? IN_VIRGIL_STRING2 : IN_VIRGIL_STRING;
+ parse_string:
+ while (i < n) {
+ c = str[i++];
+ if (c == '\\') {
+ if (i < n) {
+ i += 1;
+ }
+ } else
+ if (c == sep) {
+ state &= (sep == '\"') ? ~IN_VIRGIL_STRING2 :
~IN_VIRGIL_STRING;
+ break;
+ }
+ }
+ }
+ style = VIRGIL_STYLE_STRING;
+ break;
+
+ case '$':
+ if (str[i] == '/') {
+ /* $ slashy string */
+ i++;
+ state |= IN_VIRGIL_DOLLAR_STRING;
+ parse_dollar_string:
+ while (i < n) {
+ c = str[i++];
+ if (c == '$') {
+ if (i < n) {
+ i += 1;
+ }
+ } else
+ if (c == '/' && str[i] == '$') {
+ state &= ~IN_VIRGIL_DOLLAR_STRING;
+ i += 2;
+ break;
+ }
+ }
+ style = VIRGIL_STYLE_DOLLAR_STRING;
+ break;
+ }
+ goto hasname;
+
+ case '@':
+ if (qe_isalpha(str[i])) {
+ while (qe_isalnum_(str[i]) || qe_is_virgil_letter(str[i]) ||
str[i] == '.')
+ i++;
+ if (start == 0 || str[start - 1] != '.')
+ style = VIRGIL_STYLE_PREPROCESS;
+ break;
+ }
+ continue;
+
+ case '.':
+ if (!qe_isdigit(str[i]))
+ continue;
+ /* fallthru */
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ i--;
+ klen = java_scan_number(str + i, CLANG_VIRGIL);
+ if (klen > 0) {
+ i += klen;
+ style = VIRGIL_STYLE_NUMBER;
+ break;
+ } else
+ if (klen < 0) {
+ /* Malformed number constants */
+ i -= klen;
+ style = VIRGIL_STYLE_ERROR;
+ break;
+ }
+ i++;
+ continue;
+
+ default:
+ if (qe_is_virgil_letter(c)) {
+ hasname:
+ haslower = 0;
+ klen = 0;
+ kbuf[klen++] = c;
+ for (; qe_isalnum_(str[i]) || qe_is_virgil_letter(str[i]);
i++) {
+ haslower |= qe_islower(str[i]);
+ if (klen < countof(kbuf) - 1)
+ kbuf[klen++] = str[i];
+ }
+ kbuf[klen] = '\0';
+
+ /* keywords are not recognised after '.',
+ * nor before a single '.' nor a map key indicator ':' */
+ if ((start == 0 || str[start - 1] != '.')
+ && (str[i] != '.' || str[i + 1] == '.')
+ && str[i] != ':') {
+ if ((qe_isupper(c) && haslower && !check_fcall(str, i))
+ || strfind(syn->types, kbuf)) {
+ style = VIRGIL_STYLE_TYPE;
+ break;
+ }
+ if (strfind(syn->keywords, kbuf)) {
+ style = VIRGIL_STYLE_KEYWORD;
+ break;
+ }
+ }
+ if (check_fcall(str, i)) {
+ style = VIRGIL_STYLE_FUNCTION;
+ break;
+ }
+ continue;
+ }
+ 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 virgil_mode = {
+ .name = "Virgil",
+ .extensions = "v3",
+ .shell_handlers = "virgil",
+ .colorize_func = virgil_colorize_line,
+ .colorize_flags = CLANG_VIRGIL,
+ .keywords = virgil_keywords,
+ .types = virgil_types,
+ .indent_func = c_indent_line,
+ .auto_indent = 1,
+ .fallback = &c_mode,
+};
+
+static int virgil_init(void)
+{
+ qe_register_mode(&virgil_mode, MODEF_SYNTAX);
+
+ return 0;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemacs-commit] qemacs Makefile .cvsignore virgil.c,
Charlie Gordon <=