Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Expression Thingy</title>
  <style>
    .good {
      color: green;
    }
    .bad {
      color: #d22;
    }
  </style>
</head>
<body>
  <script>
    (function() {
      var array = ["red", "blue", "neon", "black", "orange"];
      var tests = [
        {expr: "red&&blue",                 expect: true},
        {expr: "blue&&white",               expect: false},
        {expr: "red,white",                 expect: true},
        {expr: "(red&&blue),(red&&white)",  expect: true},
        {expr: "(red&&blue)&&(red&&white)", expect: false},
        {expr: "(red&&blue)&&(red&&neon)",  expect: true},
        {expr: "(red+blue)&&(red!neon)",    expectInvalid: true}
      ];
      var data;
      
      // Turn data into an object with named properties, to make lookups
      // faster
      data = {};
      array.forEach(function(entry) {
        data[entry] = true;
      });
      
      // Run the tests
      tests.forEach(runTest);
      
      function runTest(test) {
        var parts, invalid = false;
        
        // Get an array of tokens: We'll get `(`, `)`, `,`, `&&`, whitespace, or a name in each array slot
        parts = test.expr.match(/&&|,|\(|\)|\s+|[^()&,]+/g);
        
        // Validate the operators and turn the names into "true" or "false"
        parts.forEach(function(part, index) {
          switch (part) {
            case ",":
              // Valid operator, replace with ||
              parts[index] = "||";
              break;
            case "&&":
            case "(":
            case ")":
              // Valid operator
              break;
            default:
              // Name or whitespace
              if (!part.replace(/\s+/g, "")) {
                // Whitespace
              }
              else {
                // Name, validate it -- obviously apply whatever rule works
                // for your data, the rule below allows A-Z, $, and _ in
                // the first position and those plus digits in subsequent
                // positions.
                if (!/^[A-Za-z$_][A-Za-z0-9$_]*$/.test(part)) {
                  // Invalid
                  display("Invalid name: " + part, test.expectInvalid);
                  invalid = true;
                }
                else {
                  // Valid, replace it
                  parts[index] = data[part] ? "true" : "false";
                }
              }
              break;
          }
        });
        if (!invalid) {
          // Now we know parts only has valid stuff we can trust in it, rejoin
          // and eval it
          result = !!eval(parts.join(""));
          display(test.expr + ": Got " + result + ", expected " + test.expect, result === test.expect);
        }
      }
      
      function display(msg, good) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        if (typeof good !== "undefined") {
          p.className = good ? "good" : "bad";
        }
        document.body.appendChild(p);
      }
    })();
</script>
</body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers