qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs Makefile clang.c groovy.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs Makefile clang.c groovy.c
Date: Fri, 07 Aug 2015 08:29:00 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        15/08/07 08:29:00

Modified files:
        .              : Makefile clang.c 
Added files:
        .              : groovy.c 

Log message:
        add colorizer for the Groovy programming language

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/Makefile?cvsroot=qemacs&r1=1.77&r2=1.78
http://cvs.savannah.gnu.org/viewcvs/qemacs/clang.c?cvsroot=qemacs&r1=1.90&r2=1.91
http://cvs.savannah.gnu.org/viewcvs/qemacs/groovy.c?cvsroot=qemacs&rev=1.1

Patches:
Index: Makefile
===================================================================
RCS file: /sources/qemacs/qemacs/Makefile,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -b -r1.77 -r1.78
--- Makefile    28 Jul 2015 19:03:24 -0000      1.77
+++ Makefile    7 Aug 2015 08:28:59 -0000       1.78
@@ -237,7 +237,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
+$(OBJS_DIR)/clang.o: clang.c rust.c swift.c icon.c groovy.c
 
 $(TOBJS_DIR)/cfb.o: cfb.c cfb.h fbfrender.h
 $(TOBJS_DIR)/charsetjis.o: charsetjis.c charsetjis.def
@@ -444,14 +444,14 @@
         charsetjis.c charsetjis.def charsetmore.c clang.c cobol.c config.eg \
         configure cptoqe.c cutils.c cutils.h dired.c display.c display.h \
         docbook.c ebnf.c extra-modes.c extras.c fbfrender.c fbfrender.h \
-        fbftoqe.c forth.c haiku-pe2qe.sh haiku.cpp hex.c html.c html2png.c \
-        htmlsrc.c icon.c image.c indic.c input.c jistoqe.c kmap.c kmaptoqe.c \
-        latex-mode.c libfbf.c libfbf.h ligtoqe.c lisp.c list.c makemode.c \
-        markdown.c mpeg.c orgmode.c parser.c perl.c qe-doc.html qe-doc.texi \
-        qe.1 qe.c qe.h qe.tcc qeconfig.h qeend.c qemacs.spec qestyles.h \
-        qfribidi.c qfribidi.h rlang.c rust.c script.c shell.c swift.c tty.c \
-        unicode_join.c unifont.lig unihex.c unix.c util.c variables.c \
-        variables.h video.c win32.c x11.c xml.c
+        fbftoqe.c forth.c groovy.c haiku-pe2qe.sh haiku.cpp hex.c html.c \
+        html2png.c htmlsrc.c icon.c image.c indic.c input.c jistoqe.c kmap.c \
+        kmaptoqe.c latex-mode.c libfbf.c libfbf.h ligtoqe.c lisp.c list.c \
+        makemode.c markdown.c mpeg.c orgmode.c parser.c perl.c qe-doc.html \
+        qe-doc.texi qe.1 qe.c qe.h qe.tcc qeconfig.h qeend.c qemacs.spec \
+        qestyles.h qfribidi.c qfribidi.h rlang.c rust.c script.c shell.c \
+        swift.c tty.c unicode_join.c unifont.lig unihex.c unix.c util.c \
+        variables.c variables.h video.c win32.c x11.c xml.c
 
 FILES+=plugins/Makefile  plugins/my_plugin.c
 

Index: clang.c
===================================================================
RCS file: /sources/qemacs/qemacs/clang.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -b -r1.90 -r1.91
--- clang.c     4 Aug 2015 17:14:29 -0000       1.90
+++ clang.c     7 Aug 2015 08:28:59 -0000       1.91
@@ -60,6 +60,7 @@
     CLANG_RUST,
     CLANG_SWIFT,
     CLANG_ICON,
+    CLANG_GROOVY,
     CLANG_FLAVOR = 0x3F,
 };
 
