Browse Source

Fixing binary operator precedence

Sebastien Ros 12 years ago
parent
commit
fb7f6dfeb9

+ 10 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -521,6 +521,16 @@ namespace Jint.Tests.Runtime
             ");
             ");
         }
         }
 
 
+        [Theory]
+        [InlineData(true, "'ab' == 'a' + 'b'")]
+        public void OperatorsPrecedence(object expected, string source)
+        {
+            var engine = new Engine();
+            var result = engine.GetValue(engine.Execute(source));
+
+            Assert.Equal(expected, result);
+        }
+
         [Fact]
         [Fact]
         public void FunctionPrototypeShouldHaveApplyMethod()
         public void FunctionPrototypeShouldHaveApplyMethod()
         {
         {

+ 4 - 4
Jint/Parser/JavascriptParser.cs

@@ -2564,12 +2564,12 @@ namespace Jint.Parser
             var markers = new Stack<LocationMarker>( new [] {marker, CreateLocationMarker()});
             var markers = new Stack<LocationMarker>( new [] {marker, CreateLocationMarker()});
             Expression right = ParseUnaryExpression();
             Expression right = ParseUnaryExpression();
 
 
-            var stack = new Stack<object>( new object[] {left, token, right});
+            var stack = new List<object>( new object[] {left, token, right});
 
 
             while ((prec = binaryPrecedence(_lookahead, previousAllowIn)) > 0)
             while ((prec = binaryPrecedence(_lookahead, previousAllowIn)) > 0)
             {
             {
                 // Reduce: make a binary expression from the three topmost entries.
                 // Reduce: make a binary expression from the three topmost entries.
-                while ((stack.Count > 2) && (prec <= ((Token) stack.ElementAt(stack.Count - 2)).Precedence))
+                while ((stack.Count > 2) && (prec <= ((Token) stack[stack.Count - 2]).Precedence))
                 {
                 {
                     right = (Expression) stack.Pop();
                     right = (Expression) stack.Pop();
                     var op = (string) ((Token) stack.Pop()).Value;
                     var op = (string) ((Token) stack.Pop()).Value;
@@ -2599,11 +2599,11 @@ namespace Jint.Parser
 
 
             // Final reduce to clean-up the stack.
             // Final reduce to clean-up the stack.
             int i = stack.Count - 1;
             int i = stack.Count - 1;
-            expr = (Expression) stack.ElementAt(i);
+            expr = (Expression) stack[i];
             markers.Pop();
             markers.Pop();
             while (i > 1)
             while (i > 1)
             {
             {
-                expr = CreateBinaryExpression((string) ((Token) stack.ElementAt(i - 1)).Value, expr, (Expression) stack.ElementAt(i - 2));
+                expr = CreateBinaryExpression((string) ((Token) stack[i - 1]).Value, (Expression) stack[i - 2], expr);
                 i -= 2;
                 i -= 2;
                 marker = markers.Pop();
                 marker = markers.Pop();
                 if (marker != null)
                 if (marker != null)

+ 13 - 0
Jint/Parser/ParserExtensions.cs

@@ -19,5 +19,18 @@ namespace Jint.Parser
 
 
             return source[index];
             return source[index];
         }
         }
+
+        public static T Pop<T>(this List<T> list)
+        {
+            var lastIndex = list.Count - 1;
+            var last = list[lastIndex];
+            list.RemoveAt(lastIndex);
+            return last;
+        }
+
+        public static void Push<T>(this List<T> list, T item)
+        {
+            list.Add(item);
+        }
     }
     }
 }
 }