Implement the stack based interpreter from the leg_c branch.

cc @tobi, @Shopify/liquid 

This is a ruby port of the C expression parser from the [leg_c branch](https://github.com/Shopify/liquid/compare/leg_c) that parses the expression into a list of instructions for a stack based interpreter.

Here is the reference implementation in the leg_c branch:
* [stack based interpreter](https://github.com/Shopify/liquid/blob/0c6bc2b2a390f1c6815f17ff7645823a2e4329f4/lib/liquid/context.rb#L138-L171)
* [parser definition](https://github.com/Shopify/liquid/blob/leg_c/ext/liquid/liquid_context.leg)

Note that I removed a [test_descent_hash_descent test](https://github.com/Shopify/liquid/blob/0c6bc2b2a390f1c6815f17ff7645823a2e4329f4/test/liquid/parser_test.rb#L86-L87) for parsing `variable1[test1[test2]]` since the Liquid::VariableParser regex will ignore the last close square bracket character, so this is an existing bug that I don't indent to fix here.

## Benchmarks

ran twice on master

```
              parse:       27.1 (±11.1%) i/s -       1610 in  60.061666s
        parse & run:       12.8 (±7.8%) i/s -        765 in  60.045125s

              parse:       27.0 (±11.1%) i/s -       1602 in  60.035207s
        parse & run:       12.5 (±8.0%) i/s -        745 in  60.052382s
```

ran twice on this branch

```
              parse:       27.4 (±10.9%) i/s -       1630 in  60.046285s
        parse & run:       12.2 (±8.2%) i/s -        728 in  60.081207s

              parse:       27.0 (±11.1%) i/s -       1606 in  60.038852s
        parse & run:       12.0 (±8.3%) i/s -        719 in  60.058928s
```

So it looks like this does have a performance impact on rendering at the moment.
I don't think each is inefficient, although using a while loop would allow us to flatten the instructions into a single array, which would reduce the number of objects that are allocated.