JohnEarnest / ok

An open-source interpreter for the K5 programming language.
MIT License
588 stars 72 forks source link

schizophrenic minus #74

Closed Lobachevsky closed 4 years ago

Lobachevsky commented 6 years ago

Try 1-2-3-4

tluyben commented 6 years ago

That has to do with this hack

https://github.com/JohnEarnest/ok/blob/gh-pages/oK.js#L651

Something like this fixes it but I didn't run unittests so it might break a lot of other things:

        str = str.replace(/("(?:[^"\\\n]|\\.)*")|(\s\/.*)/gi, function(_, x, y) {
        // preserve a string (x), remove a comment (y)
        return x ? x : (y ? "":y);  
    })
    str = str.replace(/([a-z\d\]\)]\-)/gi, function(x) { return x.replace('-', '- '); });

This is awfully hacky anyway and should be fixed after tokenizing or parsing, but the current implementation of oK would not make that easy to do as far as I can see. John might have other ideas.

The latest version of K:

1-2-3 2

1-2-3-4 -2

-1-2-3 0

Which my hack indeed produces as well.

Hope John has a few minutes to weigh in or someone will have time to run some tests.

I would imho be better to remove the hack and insert fix the issue by inserting ()s.

JohnEarnest commented 4 years ago

I see the problem now.

The tokenizer pre-pass was doing -\.?\d to find - adjacent to the beginning of a number. Problem is, a match in this case means that leading digit will be consumed for purposes of future matches, meaning the pattern gets correctly applied to every-other instance in an input like 1-2-3-4. The regex can be corrected by doing a lookahead match for the beginning of a digit instead: -(?=\.?\d)

Rather amusingly, this problem could only have cropped up with 1-digit numbers.

(yes, it's still a pretty dirty hack.)