コード例 #1
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int Style(CodeEditor editor, int pos, int endPos)
        {
            ILexer lex = null;

            // Find a lexer that can continue lexing.
            // Use the previous state to select the right lexer.
            // As long as no lexer can be found, move the start position backward.
            while (pos >= 0 && lex == null)
                lex = FindLexerForStyle(editor.GetStyleAt(pos--));

            // start lexing from the newly determined start position
            return (lex ?? lexer.First()).Style(editor, pos + 1, endPos);
        }
コード例 #2
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case ')': return (int)BaseState.Braces;
                case '=': return (int)BaseState.Operator;
                case ',': return (int)BaseState.Punctuation;
            }

            // the beginning of a number
            if (char.IsDigit(c.c))
                return (int)BaseState.Number;

            // the beginning of a qualifier keyword
            if (char.IsLetter(c.c))
                return (int)State.Indicator;

            return (int)State.Default;
        }
コード例 #3
0
ファイル: FXDebugger.cs プロジェクト: h3tch/ProtoFX
        /// <summary>
        /// Get debug variable from the specified text line in the code editor.
        /// </summary>
        /// <param name="editor">Source code editor.</param>
        /// <param name="line">Zero-based line number in the code.</param>
        /// <returns>Returns all debug variables in the specified line or
        /// <code>null</code> if no debug variable could be found.</returns>
        public static IEnumerable<DbgVar> GetDebugVariablesFromLine(CodeEditor editor, int line, int length = 1)
        {
            // find all debug variables
            var vars = RegexDbgVar.Matches(editor.Text);
            var from = line;
            var to = line + length;

            for (int i = 0; i < vars.Count; i++)
            {
                var varLine = editor.LineFromPosition(vars[i].Index);
                // is the debug variable in the same line
                if (from <= varLine && varLine < to)
                    yield return new DbgVar(i, vars[i].Index, varLine, vars[i].Value);
            }
        }
コード例 #4
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case '#': return (int)State.Preprocessor;
                case '_': return (int)State.Indicator;
                case '(':
                case ')':
                case '{':
                case '}':  return (int)BaseState.Braces;
                case '.':
                case ';': return (int)BaseState.Punctuation;
                case '=': return (int)BaseState.Operator;
                case '/':
                    if (c[1] == '/') return (int)BaseState.LineComment;
                    if (c[1] == '*') return (int)BaseState.BlockComment;
                    break;
            }

            // the beginning of a keyword
            if (char.IsLetter(c.c))
                return (int)State.Indicator;

            return (int)State.Default;
        }
コード例 #5
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        private int ProcessBracesState(CodeEditor editor, Region c, int endPos)
        {
            // get the lexer type of the body
            string type = null;
            switch (c[-1])
            {
                case '(':
                    // get preceding word from brace position
                    var wordStart = editor.WordStartPosition(c.Pos - 1, false);
                    type = editor.GetWordFromPosition(wordStart);

                    if (type != "layout")
                        type = "functionheader";
                    break;
                case '{':
                    // get preceding non-whitespace position from brace position
                    var bracePos = c.Pos - 2;
                    while (bracePos >= 0
                        && (char)editor.GetCharAt(bracePos) != ';'
                        && char.IsWhiteSpace((char)editor.GetCharAt(bracePos)))
                        bracePos--;

                    // if the preceding char is a closing brace, we have to lex a function body
                    var braceChar = (char)editor.GetCharAt(bracePos);
                    type = braceChar == ')' ? "function" : "struct";
                    break;
                case '}':
                    return -1;
                default:
                    return ProcessDefaultState(editor, c);
            }

            // find lexer that can lex this code block
            var lex = lexer.Where(x => x.IsLexerForType(type)).FirstOr(null);

            // re-lex body of the uniform block, struct, layout or function
            c.Pos = lex?.Style(editor, c.Pos, endPos) ?? c.Pos;

            // continue styling from the last position
            editor.StartStyling(c.Pos);
            return ProcessDefaultState(editor, c);
        }
