diff options
Diffstat (limited to 'lexers/LexMaxima.cxx')
| -rw-r--r-- | lexers/LexMaxima.cxx | 214 | 
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);  | 