@@ -134,11 +135,11 @@
 
 static const char java_keywords[] = {
     /* language keywords */
-    "abstract|assert||break|case|catch|class|const|continue|"
+    "abstract|assert|break|case|catch|class|const|continue|"
     "default|do|else|enum|extends|final|finally|for|goto|"
     "if|implements|import|instanceof|interface|native|new|"
     "package|private|protected|public|return|"
-    "static|strictfp|super|switch|synchronized|"
+    "static|strictfp|super|switch|synchronized|threadsafe|"
     "this|throw|throws|transient|try|volatile|while|"
     /* boolean and null literals */
     "false|null|true|"
@@ -2118,6 +2119,7 @@
 #include "rust.c"
 #include "swift.c"
 #include "icon.c"
+#include "groovy.c"
 
 static int c_init(void)
 {
@@ -2168,6 +2170,7 @@
     rust_init();
     swift_init();
     icon_init();
+    groovy_init();
 
     return 0;
 }

Index: groovy.c
===================================================================
RCS file: groovy.c
diff -N groovy.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ groovy.c    7 Aug 2015 08:28:59 -0000       1.1
@@ -0,0 +1,471 @@
+/*
+ * Groovy mode for QEmacs.
+ *
+ * Copyright (c) 2015 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 int check_fcall(unsigned int *str, int i) {
+    while (str[i] == ' ')
+        i++;
+    return str[i] == '(';
+}
+
+static inline int qe_match2(int c, int c1, int c2) {
+    return c == c1 || c == c2;
+}
+
+static const char groovy_keywords[] = {
+    /* language specific keywords */
+    "as|def|in|trait|"
+    /* documented java keywords */
+    "assert|break|case|catch|class|const|continue|"
+    "default|do|else|enum|extends|final|finally|for|goto|"
+    "if|implements|import|instanceof|interface|new|"
+    "package|return|super|switch|"
+    "this|throw|throws|try|while|"
+    /* boolean and null literals */
+    "false|null|true|"
+    /* other java keywords */
+    "abstract|native|private|protected|public|static|strictfp|"
+    "synchronized|threadsafe|transient|volatile|"
+};
+
+static const char groovy_types[] = {
+    "void|boolean|byte|char|short|int|long|double|float|"
+};
+
+enum {
+    IN_GROOVY_COMMENT      = 0x01,
+    IN_GROOVY_STRING       = 0x02,
+    IN_GROOVY_STRING2      = 0x04,
+    IN_GROOVY_LONG_STRING  = 0x08,
+    IN_GROOVY_LONG_STRING2 = 0x10,
+    IN_GROOVY_DOLLAR_STRING = 0x20,
+};
+
+enum {
+    GROOVY_STYLE_TEXT =       QE_STYLE_DEFAULT,
+    GROOVY_STYLE_PREPROCESS = QE_STYLE_PREPROCESS,
+    GROOVY_STYLE_COMMENT =    QE_STYLE_COMMENT,
+    GROOVY_STYLE_STRING =     QE_STYLE_STRING,
+    GROOVY_STYLE_DOLLAR_STRING = QE_STYLE_STRING,
+    GROOVY_STYLE_REGEX =      QE_STYLE_STRING_Q,
+    GROOVY_STYLE_NUMBER =     QE_STYLE_NUMBER,
+    GROOVY_STYLE_KEYWORD =    QE_STYLE_KEYWORD,
+    GROOVY_STYLE_TYPE =       QE_STYLE_TYPE,
+    GROOVY_STYLE_FUNCTION =   QE_STYLE_FUNCTION,
+    GROOVY_STYLE_ERROR =      QE_STYLE_ERROR,
+};
+
+static int qe_is_groovy_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]?
+     *
+     * Groovy 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_GROOVY && !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_GROOVY && !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 groovy_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_GROOVY_COMMENT) {
+        goto parse_comment;
+    }
+    if (state & IN_GROOVY_STRING) {
+        sep = '\'';
+        goto parse_string;
+    }
+    if (state & IN_GROOVY_STRING2) {
+        sep = '\"';
+        goto parse_string;
+    }
+    if (state & IN_GROOVY_LONG_STRING) {
+        sep = '\'';
+        goto parse_long_string;
+    }
+    if (state & IN_GROOVY_LONG_STRING2) {
+        sep = '\"';
+        goto parse_long_string;
+    }
+    if (state & IN_GROOVY_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 = GROOVY_STYLE_PREPROCESS;
+                break;
+            }
+            continue;
+            
+        case '~':
+            while (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_GROOVY_COMMENT;
+                for (; i < n; i++) {
+                    if (str[i] == '*' && str[i + 1] == '/') {
+                        i += 2;
+                        state &= ~IN_GROOVY_COMMENT;
+                        break;
+                    }
+                }
+                style = GROOVY_STYLE_COMMENT;
+                break;
+            } else
+            if (str[i] == '/') {
+                /* line comment */
+                i = n;
+                style = GROOVY_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_GROOVY_LONG_STRING2 :
+                        IN_GROOVY_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_GROOVY_LONG_STRING2 :
+                                 ~IN_GROOVY_LONG_STRING;
+                        break;
+                    }
+                }
+            } else {
+                state |= (sep == '\"') ? IN_GROOVY_STRING2 : IN_GROOVY_STRING;
+            parse_string:
+                while (i < n) {
+                    c = str[i++];
+                    if (c == '\\') {
+                        if (i < n) {
+                            i += 1;
+                        }
+                    } else
+                    if (c == sep) {
+                        state &= (sep == '\"') ? ~IN_GROOVY_STRING2 : 
~IN_GROOVY_STRING;
+                        break;
+                    }
+                }
+            }
+            style = GROOVY_STYLE_STRING;
+            break;
+
+        case '$':
+            if (str[i] == '/') {
+                /* $ slashy string */
+                i++;
+                state |= IN_GROOVY_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_GROOVY_DOLLAR_STRING;
+                        i += 2;
+                        break;
+                    }
+                }
+                style = GROOVY_STYLE_DOLLAR_STRING;
+                break;
+            }
+            goto hasname;
+
+        case '@':
+            if (qe_isalpha(str[i])) {
+                while (qe_isalnum_(str[i]) || qe_is_groovy_letter(str[i]) || 
str[i] == '.')
+                    i++;
+                if (start == 0 || str[start - 1] != '.')
+                    style = GROOVY_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_GROOVY);
+            if (klen > 0) {
+                i += klen;
+                style = GROOVY_STYLE_NUMBER;
+                break;
+            } else
+            if (klen < 0) {
+                /* Malformed number constants */
+                i -= klen;
+                style = GROOVY_STYLE_ERROR;
+                break;
+            }
+            i++;
+            continue;
+
+        default:
+            if (qe_is_groovy_letter(c)) {
+            hasname:
+                haslower = 0;
+                klen = 0;
+                kbuf[klen++] = c;
+                for (; qe_isalnum_(str[i]) || qe_is_groovy_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 = GROOVY_STYLE_TYPE;
+                        break;
+                    }
+                    if (strfind(syn->keywords, kbuf)) {
+                        style = GROOVY_STYLE_KEYWORD;
+                        break;
+                    }
+                }
+                if (check_fcall(str, i)) {
+                    style = GROOVY_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 groovy_mode = {
+    .name = "Groovy",
+    .extensions = "groovy|gradle",
+    .shell_handlers = "groovy",
+    .colorize_func = groovy_colorize_line,
+    .colorize_flags = CLANG_GROOVY,
+    .keywords = groovy_keywords,
+    .types = groovy_types,
+    .indent_func = c_indent_line,
+    .auto_indent = 1,
+    .fallback = &c_mode,
+};
+
+static int groovy_init(void)
+{
+    qe_register_mode(&groovy_mode, MODEF_SYNTAX);
+
+    return 0;
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]