Parsing bugs with the builtin parser in core:odin
zhibog opened this issue · comments
Context
I'm currently writing an AST printer, using the parser in the core library.
It's already most of the way done. Here are some things I noticed while developing.
For things I was absolutely sure about, I already PRed a fix.
Ternary
Ternary Expressions do not seem to get parsed correctly.
a := 5;
c := a == 5 ? "yes" : "no";
// Results in a Bad_Stmt as oppose to a Ternary_Expr
Fallthrough, break, continue
Those keywords result in a Branch_Stmt, which is correct.
They are, however, missing the correct token and have the Token_Kind Invalid.
If I specifically assign the "tok" variable in core:odin/parser to "s", it works. I assume there is something not quite right in the handling / assigning of the token beforehand.
Inline on ranges result in a Bad_Stmt
I have not looked into this further.
inline for in 0..2 {}
Question mark operator for maybe unions results in Bad_Expr
I have not looked into this further.
// Taken from demo.odin
Maybe :: union(T: typeid) #maybe {T};
i: Maybe(u8);
i = 123;
x := i.?;
Proc directive results in Block_Stmt, Tag_Stmt
The Block_Stmt or Tag_Stmt ends up in the root declarations and contains the Note_State_Flag for the directive, but this seems rather weird. Should it not just be a member of the proc type or lit?
// Results in Block_Stmt
foo :: proc() #no_bounds_check {}
// Results in Tag_Stmt
foo1 :: proc(y: int) -> (x: int, ok: bool) #optional_ok {
return y, y > 0;
}
Field_Value struct attribute to denote whether it's for a bit_field or not
The last thing isn't really an error, more of an idea / suggestion.
Maybe we should add something to Field_Value to note if it belongs to a bit_field.
Because bit fields use ":" rather, than "=", I have to pass down which one it currently uses.
This is also fine for me.
@gingerBill Thanks for working on the core parser.
Since some of the bugs got fixed yesterday I checked all the issues above again.
All of the old ones, except one seem to be fixed. I was able to make them work and generate correct code.
The one that doesn't seem to work is break, continue and fallthrough.
Using them results in the following Branch_Stmt, notice the token kind.
Code used:
for i := 0; i < 10; i += 1 {
if i == 5 {
continue;
} else {
break;
}
}
I also found a new one, but this isn't really a bug, just an oversight most likely.
There is no indication if a nested struct has using
. Consider this code:
BatchCall :: struct {
index : string,
stopBatchIfError : bool,
using _ : struct #raw_union {
argument0 : uint ,
returnValue : uint ,
},
argument1 : uint ,
argument2 : uint ,
argument3 : uint ,
};