Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IDE and compiler unable to handle recursive enums, even to display an error. #8

Closed
SirTony opened this issue Jan 9, 2020 · 2 comments

Comments

@SirTony
Copy link

SirTony commented Jan 9, 2020

Recursive enum cases currently cause both the IDE and beefbuild to crash, which, in addition to making it impossible to implement something like an arithmetic expression tree, makes it difficult to implement any other kind of tree structure which might refer to itself in some way, such as a JSON value (at least in the IDE's case)

This crashes both the IDE and the compiler without fail:

enum Expression
{
    case Number( double x );
    case Add( Expression left, Expression right );
    // other arithmetic operations
}

And this will crash just the IDE when typed out normally:

enum JsonValue
{
    case Null;
    case Array( JsonValue[] items );
}

The IDE crashes just after inserting JsonValue when declaring the Array case before even being able to insert the square brackets, requiring some other external editor, but otherwise it works as expected once that's sorted out.

I'm assuming naked recursion (such as in example 1) without putting the Self behind a pointer, array, or some other form of indirection is intended since doing the same thing with a struct correctly produces an error without crashing.

As an aside, what is the idiomatic way of writing the first snippet properly? Pointer? Some kind of Box<T> like Rust?

@bfiete
Copy link
Collaborator

bfiete commented Jan 9, 2020

Yes that is indeed illegal... thanks for finding that, I'll make it be a pretty error message. If you didn't want to use OOP, then the idiomatic way would be to make 'left' and 'right' pointers to Expression.

You can decide how you want to allocate and deallocate the memory for those expressions, but for an AST you probably just want to use a BumpAllocator instance which is pretty much the fastest possible allocation, and no need for deleting the individual Expression instances since the memory will all be recovered when the single BumpAllocator instance is destroyed - and since the enum won't require any per-instance destructors. You'll find that this technique is quite a lot faster than a Rust enum with Box values.

@bfiete
Copy link
Collaborator

bfiete commented Jan 17, 2020

Fixed in 9d1b85c, will be in 0.42.2.

@bfiete bfiete closed this as completed May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants