Exemplo n.º 1
0
        public static string HtmlFormatRowParam(ParseFlag flags, string text)
        {
            var image = ParseFlag.Input.ToString();

            if (flags.HasFlag(ParseFlag.InputOutput))
            {
                image = ParseFlag.InputOutput.ToString();
            }
            else if (flags.HasFlag(ParseFlag.Output))
            {
                image = ParseFlag.Output.ToString();
            }
            else if (flags.HasFlag(ParseFlag.Return))
            {
                image = ParseFlag.Return.ToString();
            }
            return("<div class='ToolTipRowWithImg'><img style='padding-right: 2px; padding-left: 5px;' src='" + image + "' height='15px'>" + text + "</div>");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Analyse a preprocessed directive (analyses the whole statement)
        /// This method does not use the MoveNext because we don't want to analyse the words in a preprocess directive
        /// (in case of a scope-define we will analyse the words in the variable value when we actually use the variable,
        /// and in the other directive the words are garbage)
        /// </summary>
        private ParsedScopePreProcBlock CreateParsedPreProcDirective(Token directiveToken)
        {
            ParsedScopePreProcBlock newBlock = null;

            // info we will extract from the current statement :
            string        variableName = null;
            StringBuilder definition   = new StringBuilder();

            var count = 0;

            while (true)
            {
                count++;
                // need to replace in case we use for instance a {&var} in a scope-define value
                ReplaceIncludeAndPreprocVariablesAhead(count);
                var token = PeekAt(count);
                if (token is TokenEof)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                // a ~ allows for a eol but we don't control if it's an eol because if it's something else we probably parsed it wrong anyway (in the lexer)
                if (token is TokenSymbol && token.Value == "~")
                {
                    if (PeekAt(count + 1) is TokenEol)
                    {
                        count++;
                    }
                    continue;
                }
                if (token is TokenEol)
                {
                    break;
                }

                // read the first word after the directive
                if (string.IsNullOrEmpty(variableName) && token is TokenWord)
                {
                    variableName = token.Value;
                    continue;
                }

                definition.Append(token.Value);
            }

            ParseFlag flags = 0;

            // match first word of the statement
            switch (directiveToken.Value.ToUpper())
            {
            case "&GLOBAL-DEFINE":
            case "&GLOBAL":
            case "&GLOB":
                flags |= ParseFlag.Global;
                break;

            case "&SCOPED-DEFINE":
            case "&SCOPED":
                flags |= ParseFlag.FileScope;
                break;

            case "&ANALYZE-SUSPEND":
                // we don't care about the blocks of include files
                if (directiveToken.OwnerNumber > 0)
                {
                    break;
                }

                // it marks the beginning of an appbuilder block, it can only be at a root/File level, otherwise flag error
                if (!(GetCurrentBlock <ParsedScopeBlock>() is ParsedFile))
                {
                    _parserErrors.Add(new ParserError(ParserErrorType.NotAllowedUibBlockStart, directiveToken, _context.BlockStack.Count, _parsedIncludes));
                }

                // we match a new block start but we didn't match the previous block end, flag error
                if (GetCurrentBlock <ParsedScopePreProcBlock>() != null)
                {
                    _parserErrors.Add(new ParserError(ParserErrorType.UnexpectedUibBlockStart, directiveToken, _context.BlockStack.Count, _parsedIncludes));
                }

                // matching different intersting blocks
                var textAfterDirective      = variableName + " " + definition.ToString().Trim();
                ParsedPreProcBlockType type = ParsedPreProcBlockType.Block;
                string blockName            = "Appbuilder block";
                if (textAfterDirective.ContainsFast("_FUNCTION-FORWARD"))
                {
                    type      = ParsedPreProcBlockType.Prototype;
                    blockName = "Function prototype";
                }
                else if (textAfterDirective.ContainsFast("_MAIN-BLOCK"))
                {
                    type      = ParsedPreProcBlockType.MainBlock;
                    blockName = "Main block";
                }
                else if (textAfterDirective.ContainsFast("_DEFINITIONS"))
                {
                    type      = ParsedPreProcBlockType.DefinitionBlock;
                    blockName = "Definitions";
                }
                else if (textAfterDirective.ContainsFast("_UIB-PREPROCESSOR-BLOCK"))
                {
                    type      = ParsedPreProcBlockType.UibPreprocessorBlock;
                    blockName = "Pre-processor definitions";
                }
                else if (textAfterDirective.ContainsFast("_XFTR"))
                {
                    type      = ParsedPreProcBlockType.XtfrBlock;
                    blockName = "Xtfr";
                }
                else if (textAfterDirective.ContainsFast("_PROCEDURE-SETTINGS"))
                {
                    type      = ParsedPreProcBlockType.SettingsBlock;
                    blockName = "Procedure settings";
                }
                else if (textAfterDirective.ContainsFast("_CREATE-WINDOW"))
                {
                    type      = ParsedPreProcBlockType.CreateWindowBlock;
                    blockName = "Window settings";
                }
                else if (textAfterDirective.ContainsFast("_RUN-TIME-ATTRIBUTES"))
                {
                    type      = ParsedPreProcBlockType.RuntimeBlock;
                    blockName = "Runtime attributes";
                }

                newBlock = new ParsedScopePreProcBlock(blockName, directiveToken)
                {
                    Type             = type,
                    BlockDescription = textAfterDirective
                };

                // save the block description
                AddParsedItem(newBlock, directiveToken.OwnerNumber);
                break;

            case "&UNDEFINE":
                if (variableName != null)
                {
                    var found = (ParsedPreProcVariable)_parsedItemList.FindLast(item => (item is ParsedPreProcVariable && item.Name.Equals(variableName)));
                    if (found != null)
                    {
                        found.UndefinedLine = _context.CurrentStatement.FirstToken.Line;
                    }
                }
                break;
            }

            // We matched a new preprocessed variable?
            if (flags > 0 && !string.IsNullOrEmpty(variableName))
            {
                var newVar = new ParsedPreProcVariable(variableName, directiveToken, 0, definition.ToString().Trim())
                {
                    Flags = flags
                };
                AddParsedItem(newVar, directiveToken.OwnerNumber);

                // add it to the know variables (either to the global scope or to the local scope)
                SetPreProcVariableValue(flags.HasFlag(ParseFlag.Global) ? 0 : directiveToken.OwnerNumber, variableName, newVar.Value);
            }

            // we directly set the new token position there (it will be the EOL after this directive)
            _tokenPos += count;

            AddLineInfo(PeekAt(0));

            // since we didn't use MoveNext we also manually replace the includes ahead
            ReplaceIncludeAndPreprocVariablesAhead(1);
            ReplaceIncludeAndPreprocVariablesAhead(2);

            return(newBlock);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a parsed item for RUN statements
        /// </summary>
        /// <param name="runToken"></param>
        private void CreateParsedRun(Token runToken)
        {
            /*
             * RUN
             * {   extern-proc-name
             | VALUE ( extern-expression )
             | path-name<<member-name>>
             | }
             | [ PERSISTENT | SINGLE-RUN | SINGLETON [ SET proc-handle]]
             | [ ON [ SERVER ] {server-handle | session-handle }
             |       [ TRANSACTION DISTINCT ]
             |       [ ASYNCHRONOUS
             |          [ SET async-request-handle]
             |          [ EVENT-PROCEDURE event-internal-procedure
             |              [ IN procedure-context]]
             |       ]
             | ]
             | [ ( parameter[ , parameter]... ) ]
             | [ argument ]...
             | [ NO-ERROR ]
             |
             | RUN
             | { intern-proc-name | VALUE ( intern-expression) }
             | [ IN proc-handle]
             | [ ASYNCHRONOUS
             |     [ SET async-request-handle]
             |     [ EVENT-PROCEDURE event-internal-procedure
             |         [ IN procedure-context]]
             | ]
             | [ ( parameter[ , parameter]... ) ]
             | [ NO-ERROR ]
             |
             | RUN portTypeName[ SET hPortType ] ON SERVER hWebService[ NO-ERROR ] .
             |
             | RUN operationName IN hPortType
             | [ ASYNCHRONOUS
             |  [ SET async-request-handle]
             |  [ EVENT-PROCEDURE event-internal-procedure
             |     [ IN procedure-context]]
             | [ ( parameter[ , parameter]... ) ]
             | [ NO-ERROR ].
             |
             |
             | RUN SUPER [ ( parameter[ , parameter]... ) ][ NO-ERROR ]
             |
             | TODO :
             | RUN STORED-PROCEDURE procedure
             | [integer-field = PROC-HANDLE ]
             | [ NO-ERROR ]
             | [ ( parameter[ , parameter]... ) ]
             |
             */

            // info we will extract from the current statement :
            string    name = "";
            ParseFlag flag = 0;

            _lastTokenWasSpace = true;
            int state = 0;

            do
            {
                var token = PeekAt(1); // next token
                if (state == 2)
                {
                    break;             // stop after finding the RUN name to be able to match other words in the statement
                }
                if (token is TokenEos)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                switch (state)
                {
                case 0:
                    // matching proc name (or VALUE)
                    if (token is TokenSymbol && token.Value.Equals(")"))
                    {
                        state++;
                    }
                    else if (flag.HasFlag(ParseFlag.Uncertain) && !(token is TokenWhiteSpace || token is TokenSymbol))
                    {
                        name += GetTokenStrippedValue(token);
                    }
                    else if (token is TokenWord)
                    {
                        if (token.Value.ToLower().Equals("value"))
                        {
                            flag |= ParseFlag.Uncertain;
                        }
                        else
                        {
                            name += token.Value;
                            state++;
                        }
                    }
                    else if (token is TokenString)
                    {
                        name = GetTokenStrippedValue(token);
                        state++;
                    }
                    break;

                case 1:
                    // matching PERSISTENT (or a path instead of a file)
                    if (token is TokenSymbol && (token.Value.Equals("/") || token.Value.Equals("\\")))
                    {
                        // if it's a path, append it to the name of the run
                        name += token.Value;
                        state = 0;
                        break;
                    }
                    if (!(token is TokenWord))
                    {
                        break;
                    }
                    if (token.Value.EqualsCi("persistent"))
                    {
                        flag |= ParseFlag.Persistent;
                    }
                    state++;
                    break;
                }
            } while (MoveNext());

            if (state == 0)
            {
                return;
            }
            AddParsedItem(new ParsedRun(name, runToken, null)
            {
                Flags = flag
            }, runToken.OwnerNumber);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Matches a function definition (not the FORWARD prototype)
        /// </summary>
        private ParsedFunction CreateParsedFunction(Token functionToken)
        {
            // info we will extract from the current statement :
            string               name             = null;
            string               parsedReturnType = null;
            string               extend           = null;
            ParseFlag            flags            = 0;
            StringBuilder        parameters       = new StringBuilder();
            List <ParsedDefine>  parametersList   = null;
            ParsedImplementation createdImp       = null;

            _lastTokenWasSpace = true;

            Token token;
            int   state = 0;

            do
            {
                token = PeekAt(1); // next token
                if (token is TokenEos)
                {
                    break;
                }
                if (token is TokenComment)
                {
                    continue;
                }
                switch (state)
                {
                case 0:
                    // matching name
                    if (!(token is TokenWord))
                    {
                        break;
                    }
                    name = token.Value;
                    state++;
                    break;

                case 1:
                    // matching return type
                    if (!(token is TokenWord))
                    {
                        break;
                    }
                    if (token.Value.EqualsCi("returns") || token.Value.EqualsCi("class"))
                    {
                        continue;
                    }

                    parsedReturnType = token.Value;

                    state++;
                    break;

                case 2:
                    // matching parameters (start)
                    if (token is TokenWord)
                    {
                        if (token.Value.EqualsCi("private"))
                        {
                            flags |= ParseFlag.Private;
                        }
                        if (token.Value.EqualsCi("extent"))
                        {
                            flags |= ParseFlag.Extent;
                        }

                        // we didn't match any opening (, but we found a forward
                        if (token.Value.EqualsCi("forward"))
                        {
                            state = 99;
                        }
                        else if (token.Value.EqualsCi("in"))
                        {
                            state = 100;
                        }
                    }
                    else if (token is TokenSymbol && token.Value.Equals("("))
                    {
                        state = 3;
                    }
                    else if (flags.HasFlag(ParseFlag.Extent) && token is TokenNumber)
                    {
                        extend = token.Value;
                    }
                    break;

                case 3:
                    // read parameters, define a ParsedDefineItem for each
                    parametersList = GetParsedParameters(functionToken, parameters);
                    state          = 10;
                    break;

                case 10:
                    // matching prototype, we dont want to create a ParsedItem for prototype
                    if (token is TokenWord)
                    {
                        if (token.Value.EqualsCi("forward"))
                        {
                            state = 99;
                        }
                        else if (token.Value.EqualsCi("in"))
                        {
                            state = 100;
                        }
                    }
                    break;
                }
            } while (MoveNext());
            if (name == null || parsedReturnType == null)
            {
                return(null);
            }

            // otherwise it needs to ends with : or .
            if (!(token is TokenEos))
            {
                return(null);
            }



            // New prototype, we matched a forward or a IN
            if (state >= 99)
            {
                ParsedPrototype createdProto = new ParsedPrototype(name, functionToken, parsedReturnType)
                {
                    Scope            = GetCurrentBlock <ParsedScopeBlock>(),
                    FilePath         = FilePathBeingParsed,
                    SimpleForward    = state == 99, // allows us to know if we expect an implementation in this .p or not
                    EndPosition      = token.EndPosition,
                    EndBlockLine     = token.Line,
                    EndBlockPosition = token.EndPosition,
                    Flags            = flags,
                    Extend           = extend,
                    ParametersString = parameters.ToString()
                };
                if (!_functionPrototype.ContainsKey(name))
                {
                    _functionPrototype.Add(name, createdProto);
                }

                AddParsedItem(createdProto, functionToken.OwnerNumber);

                // case of a IN
                if (!createdProto.SimpleForward)
                {
                    // add the parameters to the list
                    if (parametersList != null)
                    {
                        createdProto.Parameters = new List <ParsedDefine>();
                        foreach (var parsedItem in parametersList)
                        {
                            createdProto.Parameters.Add(parsedItem);
                        }
                    }
                }
            }
            else
            {
                // New function
                createdImp = new ParsedImplementation(name, functionToken, parsedReturnType)
                {
                    EndPosition      = token.EndPosition,
                    Flags            = flags,
                    Extend           = extend,
                    ParametersString = parameters.ToString()
                };

                // it has a prototype?
                if (_functionPrototype.ContainsKey(name))
                {
                    // make sure it was a prototype!
                    var proto = _functionPrototype[name] as ParsedPrototype;
                    if (proto != null && proto.SimpleForward)
                    {
                        createdImp.HasPrototype         = true;
                        createdImp.PrototypeLine        = proto.Line;
                        createdImp.PrototypeColumn      = proto.Column;
                        createdImp.PrototypePosition    = proto.Position;
                        createdImp.PrototypeEndPosition = proto.EndPosition;

                        // boolean to know if the implementation matches the prototype
                        createdImp.PrototypeUpdated = (
                            createdImp.Flags == proto.Flags &&
                            createdImp.Extend.EqualsCi(proto.Extend) &&
                            createdImp.TempReturnType.EqualsCi(proto.TempReturnType) &&
                            createdImp.ParametersString.EqualsCi(proto.ParametersString));
                    }
                }
                else
                {
                    _functionPrototype.Add(name, createdImp);
                }

                // add the parameters to the list
                if (parametersList != null)
                {
                    createdImp.Parameters = new List <ParsedDefine>();
                    foreach (var parsedItem in parametersList)
                    {
                        createdImp.Parameters.Add(parsedItem);
                    }
                }

                AddParsedItem(createdImp, functionToken.OwnerNumber);
            }

            return(createdImp);
        }