コード例 #6
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case  '_': return (int)State.Indicator;
                case  '"': return (int)BaseState.String;
                case  '.': return (int)(char.IsNumber(c[1]) ? BaseState.Number : BaseState.Punctuation);
                case '\n': return DefaultProcessNewLine(editor, c);
            }

            // the beginning of a word or keyword
            if (char.IsLetter(c.c))
                return (int)State.Indicator;

            // start of a number
            if(char.IsNumber(c.c))
                return (int)BaseState.Number;

            return (int)State.Default;
        }
コード例 #7
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case '"': case '\'':
                    // the beginning of a string
                    return (int)BaseState.String;

                case '.':
                    // the beginning of a number or punctuation
                    return (int)(char.IsNumber(c[1]) ? BaseState.Number : BaseState.Punctuation);
                case ',': case ';':
                    // a punctuation
                    return (int)BaseState.Punctuation;

                case '*': case '+': case '-':
                    // an operator
                    return (int)BaseState.Operator;
                case '/':
                    // the beginning of a line comment
                    if (c[1] == '/') return (int)BaseState.LineComment;
                    // the beginning of a block comment
                    if (c[1] == '*') return (int)BaseState.BlockComment;
                    // an operator
                    return (int)BaseState.Operator;

                case '(': case ')':
                case '[': case ']':
                    // a brace
                    return (int)BaseState.Braces;

                case '}':
                    // exit lexer
                    return -1;

                case '\n':
                    // exit lexer if line does not end with "."
                    return DefaultProcessNewLine(editor, c);
            }

            // the beginning of an operator
            if (char.IsSymbol(c.c))
                return (int)BaseState.Operator;

            // the beginning of a number
            if (char.IsNumber(c.c) && !char.IsLetter(c[-1]) && c[-1] != '_')
                return (int)BaseState.Number;
            
            return (int)BaseState.Default;
        }
コード例 #8
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process block comment state.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="c"></param>
 /// <returns>The new state after processing the current state.</returns>
 protected int ProcessBlockCommentState(CodeEditor editor, Region c)
     => c[-2] == '*' && c[-1] == '/' ? ProcessDefaultState(editor, c) : (int)BaseState.BlockComment;
コード例 #9
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        /// <summary>
        /// Default process indicator state.
        /// </summary>
        /// <param name="editor"></param>
        /// <param name="c"></param>
        /// <param name="IndicatorState"></param>
        /// <returns>The new state after processing the current state.</returns>
        protected int ProcessIndicatorState(CodeEditor editor, Region c, int IndicatorState)
        {
            // position still inside the word range
            if (char.IsLetterOrDigit(c.c) || c.c == '_')
                return IndicatorState;

            // relex last word
            RelexPreviousWord(editor, c.Pos);

            // continue from default state
            return ProcessDefaultState(editor, c);
        }
コード例 #10
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process number state method.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="c"></param>
 /// <returns>The new state after processing the current state.</returns>
 protected int ProcessNumberState(CodeEditor editor, Region c)
     => char.IsNumber(c.c)
         || c.c == '.' || c.c == 'x'
         || ('a' <= c.c && c.c <= 'f')
         || ('A' <= c.c && c.c <= 'F')
         ? (int)BaseState.Number
         : ProcessDefaultState(editor, c);
コード例 #11
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process line comment state.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="c"></param>
 /// <returns>The new state after processing the current state.</returns>
 protected int ProcessLineCommentState(CodeEditor editor, Region c)
     => c.c == '\n' ? ProcessDefaultState(editor, c) : (int)BaseState.LineComment;
コード例 #12
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process string state method.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="c"></param>
 /// <returns>The new state after processing the current state.</returns>
 protected int ProcessStringState(CodeEditor editor, Region c)
     => (c.c == '\n' || (c[-1] == '"' && c[-2] != '\\' && c.GetStyleAt(-2) == StringStyle))
         ? ProcessDefaultState(editor, c)
         : (int)BaseState.String;
コード例 #13
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process default state method.
 /// </summary>
 /// <param name="e">unused</param>
 /// <param name="c">unused</param>
 /// <returns>The new state after processing the current state.</returns>
 public virtual int ProcessDefaultState(CodeEditor e, Region c) => 0;
コード例 #14
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process state method.
 /// </summary>
 /// <param name="e">unused</param>
 /// <param name="state"></param>
 /// <param name="c">unused</param>
 /// <param name="p">unused</param>
 /// <returns>The new state after processing the current state.</returns>
 public virtual int ProcessState(CodeEditor e, int state, Region c, int p) => state;
