qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs extra-modes.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs extra-modes.c
Date: Wed, 27 Mar 2019 03:43:08 -0400 (EDT)

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        19/03/27 03:43:08

Modified files:
        .              : extra-modes.c 

Log message:
        Small fixes
        
        - fix non-recursive Pascal comments
        - fix OCaml recursive comments
        - fix Pascal and OCaml comments
        - add Wolfram Language

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/extra-modes.c?cvsroot=qemacs&r1=1.68&r2=1.69

Patches:
Index: extra-modes.c
===================================================================
RCS file: /sources/qemacs/qemacs/extra-modes.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- extra-modes.c       30 Jun 2017 16:28:02 -0000      1.68
+++ extra-modes.c       27 Mar 2019 07:43:07 -0000      1.69
@@ -1,7 +1,7 @@
 /*
  * Miscellaneous language modes for QEmacs.
  *
- * Copyright (c) 2000-2017 Charlie Gordon.
+ * Copyright (c) 2000-2019 Charlie Gordon.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -598,7 +598,7 @@
             in_comment1:
                 style = PASCAL_STYLE_PREPROCESS;
             } else {
-                /* regular comment (recursive?) */
+                /* regular comment, non-recursive */
                 colstate = IN_PASCAL_COMMENT;
             in_comment:
                 style = PASCAL_STYLE_COMMENT;
@@ -611,9 +611,11 @@
             }
             break;
         case '(':
