aboutsummaryrefslogtreecommitdiffhomepage
path: root/lexers/LexMaxima.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'lexers/LexMaxima.cxx')
-rw-r--r--lexers/LexMaxima.cxx214
1 files changed, 214 insertions, 0 deletions
diff --git a/lexers/LexMaxima.cxx b/lexers/LexMaxima.cxx
new file mode 100644
index 000000000..4dcfa5208
--- /dev/null
+++ b/lexers/LexMaxima.cxx
@@ -0,0 +1,214 @@
+// Scintilla source code edit control
+/** @file LexMaxima.cxx
+ ** Lexer for Maxima (http://maxima.sourceforge.net).
+ ** Written by Gunter Königsmann based on the lisp lexer by Alexey Yutkin and Neil Hodgson .
+ **/
+// Copyright 2018 by Gunter Königsmann <wxMaxima@physikbuch.de>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+using namespace Scintilla;
+
+static inline bool isMaximaoperator(char ch) {
+ return (ch == '\'' || ch == '`' || ch == '(' ||
+ ch == ')' || ch == '[' || ch == ']' ||
+ ch == '{' || ch == '}' || ch == '!' ||
+ ch == '*' || ch == '/' || ch == '^' ||
+ ch == ',' || ch == ':' || ch == '+' ||
+ ch == '-');
+}
+
+static void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int,
+ WordList *[],
+ Accessor &styler) {
+
+ styler.StartAt(startPos);
+
+ char chNext = styler[startPos];
+ Sci_PositionU lengthDoc = startPos + length;
+ styler.StartSegment(startPos);
+ for (Sci_PositionU i = startPos; i < lengthDoc; i++) {
+ char ch = styler.SafeGetCharAt(i);
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch))
+ continue;
+
+ // Handle comments.
+ // Comments start with /* and end with */
+ if((ch == '/') && (chNext == '*'))
+ {
+ i++;i++;
+
+ chNext = styler.SafeGetCharAt(i);
+ for (; i < lengthDoc; i++)
+ {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if((ch == '*') && (chNext == '/'))
+ {
+ i++;
+ i++;
+ break;
+ }
+ }
+ if(i > lengthDoc)
+ i = lengthDoc;
+ i--;
+ styler.ColourTo(i, SCE_MAXIMA_COMMENT);
+ continue;
+ }
+
+ // Handle Operators
+ if(isMaximaoperator(ch))
+ {
+ styler.ColourTo(i, SCE_MAXIMA_OPERATOR);
+ continue;
+ }
+
+ // Handle command endings.
+ if((ch == '$') || (ch == ';'))
+ {
+ styler.ColourTo(i, SCE_MAXIMA_COMMANDENDING);
+ continue;
+ }
+
+ // Handle numbers. Numbers always begin with a digit.
+ if(IsASCII(ch) && isdigit(ch))
+ {
+ i++;
+ for (; i < lengthDoc; i++)
+ {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if(ch == '.')
+ continue;
+
+ // A "e" or similar can be followed by a "+" or a "-"
+ if(((ch == 'e') || (ch == 'b') || (ch == 'g') || (ch == 'f')) &&
+ ((chNext == '+') || (chNext == '-')))
+ {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ if(!IsASCII(ch) || !(isdigit(ch) || islower(ch) || isupper(ch)))
+ {
+ i--;
+ break;
+ }
+ }
+ styler.ColourTo(i, SCE_MAXIMA_NUMBER);
+ continue;
+ }
+
+ // Handle strings
+ if(ch == '\"')
+ {
+ i++;
+ for (; i < lengthDoc; i++)
+ {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if(ch == '\\')
+ i++;
+ else
+ {
+ if(ch == '\"')
+ break;
+ }
+ }
+ styler.ColourTo(i, SCE_MAXIMA_STRING);
+ continue;
+ }
+
+ // Handle keywords. Maxima treats Non-ASCII chars as ordinary letters.
+ if(((!IsASCII(ch))) || isalpha(ch))
+ {
+ char cmd[100];
+ int cmdidx = 0;
+ memset(cmd,0,100);
+ cmd[cmdidx++] = ch;
+ i++;
+ for (; i < lengthDoc; i++)
+ {
+ ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ if(ch == '\\')
+ {
+ if(cmdidx < 99)
+ cmd[cmdidx++] = ch;
+ i++;
+ if(cmdidx < 99)
+ cmd[cmdidx++] = ch;
+ continue;
+ }
+ if(isMaximaoperator(ch) || ((IsASCII(ch) && !isalpha(ch) && !isdigit(ch))))
+ {
+ i--;
+ break;
+ }
+ if(cmdidx < 99)
+ cmd[cmdidx++] = ch;
+ }
+
+ // A few known keywords
+ if(
+ (strncmp(cmd,"if",99) == 0) ||
+ (strncmp(cmd,"then",99) == 0) ||
+ (strncmp(cmd,"else",99) == 0) ||
+ (strncmp(cmd,"thru",99) == 0) ||
+ (strncmp(cmd,"for",99) == 0) ||
+ (strncmp(cmd,"while",99) == 0) ||
+ (strncmp(cmd,"do",99) == 0)
+ )
+ {
+ styler.ColourTo(i, SCE_MAXIMA_COMMAND);
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ // All other keywords are functions if they are followed
+ // by an opening parenthesis
+ char nextNonwhitespace = ' ';
+ for (Sci_PositionU o = i + 1; o < lengthDoc; o++)
+ {
+ nextNonwhitespace = styler.SafeGetCharAt(o);
+ if(!IsASCII(ch) || !isspacechar(nextNonwhitespace))
+ break;
+ }
+ if(nextNonwhitespace == '(')
+ {
+ styler.ColourTo(i, SCE_MAXIMA_COMMAND);
+ }
+ else
+ {
+ styler.ColourTo(i, SCE_MAXIMA_VARIABLE);
+ }
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ styler.ColourTo(i-1, SCE_MAXIMA_UNKNOWN);
+ }
+}
+
+LexerModule lmMaxima(SCLEX_MAXIMA, ColouriseMaximaDoc, "maxima", 0, 0);