コード例 #15
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case '/':
                    if (c[1] == '/') return (int)BaseState.LineComment;
                    if (c[1] == '*') return (int)BaseState.BlockComment;
                    break;
                case '_': return (int)State.Indicator;
                case '.': return (int)BaseState.Punctuation;
                case '}': return (int)BaseState.Braces; // end of the block
            }

            // the beginning of a word or keyword
            if (char.IsLetter(c.c))
                return (int)State.Indicator;
            
            return (int)State.Default;
        }
コード例 #16
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Default process new line state.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="c"></param>
 /// <returns>The new state after processing the current state.</returns>
 protected int DefaultProcessNewLine(CodeEditor editor, Region c)
 {
     // exit lexer if line does not end with "..."
     int i = c.Pos - 1;
     var C = (char)editor.GetCharAt(i);
     while (i > 0 && C != '\n' && char.IsWhiteSpace(C))
         C = (char)editor.GetCharAt(--i);
     return editor.GetTextRange(i - 2, 3) != "..." ? -1 : (int)BaseState.Default;
 }
コード例 #17
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        private new int ProcessIndicatorState(CodeEditor editor, Region c, int endPos)
        {
            // is still part of the command
            if (!char.IsWhiteSpace(c.c))
                return (int)State.Indicator;

            // relex last word
            RelexPreviousWord(editor, c.Pos);

            // get header string from block position
            var cmd = editor.GetWordFromPosition(c.Pos - 1);

            // find lexer that can lex this code block
            var lex = lexer.Where(x => x.IsLexerForType(cmd)).FirstOr(defaultLexer);

            // re-lex code block
            c.Pos = lex.Style(editor, c.Pos, endPos);

            // continue lexing
            return ProcessDefaultState(editor, c);
        }
コード例 #18
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        /// <summary>
        /// Relex the first word directly before the current position.
        /// </summary>
        /// <param name="editor"></param>
        /// <param name="pos"></param>
        protected void RelexPreviousWord(CodeEditor editor, int pos)
        {
            // get previous word and start position
            var start = editor.WordStartPosition(pos, false);
            var word = editor.GetWordFromPosition(start);

            // find out if the previous word is a keyword
            for (int i = 0; i < keywords.Length; i++)
            {
                // reset the style of the word if it is a keyword
                if (keywords[i]?[word].Any(x => x.word == word) ?? false)
                {
                    editor.StartStyling(start);
                    editor.SetStyling(pos - start, StateToStyle(i));
                }
            }
        }
コード例 #19
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 public override int ProcessState(CodeEditor editor, int state, Region c, int endPos)
 {
     switch (state)
     {
         case (int)BaseState.Number:
             return ProcessNumberState(editor, c);
         case (int)BaseState.String:
             return ProcessStringState(editor, c);
         case (int)BaseState.LineComment:
             return ProcessLineCommentState(editor, c);
         case (int)BaseState.BlockComment:
             return ProcessBlockCommentState(editor, c);
     }
     return ProcessDefaultState(editor, c);
 }
コード例 #20
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 /// <summary>
 /// Find last position in the text that has the specified style.
 /// </summary>
 /// <param name="editor"></param>
 /// <param name="style"></param>
 /// <param name="from"></param>
 /// <returns></returns>
 protected int FindLastStyleOf(CodeEditor editor, int style, int from)
 {
     while (from > 0 && editor.GetStyleAt(from) != style)
         from--;
     return editor.GetStyleAt(from) == style ? from : -1;
 }
コード例 #21
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 public override int ProcessState(CodeEditor editor, int state, Region c, int endPos)
 {
     switch (state)
     {
         case (int)BaseState.Braces:
             return ProcessBracesState(editor, c, endPos);
         case (int)BaseState.LineComment:
             return ProcessLineCommentState(editor, c);
         case (int)BaseState.BlockComment:
             return ProcessBlockCommentState(editor, c);
         case (int)State.Preprocessor:
             return ProcessPreprocessorState(editor, c, endPos);
         case (int)State.Indicator:
             return ProcessIndicatorState(editor, c, (int)State.Indicator);
     }
     return ProcessDefaultState(editor, c);
 }
