示例#1
0
        public void GenerateExistingResultForBranch(Generator generator, int branch)
        {
            MultipleValElement leftOperand = Child <MultipleValElement>(0);

            leftOperand.Child <GetVariableElement>(branch).ResultOfGeneration = GetVariableElement.GenerateOptions.Value;

            leftOperand.GenerateForBranch(generator, branch);
        }
示例#2
0
        /// <summary>
        /// Build expression value. It's called from ParseExpression
        /// </summary>
        /// <param name="lexemes">List of lexemes</param>
        /// <param name="pos">Position of current parsed lexeme</param>
        /// <param name="flags">Control flags. ExpressionFlags.None to ignore all flags</param>
        /// <param name="elem">Builded value element. null if it's not a value</param>
        /// <returns>Position of a next lexeme</returns>
        private int ParseExpressionValue(List <Lexeme> lexemes, int pos, ExpressionFlags flags, out ValueElement elem)
        {
            MultipleValElement multipleVals = new MultipleValElement();

            if (lexemes[pos].Source == "(")
            {
                List <ValueElement> values;

                pos = ExtractSeparatedExpressions(lexemes, pos, flags | ExpressionFlags.ForbidMultiple, out values);

                if (pos >= (lexemes.Count - 1))
                {
                    Compilation.WriteError("Unexpected end of file. Did you forget ')' and ';' ?", -1);
                }

                foreach (var i in values)
                {
                    multipleVals.AddValue(i);
                }
            } //"("
            else if (lexemes[pos].Code == Lexeme.CodeType.Number)
            {
                var val = new ConstValElement
                {
                    Type  = m_symbols.GetTypeOfConstVal(lexemes[pos].Source),
                    Value = lexemes[pos].Source
                };
                ++pos;
                elem = val;
                return(pos);
            }
            else if (m_currentFunction.HasVariable(lexemes[pos].Source) && lexemes[pos + 1].Source != "(")
            {
                var val = new GetVariableElement()
                {
                    VarName            = lexemes[pos].Source,
                    VarType            = m_currentFunction.GetVariable(lexemes[pos].Source).VarType,
                    ResultOfGeneration = GetVariableElement.GenerateOptions.Value
                };

                ++pos;
                elem = val;
                return(pos);
            }
            else if (m_symbols.HasFunctionWithName(lexemes[pos].Source))
            {
                FunctionCallElement callElement = new FunctionCallElement();

                string funcName = lexemes[pos].Source;

                ++pos;
                List <ValueElement> values;

                if (lexemes[pos + 1].Source == ")") //fucntion without arguments
                {
                    values = new List <ValueElement>();
                    pos   += 2; //'(' ')'
                }
                else
                {
                    pos = ExtractSeparatedExpressions(lexemes, pos,
                                                      flags | ExpressionFlags.AllowAutoDefault,
                                                      out values);
                }
                if (values.Count == 1 && values[0].NumberOfBranches > 1)
                {
                    values = values[0].Children().Select(child => (ValueElement)child).ToList();
                }

                callElement.FunctionInfo = m_symbols.GetFunction(
                    funcName,
                    values.Select(val => val?.ResultType.ResultTypes[0].Name).ToList());

                for (int i = 0, end = values.Count; i < end; ++i)
                {
                    if (values[i] == null)
                    {
                        values[i] = callElement.FunctionInfo.Arguments[i].DefaultVal;
                    }
                }

                callElement.CallArguments = values;

                elem = callElement;

                return(pos);
            }
            else if (lexemes[pos].Source == "default")
            {
                ++pos;

                if (lexemes[pos].Source == "(")
                {
                    Compilation.Assert(flags.HasFlag(ExpressionFlags.AllowDefaultValue),
                                       "Default type value keyword is used but it isn't allowed here.", lexemes[pos].Line);

                    ++pos;                                 //skip '('

                    string typeName = lexemes[pos].Source; //TODO: namespaces

                    ConstValElement constVal = m_symbols.GetDefaultVal(typeName);

                    elem = new ConstValElement {
                        Type = constVal.Type, Value = constVal.Value
                    };

                    ++pos;
                    ++pos; //skip ')'
                }
                else
                {
                    Compilation.Assert(flags.HasFlag(ExpressionFlags.AllowAutoDefault),
                                       "Auto default keyword is used but it isn't allowed here.", lexemes[pos].Line);
                    elem = null;
                }

                return(pos);
            }
            else //Not a value
            {
                elem = null;
                return(pos);
            }

            elem = multipleVals;
            return(pos);
        }
