예제 #1
0
 /// <summary>
 /// Evaluates a math expression of 2 time spans.
 /// </summary>
 /// <param name="node">The AST node the evaluation is a part of.</param>
 /// <param name="lhs">The time on the left hand side</param>
 /// <param name="rhs">The time on the right hand side</param>
 /// <param name="op">The math operator.</param>
 /// <returns></returns>
 public static LBool CompareTimes(AstNode node, LTime lhs, LTime rhs, Operator op)
 {
     var left = lhs.Value;
     var right = rhs.Value;
     var result = false;
     if (op == Operator.LessThan)             result = left < right;
     else if (op == Operator.LessThanEqual)   result = left <= right;
     else if (op == Operator.MoreThan)        result = left > right;
     else if (op == Operator.MoreThanEqual)   result = left >= right;
     else if (op == Operator.EqualEqual)      result = left == right;
     else if (op == Operator.NotEqual)        result = left != right;
     return new LBool(result);
 }
예제 #2
0
        private MatchResult CheckExpressionMatches(CompilerPlugin plugin, List<TokenMatch> matches, Dictionary<string, object> args, int peekCount, int matchCount)
        {
            var isMatch = true;
            var token = peekCount == 0 ? this.TokenIt.NextToken : this.TokenIt.Peek(peekCount);
            var totalMatched = matchCount;
            
            foreach (var match in matches)
            {
                var continueCheck = false;
                var trackNamedArgs = true;
                var valueMatched = false;

                // Termninators
                if (match.TokenType == "@exprTerminators" 
                    && ( Terminators.ExpFlexibleEnd.ContainsKey(token.Token) || Terminators.ExpThenEnd.ContainsKey(token.Token) ) 
                    )
                {
                    // Don't increment the peekcount
                    isMatch = totalMatched >= plugin.TotalRequiredMatches;
                    break;
                }
                // Check for ";" and EOF ( end of file/text )
                if (token.Token == Tokens.Semicolon || token.Token == Tokens.EndToken)
                {
                    isMatch = totalMatched >= plugin.TotalRequiredMatches;
                    break;
                }

                // Check 1: Group tokens ?
                if(match.IsGroup)
                {
                    var submatches = ((TokenGroup) match).Matches;
                    var result = CheckExpressionMatches(plugin, submatches, args, peekCount, totalMatched);
                    if(match.IsRequired && !result.Success)
                    {
                        isMatch = false;
                        break;
                    }
                    if(result.Success)
                    {
                        peekCount = result.TokenCount;
                        if(match.IsRequired)
                            totalMatched += result.TotalMatched;
                    }
                }
                // Check 2: starttoken?
                else if (match.TokenType == "@starttoken")
                {
                    continueCheck = true;
                    totalMatched++;
                }
                // Check 2a: tokenmap1
                else if (match.TokenType == "@tokenmap1")
                {
                    if (plugin.TokenMap1 == null || !plugin.TokenMap1.ContainsKey(token.Token.Text))
                    {
                        isMatch = false;
                        break;
                    }
                    continueCheck = true;
                    totalMatched++;
                }
                else if (match.TokenType == "@tokenmap2")
                {
                    if (plugin.TokenMap2 == null || !plugin.TokenMap2.ContainsKey(token.Token.Text))
                    {
                        isMatch = false;
                        break;
                    }
                    continueCheck = true;
                    totalMatched++;
                }
                // Check 2c: "identSymbol" must exist
                else if (match.TokenType == "@identsymbol")
                {
                    var symbolExists = this.Symbols.Contains(token.Token.Text);
                    continueCheck = symbolExists;
                    if (!continueCheck)
                    {
                        isMatch = false;
                        break;
                    }
                    totalMatched++;
                }
                // Check 2c: "identSymbol" must exist
                else if (match.TokenType == "@singularsymbol")
                {
                    var plural = token.Token.Text + "s";
                    var symbolExists = this.Symbols.Contains(plural);
                    continueCheck = symbolExists;
                    if (!continueCheck)
                    {
                        isMatch = false;
                        break;
                    }
                    totalMatched++;
                }
                // Check 2d: paramlist = @word ( , @word )* parameter names
                else if(match.TokenType == "@paramnames")
                {
                    var isvalidParamList = true;
                    var maxParams = 10;
                    var totalParams = 0;
                    var paramList = new List<object>();

                    while(totalParams <= maxParams)
                    {
                        var token2 = this.TokenIt.Peek(peekCount, false);
                        if(token2.Token == Tokens.Comma)
                        {
                            peekCount++;
                        }
                        else if(token2.Token.Kind == TokenKind.Ident)
                        {
                            paramList.Add(token2.Token.Text);
                            peekCount++;
                        }
                        else
                        {
                            peekCount--;
                            break;
                        }
                        totalParams++;
                    }
                    isMatch = isvalidParamList;
                    continueCheck = isMatch;
                    if (continueCheck)
                    {
                        trackNamedArgs = false;
                        if(!string.IsNullOrEmpty(match.Name))
                        {
                            args[match.Name] = token;
                            args[match.Name + "Value"] = new LArray(paramList);
                        }
                        totalMatched++;
                    }
                    else
                    {
                        break;
                    }
                }
                // Check 3a: Optional words with text
                else if (!match.IsRequired && match.Text != null && match.Text != token.Token.Text)
                {
                    continueCheck = false;
                }
                // Check 3b: Optional words matched
                else if (!match.IsRequired && match.IsMatchingValue(token.Token))
                {
                    continueCheck = true;
                }
                // Check 4: Optional word not matched
                else if (!match.IsRequired && !match.IsMatchingValue(token.Token))
                {
                    continueCheck = false;
                }
                // Check 5a: Expected word
                else if (match.IsRequired && match.TokenType == null && match.Text == token.Token.Text)
                {
                    continueCheck = true;
                    totalMatched++;
                }
                // Check 5b: Expected word in list
                else if (match.IsRequired && match.TokenType == null && match.Values != null)
                {
                    if (!match.IsMatchingValue(token.Token))
                    {
                        isMatch = false;
                        break;
                    }
                    continueCheck = true;
                    valueMatched = true;
                    totalMatched++;
                }
                // Check 6: check the type of n1
                else if (match.IsMatchingType(token.Token))
                {
                    continueCheck = true;
                    totalMatched++;
                }
                else
                {
                    isMatch = false;
                    break;
                }
                if (continueCheck)
                {
                    if (!string.IsNullOrEmpty(match.Name) && trackNamedArgs)
                    {
                        args[match.Name] = token; 
                        if(match.TokenPropEnabled)
                        {
                            // 1. figure out which token map to use.
                            var lookupmap = plugin.StartTokenMap;

                            if (match.TokenType == "@tokenmap1")
                                lookupmap = plugin.TokenMap1;
                            else if (match.TokenType == "@tokenmap2")
                                lookupmap = plugin.TokenMap2;

                            // Case 1: Start token replacement value
                            if (match.TokenPropValue == "value")
                            {
                                var startToken = token.Token.Text;
                                args[match.Name + "Value"] = lookupmap[startToken];
                            }
                            // Case 2: Token value
                            else if (match.TokenPropValue == "tvalue")
                            {
                                LObject val = LObjects.Null;
                                if (match.TokenType == "@number")
                                    val = new LNumber((double)token.Token.Value);
                                else if (match.TokenType == "@time")
                                    val = new LTime((TimeSpan)token.Token.Value);
                                else if (match.TokenType == "@word")
                                    val = new LString((string)token.Token.Value);
                                else if (match.TokenType == "@starttoken")
                                    val = new LString(token.Token.Text);
                                args[match.Name + "Value"] = val;
                            }
                            // Case 2: Token value
                            else if (match.TokenPropValue == "tvaluestring")
                            {
                                LObject val = LObjects.Null;
                                if (match.TokenType == "@number")
                                    val = new LString(((double)token.Token.Value).ToString(CultureInfo.InvariantCulture));
                                else if (match.TokenType == "@time")
                                    val = new LString(((TimeSpan)token.Token.Value).ToString());
                                else if (match.TokenType == "@starttoken")
                                    val = new LString(token.Token.Text);
                                else if (match.TokenType == "@word")
                                    val = new LString(token.Token.Text);
                                else if (match.TokenType == "@singularsymbol")
                                    val = new LString(token.Token.Text);
                                args[match.Name + "Value"] = val;
                            }
                        }
                        // matching values
                        else if(valueMatched)
                        {
                            args[match.Name + "Value"] = token.Token.Text;
                        }
                    }
                    // Matched: increment.
                    peekCount++;
                    token = this.TokenIt.Peek(peekCount, false);
                }
            }
            var res = new MatchResult(isMatch, null, args);
            res.TotalMatched = totalMatched;
            res.TokenCount = peekCount;
            return res;
        }
예제 #3
0
        /// <summary>
        /// Evaluates a math expression of 2 time spans.
        /// </summary>
        /// <param name="node">The AST node the evaluation is a part of.</param>
        /// <param name="lhs">The time on the left hand side</param>
        /// <param name="rhs">The time on the right hand side</param>
        /// <param name="op">The math operator.</param>
        /// <returns></returns>
        public static LTime CalcTimes(AstNode node, LTime lhs, LTime rhs, Operator op)
        {
            if (op != Operator.Add && op != Operator.Subtract)
                throw ExceptionHelper.BuildRunTimeException(node, "Can only add/subtract times");

            var left = lhs.Value;
            var right = rhs.Value;
            var result = TimeSpan.MinValue;
            if (op == Operator.Add)
            {
                result = left + right;
            }
            else if (op == Operator.Subtract)
            {
                result = left - right;
            }
            return new LTime(result);
        }