コード例 #22
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public override int ProcessDefaultState(CodeEditor editor, Region c)
        {
            switch (c.c)
            {
                case '/':
                    if (c[1] == '/') return (int)BaseState.LineComment;
                    if (c[1] == '*') return (int)BaseState.BlockComment;
                    break;
                case '#': return (int)State.Preprocessor;
                case '{': return (int)BaseState.Braces;
                case '_': return (int)State.Indicator;
            }

            if (char.IsLetter(c.c))
                return (int)State.Indicator;

            return (int)State.Default;
        }
コード例 #23
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 private int ProcessPreprocessorState(CodeEditor editor, Region c, int endPos)
 {
     if (c.c == '\n')
         return (int)State.Default;
     if (char.IsWhiteSpace(c.c))
     {
         c.Pos = defaultLexer.Style(editor, c.Pos, endPos);
         return ProcessDefaultState(editor, c);
     }
     return (int)State.Preprocessor;
 }
コード例 #24
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        private int ProcessBraceState(CodeEditor editor, Region c, int endPos)
        {
            if (c[-1] == '{')
            {
                // get header string from block position
                var typePos = FindLastStyleOf(editor, StateToStyle((int)State.Type), c.Pos);
                var typeName = typePos >= 0 ? editor.GetWordFromPosition(typePos) : null;

                // find lexer that can lex this code block
                var lex = lexer.Where(x => x.IsLexerForType(typeName)).FirstOr(null);

                // if no lexer found, skip this code block
                if (lex == null)
                {
                    // go to matching brace
                    int start = c.Pos;
                    for (int n = 0; c.Pos < endPos && n >= 0; c.Pos++)
                    {
                        if (c.c == '{') n++;
                        if (c.c == '}') n--;
                    }
                    // make code block invalid
                    editor.SetStyling(--c.Pos - start, StateToStyle((int)BaseState.Default));
                    return (int)(c.c == '}' ? BaseState.Braces : BaseState.Default);
                }

                // re-lex code block
                c.Pos = lex.Style(editor, c.Pos, endPos);
            }
            return ProcessDefaultState(editor, c);
        }
コード例 #25
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 public override int ProcessState(CodeEditor editor, int state, Region c, int endPos)
 {
     switch (state)
     {
         case (int)BaseState.Braces:
             return -1; // exit lexer
         case (int)State.Indicator:
             return ProcessIndicatorState(editor, c, (int)State.Indicator);
         case (int)BaseState.Number:
             return ProcessNumberState(editor, c);
     }
     return ProcessDefaultState(editor, c);
 }
コード例 #26
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
 private int ProcessPreprocessorState(CodeEditor editor, Region c)
 {
     if (c.c == '\n')
         return (int)State.Default;
     if (char.IsWhiteSpace(c.c))
         return (int)State.PreprocessorBody;
     return (int)State.Preprocessor;
 }
コード例 #27
0
ファイル: FXDebugger.cs プロジェクト: h3tch/ProtoFX
        /// <summary>
        /// Get debug variable from the specified text position in the code editor.
        /// </summary>
        /// <param name="editor">Source code editor.</param>
        /// <param name="position">Position in the code.</param>
        /// <returns>Returns the debug variable at the specified position or
        /// the default value if no debug variable could be found.</returns>
        public static DbgVar GetDebugVariableFromPosition(CodeEditor editor, int position)
        {
            // find all debug variables
            var vars = RegexDbgVar.Matches(editor.Text);

            for (int i = 0; i < vars.Count; i++)
            {
                var varLine = editor.LineFromPosition(vars[i].Index);
                // is the debug variable in the same line
                if (vars[i].Index <= position && position <= vars[i].Index + vars[i].Length)
                    return new DbgVar(i, vars[i].Index, varLine, vars[i].Value);
            }
            return null;
        }
コード例 #28
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        private int ProcessPreprocessorBodyState(CodeEditor editor, Region c)
        {
            // still inside the preprocessor body
            if (c.c != '\n')
                return (int)State.PreprocessorBody;

            // RE-LEX ALL PREPROCESSORCODE PARTS

            // get code region of the block
            var start = FindLastStyleOf(editor, StateToStyle((int)State.Preprocessor), c.Pos);
            // re-lex code block
            defaultLexer.Style(editor, start + 1, c.Pos);
            // continue styling from the last position
            editor.StartStyling(c.Pos);
            return (int)State.Default;
        }
