diff options
| -rw-r--r-- | src/LexForth.cxx | 348 | 
1 files changed, 348 insertions, 0 deletions
| diff --git a/src/LexForth.cxx b/src/LexForth.cxx new file mode 100644 index 000000000..3f128156d --- /dev/null +++ b/src/LexForth.cxx @@ -0,0 +1,348 @@ +// Scintilla source code edit control +/** @file LexCrontab.cxx + ** Lexer to use with extended crontab files used by a powerful + ** Windows scheduler/event monitor/automation manager nnCron. + ** (http://nemtsev.eserv.ru/) + **/ +// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include <stdarg.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +bool is_whitespace(int ch){ +    return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '; +} + +bool is_blank(int ch){ +    return ch == '\t' || ch == ' '; +} +//#define FORTH_DEBUG +#ifdef FORTH_DEBUG +static FILE *f_debug; +#define log(x)  fputs(f_debug,x); +#else +#define log(x) +#endif + +#define STATE_LOCALE +#define BL ' ' + +static Accessor *st; +static int cur_pos,pos1,pos2,pos0,lengthDoc; +char *buffer; + +char getChar(bool is_bl){ +    char ch=st->SafeGetCharAt(cur_pos); +    if(is_bl) if(is_whitespace(ch)) ch=BL; +    return ch; +} + +char getCharBL(){ +    char ch=st->SafeGetCharAt(cur_pos); +    return ch; +} +bool is_eol(char ch){ +    return ch=='\n' || ch=='\r'; +} + +int parse(char ch, bool skip_eol){ +// pos1 - start pos of word +// pos2 - pos after of word +// pos0 - start pos +    char c=0; +    int len; +    bool is_bl=ch==BL; +    pos0=pos1=pos2=cur_pos; +    for(;cur_pos<lengthDoc && (c=getChar(is_bl))==ch; cur_pos++){ +        if(is_eol(c) && !skip_eol){ +            pos2=pos1; +            return 0; +        } +    } +    pos1=cur_pos; +    pos2=pos1; +    if(cur_pos==lengthDoc) return 0; +    for(len=0;cur_pos<lengthDoc && (c=getChar(is_bl))!=ch; cur_pos++){ +        if(is_eol(c) && !skip_eol) break; +        pos2++; +        buffer[len++]=c; +    } +    if(c==ch) pos2--; +    buffer[len]='\0'; +#ifdef FORTH_DEBUG +    fprintf(f_debug,"parse: %c %s\n",ch,buffer); +#endif +    return len; +} + +bool _is_number(char *s,int base){ +    for(;*s;s++){ +        int digit=((int)*s)-(int)'0'; +#ifdef FORTH_DEBUG +    fprintf(f_debug,"digit: %c %d\n",*s,digit); +#endif +        if(digit>9 && base>10) digit-=7; +        if(digit<0) return false; +        if(digit>=base) return false; +    } +    return true; +} + +bool is_number(char *s){ +    if(strncmp(s,"0x",2)==0) return _is_number(s+2,16); +    return _is_number(s,10); +} + +static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) +{ +    st=&styler; +    cur_pos=startPos; +    lengthDoc = startPos + length; +    buffer = new char[length]; + +#ifdef FORTH_DEBUG +    f_debug=fopen("c:\\sci.log","at"); +#endif + +    WordList &control = *keywordLists[0]; +    WordList &keyword = *keywordLists[1]; +    WordList &defword = *keywordLists[2]; +    WordList &preword1 = *keywordLists[3]; +    WordList &preword2 = *keywordLists[4]; +    WordList &strings = *keywordLists[5]; + +    // go through all provided text segment +    // using the hand-written state machine shown below +    styler.StartAt(startPos); +    styler.StartSegment(startPos); +    while(parse(BL,true)!=0){ +        if(pos0!=pos1){ +            styler.ColourTo(pos0,SCE_FORTH_DEFAULT); +            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT); +        } +        if(strcmp("\\",buffer)==0){ +            styler.ColourTo(pos1,SCE_FORTH_COMMENT); +            parse(1,false); +            styler.ColourTo(pos2,SCE_FORTH_COMMENT); +        }else if(strcmp("(",buffer)==0){ +            styler.ColourTo(pos1,SCE_FORTH_COMMENT); +            parse(')',true); +            if(cur_pos<lengthDoc) cur_pos++; +            styler.ColourTo(cur_pos,SCE_FORTH_COMMENT); +        }else if(strcmp("[",buffer)==0){ +            styler.ColourTo(pos1,SCE_FORTH_STRING); +            parse(']',true); +            if(cur_pos<lengthDoc) cur_pos++; +            styler.ColourTo(cur_pos,SCE_FORTH_STRING); +        }else if(strcmp("{",buffer)==0){ +            styler.ColourTo(pos1,SCE_FORTH_LOCALE); +            parse('}',false); +            if(cur_pos<lengthDoc) cur_pos++; +            styler.ColourTo(cur_pos,SCE_FORTH_LOCALE); +        }else if(strings.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_STRING); +            parse('"',false); +            if(cur_pos<lengthDoc) cur_pos++; +            styler.ColourTo(cur_pos,SCE_FORTH_STRING); +        }else if(control.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_CONTROL); +            styler.ColourTo(pos2,SCE_FORTH_CONTROL); +        }else if(keyword.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_KEYWORD); +            styler.ColourTo(pos2,SCE_FORTH_KEYWORD); +        }else if(defword.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_KEYWORD); +            styler.ColourTo(pos2,SCE_FORTH_KEYWORD); +            parse(BL,false); +            styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT); +            styler.ColourTo(pos1,SCE_FORTH_DEFWORD); +            styler.ColourTo(pos2,SCE_FORTH_DEFWORD); +        }else if(preword1.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_PREWORD1); +            parse(BL,false); +            styler.ColourTo(pos2,SCE_FORTH_PREWORD1); +        }else if(preword2.InList(buffer)) { +            styler.ColourTo(pos1,SCE_FORTH_PREWORD2); +            parse(BL,false); +            styler.ColourTo(pos2,SCE_FORTH_PREWORD2); +            parse(BL,false); +            styler.ColourTo(pos1,SCE_FORTH_STRING); +            styler.ColourTo(pos2,SCE_FORTH_STRING); +        }else if(is_number(buffer)){ +            styler.ColourTo(pos1,SCE_FORTH_NUMBER); +            styler.ColourTo(pos2,SCE_FORTH_NUMBER); +        } +    } +#ifdef FORTH_DEBUG +    fclose(f_debug); +#endif +    delete []buffer; +    return; +/* +                        if(control.InList(buffer)) { +                            styler.ColourTo(i,SCE_FORTH_CONTROL); +                        } else if(keyword.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD ); +                        } else if(defword.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD ); +//                            prev_state=SCE_FORTH_DEFWORD +                        } else if(preword1.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 ); +//                            state=SCE_FORTH_PREWORD1; +                        } else if(preword2.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 ); +                         } else { +                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT); +                        } +*/ +/* +    chPrev=' '; +    for (int i = startPos; i < lengthDoc; i++) { +        char ch = chNext; +        chNext = styler.SafeGetCharAt(i + 1); +        if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1); + +        if (styler.IsLeadByte(ch)) { +            chNext = styler.SafeGetCharAt(i + 2); +            i++; +            continue; +        } +#ifdef FORTH_DEBUG +        fprintf(f_debug,"%c %d ",ch,state); +#endif +        switch(state) { +            case SCE_FORTH_DEFAULT: +                if(is_whitespace(ch)) { +                    // whitespace is simply ignored here... +                    styler.ColourTo(i,SCE_FORTH_DEFAULT); +                    break; +                } else if( ch == '\\' && is_blank(chNext)) { +                    // signals the start of an one line comment... +                    state = SCE_FORTH_COMMENT; +                    styler.ColourTo(i,SCE_FORTH_COMMENT); +                } else if( is_whitespace(chPrev) &&  ch == '(' &&  is_whitespace(chNext)) { +                    // signals the start of a plain comment... +                    state = SCE_FORTH_COMMENT_ML; +                    styler.ColourTo(i,SCE_FORTH_COMMENT_ML); +                } else if( isdigit(ch) ) { +                    // signals the start of a number +                    bufferCount = 0; +                    buffer[bufferCount++] = ch; +                    state = SCE_FORTH_NUMBER; +                } else if( !is_whitespace(ch)) { +                    // signals the start of an identifier +                    bufferCount = 0; +                    buffer[bufferCount++] = ch; +                    state = SCE_FORTH_IDENTIFIER; +                } else { +                    // style it the default style.. +                    styler.ColourTo(i,SCE_FORTH_DEFAULT); +                } +                break; + +            case SCE_FORTH_COMMENT: +                // if we find a newline here, +                // we simply go to default state +                // else continue to work on it... +                if( ch == '\n' || ch == '\r' ) { +                    state = SCE_FORTH_DEFAULT; +                } else { +                    styler.ColourTo(i,SCE_FORTH_COMMENT); +                } +                break; + +            case SCE_FORTH_COMMENT_ML: +                if( ch == ')') { +                    state = SCE_FORTH_DEFAULT; +                } else { +                    styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML); +                } +                break; + +            case SCE_FORTH_IDENTIFIER: +                // stay  in CONF_IDENTIFIER state until we find a non-alphanumeric +                if( !is_whitespace(ch) ) { +                    buffer[bufferCount++] = ch; +                } else { +                    state = SCE_FORTH_DEFAULT; +                    buffer[bufferCount] = '\0'; +#ifdef FORTH_DEBUG +        fprintf(f_debug,"\nid %s\n",buffer); +#endif + +                    // check if the buffer contains a keyword, +                    // and highlight it if it is a keyword... +//                    switch(prev_state) +//                    case SCE_FORTH_DEFAULT: +                        if(control.InList(buffer)) { +                            styler.ColourTo(i,SCE_FORTH_CONTROL); +                        } else if(keyword.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_KEYWORD ); +                        } else if(defword.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_DEFWORD ); +//                            prev_state=SCE_FORTH_DEFWORD +                        } else if(preword1.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_PREWORD1 ); +//                            state=SCE_FORTH_PREWORD1; +                        } else if(preword2.InList(buffer)) { +                            styler.ColourTo(i-1,SCE_FORTH_PREWORD2 ); +                         } else { +                            styler.ColourTo(i-1,SCE_FORTH_DEFAULT); +                        } +//                        break; +//                    case + +                    // push back the faulty character +                    chNext = styler[i--]; +                } +                break; + +            case SCE_FORTH_NUMBER: +                // stay  in CONF_NUMBER state until we find a non-numeric +                if( isdigit(ch) ) { +                    buffer[bufferCount++] = ch; +                } else { +                    state = SCE_FORTH_DEFAULT; +                    buffer[bufferCount] = '\0'; +                    // Colourize here... (normal number) +                    styler.ColourTo(i-1,SCE_FORTH_NUMBER); +                    // push back a character +                    chNext = styler[i--]; +                } +                break; +        } +    } +#ifdef FORTH_DEBUG +    fclose(f_debug); +#endif +    delete []buffer; +*/ +} + +static void FoldForthDoc(unsigned int, int, int, WordList *[], +                       Accessor &) { +} + +static const char * const forthWordLists[] = { +            "control keywords", +            "keywords", +            "definition words", +            "prewords with one argument", +            "prewords with two arguments", +            "string definition keywords", +            0, +        }; + +LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth",FoldForthDoc,forthWordLists); | 