示例#3
0
        /// <summary>
        /// Build expression element
        /// </summary>
        /// <param name="lexemes">List of lexemes</param>
        /// <param name="pos">Position of current parsed lexeme</param>
        /// <param name="endPos">Position at which function breaks. Pass -1 to parse until the end</param>
        /// <param name="flags">Control flags. ExpressionFlags.None to ignore all flags</param>
        /// <param name="elem"></param>
        /// <returns>Position of a next lexeme</returns>
        private int ParseExpression(List <Lexeme> lexemes, int pos, int endPos,
                                    ExpressionFlags flags,
                                    out ValueElement elem)
        {
            OperationElement lastOperation  = null;
            OperationElement rootOperation  = null;
            ValueElement     lastValElement = null;

            bool breakCycle = false;

            if (endPos == -1)
            {
                endPos = lexemes.Count;
            }

            for (int end = endPos; !breakCycle && pos < end;)
            {
                var currentLexeme = lexemes[pos];

                switch (currentLexeme.Source)
                {
                case ")":
                case ";":
                case "{":
                case "}":
                    breakCycle = true;
                    continue;

                case ",":
                    Compilation.WriteError("Unexpected symbol: ','." +
                                           "Did you forget '(' ?\nExample: '( SYMBOLS, SYMBOLS )'.",
                                           lexemes[pos].Line);
                    continue;

                case "+":
                case "-":
                case "*":
                case "/":
                case "^":
                case "=":
                {
                    if (lastValElement == null && lastOperation == null)
                    {
                        if (lexemes[pos].Source == "-")
                        {
                            rootOperation = lastOperation = new UnaryMinusElement();
                            ++pos;
                            continue;
                        }
                        else
                        {
                            Compilation.WriteError("Expected value or expression before '"
                                                   + lexemes[pos].Source + "'", lexemes[pos].Line);
                        }
                    }

                    OperationElement operation = null;
                    switch (lexemes[pos].Source)
                    {
                    case "+":
                        operation = new BinaryPlusElement();
                        break;

                    case "-":
                        operation = new BinaryMinusElement();
                        break;

                    case "*":
                        operation = new BinaryMultiplicationElement();
                        break;

                    case "/":
                        operation = new BinaryDivisionElement();
                        break;

                    case "^":
                        operation = new BinaryExponentiationElement();
                        break;

                    case "=":
                    {
                        operation = new CopyElement();

                        if (lastValElement != null)
                        {
                            if (!(lastValElement is MultipleValElement))
                            {
                                var multiple = new MultipleValElement();
                                multiple.AddValue(lastValElement);
                                lastValElement = multiple;
                            }
                        }
                        else
                        {
                            if (lastOperation != null)
                            {
                                var valElem = lastOperation.Child(1);
                                if (!(valElem is MultipleValElement))
                                {
                                    var multiple = new MultipleValElement();
                                    multiple.AddValue((ValueElement)valElem);

                                    lastOperation.SetChild(1, valElem);
                                }
                            }
                            else
                            {
                                Compilation.WriteError("Expected value before '='", -1);
                            }
                        }
                    }
                    break;

                    default:
                        Compilation.WriteCritical("BUG: Unknown operator passed through the switch");
                        break;
                    }

                    if (lastOperation == null)
                    {
                        operation.SetChild(0, lastValElement);
                        lastValElement = null;
                        rootOperation  = operation;
                    }
                    else
                    {
                        InsertOperationInTree(ref lastOperation, ref operation, ref rootOperation);
                    }

                    lastOperation = operation;
                }
                    ++pos;
                    break;

                default:
                    pos = ParseExpressionValue(lexemes, pos, flags | ExpressionFlags.AllowDefaultValue
                                               & (~ExpressionFlags.OperationRequired),
                                               out lastValElement);
                    if (lastValElement == null)
                    {
                        if (!flags.HasFlag(ExpressionFlags.AllowAutoDefault))
                        {
                            Compilation.WriteError("Unknown symbol: '" + currentLexeme.Source + "'.",
                                                   currentLexeme.Line);
                        }
                        else     //used default keyword. Caller have to find result
                        {
                            elem = null;
                            return(pos);
                        }
                    }
                    else
                    {
                        if (lastOperation != null)
                        {
                            InsertValInTree(lastOperation, lastValElement);
                            lastValElement = null;
                        }
                    }
                    break;
                }
            }

            if (rootOperation == null)
            {
                if (flags.HasFlag(ExpressionFlags.OperationRequired) && !(lastValElement is FunctionCallElement))
                {
                    Compilation.WriteError("Expression must contain at least one operator", lexemes[pos].Line);
                }
                if (lastValElement == null)
                {
                    Compilation.WriteError("No operation or value in expression", lexemes[pos].Line);
                }
                elem = lastValElement;
            }
            else
            {
                elem = rootOperation;
            }

            return(pos);
        }