コード例 #29
0
ファイル: App.Debug.cs プロジェクト: h3tch/ProtoFX
        /// <summary>
        /// Show variables of the currently selected line in the editor.
        /// </summary>
        /// <param name="editor"></param>
        private void UpdateDebugListView(CodeEditor editor)
        {
            // RESET DEBUG LIST VIEW
            debugListView.Clear();
            debugListView.AddColumn("X", 80);
            debugListView.AddColumn("Y", 80);
            debugListView.AddColumn("Z", 80);
            debugListView.AddColumn("W", 80);

            // if the code has been edited no debug information can
            // be shown, because debug variables might have been
            // added or removed, which leads to invalid debug output
            if ((editor.Parent as TabPage).Text.EndsWith("*"))
                return;

            // get debug variables of the line where the caret is placed
            var first = editor.LineFromPosition(editor.SelectionStart);
            var last = editor.LineFromPosition(editor.SelectionEnd);
            var dbgVars = FxDebugger.GetDebugVariablesFromLine(editor, first, last - first + 1);
            dbgVars.Select(Var => FxDebugger.GetDebugVariableValue(Var.ID, glControl.Frame - 1))
                   .ForEach(dbgVars, (Val, Var) => { if (Val != null) NewVariableItem(Var.Name, Val); });
            debugListView.Update();
        }
コード例 #30
0
ファイル: FXLexer.cs プロジェクト: h3tch/ProtoFX
        public void Fold(CodeEditor editor, int pos, int endPos)
        {
            // setup state machine
            var line = editor.LineFromPosition(pos);
            var lastLine = -1;
            var lastCharPos = line;
            var foldLevel = editor.Lines[line].FoldLevel;
            var textLength = editor.TextLength;
            const int DEFAULT_FOLD_LEVEL = 1024;

            // for each character
            for (var state = FoldState.Unknown;
                state == FoldState.Unknown ? pos < endPos : pos < textLength;
                pos++)
            {
                var c = (char)editor.GetCharAt(pos);

                switch (c)
                {
                    // open folding
                    case '{':
                        state = FoldState.StartFolding;
                        break;
                    // close folding
                    case '}':
                        state = FoldState.EndFolding;
                        break;
                    // next line
                    case '\n':
                        line++;
                        break;
                    // remember last character to place
                    // fold icon in the last character line
                    default:
                        if (char.IsLetterOrDigit(c))
                            lastCharPos = pos;
                        break;
                }

                switch (state)
                {
                    // STATE: open folding
                    case FoldState.StartFolding:
                        var lastCharLine = editor.LineFromPosition(lastCharPos);
                        // start folding at last character containing line
                        editor.Lines[lastCharLine].FoldLevelFlags = FoldLevelFlags.Header;
                        editor.Lines[lastCharLine].FoldLevel = foldLevel++;
                        // for all other lines up to the current position also add folding
                        for (int i = lastCharLine + 1; i <= line; i++)
                        {
                            editor.Lines[i].FoldLevelFlags = FoldLevelFlags.White;
                            editor.Lines[i].FoldLevel = foldLevel;
                        }
                        lastLine = line;
                        // switch to folding state
                        state = FoldState.Foldable;
                        break;
                    // STATE: close folding
                    case FoldState.EndFolding:
                        // end folding
                        editor.Lines[line].FoldLevel = foldLevel;
                        // decrease fold level
                        foldLevel = Math.Max(--foldLevel, DEFAULT_FOLD_LEVEL);
                        lastLine = line;
                        // switch to folding state (which will
                        // switch to unknown state if the most
                        // outer fold level is reached)
                        state = FoldState.Foldable;
                        break;
                    // STATE: folding
                    case FoldState.Foldable:
                        // still in folding state
                        if (foldLevel > DEFAULT_FOLD_LEVEL)
                        {
                            if (line != lastLine)
                            {
                                // set fold level for line
                                editor.Lines[line].FoldLevel = foldLevel;
                                lastLine = line;
                            }
                        }
                        // end folding state
                        else
                            state = FoldState.Unknown;
                        break;
                }
            }
        }