Skip to content

v2.4.2

Compare
Choose a tag to compare
@odino odino released this 30 Mar 16:09
· 72 commits to master since this release

A fresh new patch release of ABS: always be shipping! 🚢

Fixed parsing of numbers and their sign

By solving #409, we bring a little more stability and less funkiness in ABS' parser.

The way ABS used to parse prefixes (eg. -5) was kind of wonky:
we would dump in a token the whole prefix + number (-5) vs
parsing them separately and build the AST according to where
the minus token is found. This change makes it so -5 is actually
(-)(5).

Problems with the previous approach:

  • inconsistent behavior between x = 5; -x and -5
  • -5 would be treated differently than - 5
  • code such as 1 -1 would be parsed as (1); (-1), producing 2
    statements. The return value would be -1 rather than 0

In general, I looked around and the common behavior is to read
tokens separately and, while parsing, figure out, based on their
position, what precedence they should have. This is what this PR
fundamentally does.

For example:

  • when - is a prefix (-2), it should have the highest precedence over
    any other operator. For example, -2.clamp(0, 1) should interpret as
    (-2).clamp(0, 1)
  • when - is not a prefix, it can fallback to its usual precedence (eg.
    less than * or /)

Thie behavior is also consistent with other, languages, take ruby as an
example:

irb(main):011:0> -1.clamp(0, 10)
=> 0

One way in which ABS now deviates with other implementations
is that, since we do not bother reading whitespaces etc in our lexer
-1.clamp(0, 10) and - 1.clamp(0, 10) are exactly the same (while
in ruby, for example, the latter is intepreted as (-)(1.clamp(0, 10))). I think for now this is a reasonable compromise, but I'm open
to change this behavior in subsequent versions of ABS.

This PR also fixes a couple additional issues:

  • +2 is now a valid number, earlier we only considered - as the only
    valid prefix for numbers
  • there could be instances where an infinite loop would be triggered
    because of ABS parsing x +y as x; +y; where the return value is just
    +y. A for loop written like this would have triggered the bug: decr = f(x) {x -1}; for x = 0; x > -10; x = decr(x). It would only happen on for loops where our looper is decrementing