How to transform a tree structure into a different tree structure?


Hi everyone,

I still try to learn Rust by converting the Super Tiny Compiler from JavaScript to Rust. It’s a great learning exercise, because in small code I need to solve a lot of different problems and patterns. I came quite far already with a lot of help from the community.

Now I need to implement the transformer which transforms a tree structure into a different tree structure. It’s the only part in the original implementation which uses a “hack” (in the authors own words). The author adds a reference from the new ast to the old ast, than the old ast is traversed and changes to the new ast are made.

I have a hard time to solve this problem in Rust. I looked for other implementations of the Super Tiny Compiler and found one in Go. However I do not like the way it was solved their. The node in the Go implementation contains everything: all fields for nodes from the old ast, all fields for nodes for the new ast and the context which connects the old ast with the new ast.

In my implementation I have two different types of nodes for the old and the new ast (here and here). I think this is better when I think of converting one programming language into a different programming language as a use case. I also would like to not pollute my node types with context. I thought of creating a type like NodeContext which has a reference to the old and the new ast. But I would need to change my visitors than to use this NodeContext, but I got lost in the way to solve this :frowning:

Has anyone a good idea?


Still having a hard time to find the solution for this. I pushed a new version here.

All “visitor methods” now get a “context”.

But I fight a lot with borrowing :frowning:

error[E0502]: cannot borrow `*context` as mutable because `context.visitors` is also borrowed as immutable
   --> src/
168 |         let visitor = context.visitors.get(&node.get_type());
    |                       ---------------- immutable borrow occurs here
172 |                 enter(&node, parent, context);
    |                                      ^^^^^^^ mutable borrow occurs here
188 |     };
    |     - immutable borrow ends here


I think I found a solution. I’ll update my repo soon.