lojikil / coastML

a tiny experimental ML dialect combining Yeti & CarML
ISC License
12 stars 0 forks source link

array literals with variables in blocks fail #11

Closed lojikil closed 1 year ago

lojikil commented 1 year ago

this works:

f = fn {
    [10 20];
};

g = (f);
print g

however this fails:

f = fn x y {
    xx = x + 10;
    yy = y + 20;
    [xx yy];
};

g = f 10 20;
print g

We get an error about an incorrect top level form, which is neat (usually means the state machine is off in the parser): carpet.parse.CoastalParseError: ("Incorrect top-level form <class 'carpet.parse.TokenArrayEnd'>", 3)

lojikil commented 1 year ago

Part of what I need to do when I release the self-hosted compiler is to use all of these cases to form a test suite.

lojikil commented 1 year ago

so interestingly, I just dealt with a similar bug in the self-hosting compiler; from carpet/parse.py:

1460         elif type(self.lexemes[self.current_offset]) == TokenIdent or \
1461              type(self.lexemes[self.current_offset]) == TokenOperatorLiteral:
1462             # could be a function call or an assignment
1463             if self.is_assignment(self.lexemes[self.current_offset + 1]):
1464                 return self.parse_assignment()
1465             elif type(self.lexemes[self.current_offset + 1]) == TokenKeyword and \
1466                  self.lexemes[self.current_offset + 1].lexeme == "is":
1467                 return self.parse_assignment()
1468             else:                                                                                                                                                                                
1469                 return self.parse_call()

Basically, the runaway parse_call method (line 1469) there is what's hurting us: we land on an identifier and then attempt to parse a call, but end up with a TokenArrayEnd. There really only should be so many things in an array literal, so unlike how I fixed it in the self-hosting compiler (by making the call semantics explicit to call contexts, like what I should do here) what I'll do is just expand out the tests for values and call their respective sub-parsers, just like I already do for simple values.