-            /* check for preprocessor */
             if (str[i] == '*') {
-                /* regular comment (recursive?) */
+                /* regular comment non-recursive */
+                /* in Standard Pascal, { and (* are equivalent,
+                   so { *) would be a valid comment.
+                   We do not support this as Turbo-Pascal does not either */
                 colstate = IN_PASCAL_COMMENT2;
                 i++;
             in_comment2:
@@ -3837,7 +3839,8 @@
 
 enum {
     IN_OCAML_COMMENT  = 0x01,
-    IN_OCAML_STRING   = 0x02,
+    IN_OCAML_COMMENT_MASK  = 0x0F,
+    IN_OCAML_STRING        = 0x10,
 };
 
 enum {
@@ -3860,7 +3863,7 @@
     int i = 0, start = i, c, k, style, len;
     int colstate = cp->colorize_state;
 
-    if (colstate & IN_OCAML_COMMENT)
+    if (colstate & IN_OCAML_COMMENT_MASK)
         goto parse_comment;
 
     if (colstate & IN_OCAML_STRING)
@@ -3890,9 +3893,14 @@
         parse_comment:
             style = OCAML_STYLE_COMMENT;
             for (; i < n; i++) {
+                /* OCaml comments do nest */
+                if (str[i] == '(' && str[i + 1] == '*') {
+                    i += 2;
+                    colstate++;
+                } else
                 if (str[i] == '*' && str[i + 1] == ')') {
                     i += 2;
-                    colstate = 0;
+                    if (--colstate == 0)
                     break;
                 }
             }
@@ -5106,6 +5114,226 @@
     return 0;
 }
 
+/*---------------- Mathematica / Wolfram language ----------------*/
+
+static char const wolfram_keywords[] = {
+    "|False|True|None"
+    "|"
+};
+
+static char const wolfram_types[] = {
+    "|"
+};
+
+enum {
+    IN_WOLFRAM_DEFAULT  = 0,
+    IN_WOLFRAM_STRING1  = 1,
+    IN_WOLFRAM_STRING2  = 2,
+    IN_WOLFRAM_COMMENT_SHIFT = 2,
+};
+
+enum {
+    WOLFRAM_STYLE_TEXT =       QE_STYLE_DEFAULT,
+    WOLFRAM_STYLE_KEYWORD =    QE_STYLE_KEYWORD,
+    WOLFRAM_STYLE_TYPE =       QE_STYLE_TYPE,
+    WOLFRAM_STYLE_COMMENT =    QE_STYLE_COMMENT,
+    WOLFRAM_STYLE_STRING1 =    QE_STYLE_STRING,
+    WOLFRAM_STYLE_STRING2 =    QE_STYLE_STRING,
+    WOLFRAM_STYLE_IDENTIFIER = QE_STYLE_DEFAULT,
+    WOLFRAM_STYLE_VARIABLE =   QE_STYLE_VARIABLE,
+    WOLFRAM_STYLE_NUMBER =     QE_STYLE_NUMBER,
+    WOLFRAM_STYLE_FUNCTION =   QE_STYLE_FUNCTION,
+};
+
+static int wolfram_get_identifier(char *buf, int buf_size, int c,
+                                  const unsigned int *str, int i, int n)
+{
+    int len = 0, j;
+
+    if (len < buf_size) {
+        buf[len++] = c;
+    }
+    for (j = i; j < n; j++) {
+        c = str[j];
+        if (!qe_isalnum_(c) && c != '$' && c != '`')
+            break;
+        if (len < buf_size - 1)
+            buf[len++] = c;
+    }
+    if (len < buf_size) {
+        buf[len] = '\0';
+    }
+    return j - i;
+}
+
+static void wolfram_colorize_line(QEColorizeContext *cp,
+                                  unsigned int *str, int n, ModeDef *syn)
+{
+    char kbuf[MAX_KEYWORD_SIZE];
+    int i = 0, start = i, c, c1 = 0, k, style = 0, comment_level, base;
+    int colstate = cp->colorize_state;
+
+    switch (colstate) {
+    case IN_WOLFRAM_DEFAULT:
+        break;
+    case IN_WOLFRAM_STRING1:
+        goto in_string1;
+    case IN_WOLFRAM_STRING2:
+        goto in_string2;
+    default:
+        comment_level = colstate >> IN_WOLFRAM_COMMENT_SHIFT;
+        goto in_comment;
+    }
+
+    while (i < n) {
+        start = i;
+        c = str[i++];
+        switch (c) {
+        case '(':
+            if (str[i] == '*') {    /* parse comment */
+                comment_level = 1;
+                i++;
+            in_comment:
+                while (i < n) {
+                    c = str[i++];
+                    if (c == '(' && str[i] == '*') {
+                        /* nested comment */
+                        i++;
+                        comment_level++;
+                    } else
+                    if (c == '*' && str[i] == ')') {
+                        i++;
+                        if (--comment_level == 0)
+                            break;
+                    }
+                }
+                colstate = comment_level << IN_WOLFRAM_COMMENT_SHIFT;
+                style = WOLFRAM_STYLE_COMMENT;
+                break;
+            }
+            continue;
+        case '\'':
+            /* parse single quoted string */
+            colstate = IN_WOLFRAM_STRING1;
+        in_string1:
+            /* XXX: should flag syntax error on
+               unescaped newline except at EOF */
+            style = WOLFRAM_STYLE_STRING1;
+            while (i < n) {
+                c1 = str[i++];
+                if (c1 == '\'') {
+                    colstate = 0;
+                    break;
+                }
+                if (c1 == '\\') {
+                    if (i < n)
+                        i++;
+                }
+            }
+            break;
+        case '\"':
+            /* parse double quoted string */
+            colstate = IN_WOLFRAM_STRING2;
+        in_string2:
+            /* XXX: should flag syntax error on
+               unescaped newline except at EOF */
+            style = WOLFRAM_STYLE_STRING2;
+            while (i < n) {
+                c1 = str[i++];
+                if (c1 == '\"') {
+                    colstate = 0;
+                    break;
+                }
+                if (c1 == '\\') {
+                    if (i < n)
+                        i++;
+                }
+            }
+            break;
+        default:
+            /* parse numbers */
+            base = 10;
+            if (c == '.' && qe_isdigit(str[i]))
+                goto in_number;
+            if (qe_isdigit(c)) {
+                int value = 0;
+                while (qe_isdigit(str[i])) {
+                    value = value * 10 + str[i++] - '0';
+                }
+                if (str[i] == '^' && str[i + 1] == '^' && value < 36) {
+                    i += 2;
+                    base = value;
+                    while (qe_digit_value(str[i]) < base)
+                        i++;
+                }
+                if (str[i] == '.') {
+                    i++;
+                in_number:
+                    while (qe_digit_value(str[i]) < base)
+                        i++;
+                }
+                if (str[i] == '`') {
+                    i++;
+                    if (str[i] == '`')
+                        i++;
+                    while (qe_isdigit(str[i]))
+                        i++;
+                }
+                if (str[i] == '*' && str[i + 1] == '^' && qe_isdigit(str[i + 
2])) {
+                    i += 3;
+                    while (qe_isdigit(str[i]))
+                        i++;
+                }
+                style = WOLFRAM_STYLE_NUMBER;
+                break;
+            }
+            /* parse identifiers and keywords */
+            if (c == '$' || c == '#' || qe_isalpha_(c)) {
+                i += wolfram_get_identifier(kbuf, countof(kbuf), c, str, i, n);
+                if (strfind(syn->keywords, kbuf)) {
+                    style = WOLFRAM_STYLE_KEYWORD;
+                } else
+                if (strfind(syn->types, kbuf)) {
+                    style = WOLFRAM_STYLE_TYPE;
+                } else {
+                    k = i;
+                    if (qe_isblank(str[k]))
+                        k++;
+                    if (str[k] == '[')
+                        style = WOLFRAM_STYLE_FUNCTION;
+                    else
+                    if (qe_islower(c) || c == '#' || c == '_')
+                        style = WOLFRAM_STYLE_VARIABLE;
+                    else
+                        style = WOLFRAM_STYLE_IDENTIFIER;
+                }
+                break;
+            }
+            continue;
+        }
+        if (style) {
+            SET_COLOR(str, start, i, style);
+            style = 0;
+        }
+    }
+    cp->colorize_state = colstate;
+}
+
+static ModeDef wolfram_mode = {
+    .name = "Wolfram",
+    .extensions = "nb",
+    .keywords = wolfram_keywords,
+    .types = wolfram_types,
+    .colorize_func = wolfram_colorize_line,
+};
+
+static int wolfram_init(void)
+{
+    qe_register_mode(&wolfram_mode, MODEF_SYNTAX);
+
+    return 0;
+}
+
 /*----------------*/
 
 static int extra_modes_init(void)
@@ -5136,6 +5364,7 @@
     scad_init();
     magpie_init();
     falcon_init();
+    wolfram_init();
     return 0;
 }
 



reply via email to

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