odin-lang / Odin

Odin Programming Language

Home Page:https://odin-lang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.
image
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     ,
};