wu-lang / wu

🐉 A practical game and data language
https://wu-lang.gitbook.io/guide/
MIT License
467 stars 17 forks source link

Basic Interpreter Functionality #22

Closed cedric-h closed 3 years ago

cedric-h commented 4 years ago

This PR adds a standalone interpreter to Wu, so that you don't have to have luac to run Wu programs. Because we offer finer grained control that isn't always reflected in Lua, having our own interpreter gives us the opportunity to run Wu code with much higher performance. Also, writing interpreters is just fun.

Interaction with the existing code: I butchered src/main.rs to make the interpreter accessible from the command line. I also added some convenience methods to parser::ast::Expression, so that I can easily convert Expressions into their base values. I was able to leave everything else alone.

Progress so far: The Interpreter isn't entirely usable on its own yet, but you can call external Rust functions and evaluate simple binary operators between floats, create user defined functions and cast floats to strings.

Going forward: Now that a template is in place for the Binary operations and casting, all that needs to be done is for these patterns to be extended with more types. We would probably benefit from having a better way to provide Rust functions to the Wu evaluator as it's running, zesterer provided a very good example with his Forge engine construct. If and While are also crucial additions, as well as Block processing, but the majority of the heavy lifting required for these to happen is already in place.

evolbug commented 4 years ago

Hey, this is a good concept, however I see that what you are currently building is a tree based interpreter. Unfortunately, this by definition will be slower than even unoptimized Lua code. Afterall, you are going up against two decades of professional optimization and architecture. There's LuaJIT too which is one of the top performing scripting language VMs.

The initial concept of Wu was a bytecode interpreter, but we opted to target Lua due to the ecosystem available, as we wanted to target games. The ability to use Love2D is a big sell.

Regardless, the original VM is still available in the vm-version branch, you can try to get that back up and running if you want, it's 99% there, I think we stopped at FFI and some scope bugs, I don't remember exactly :smile:

cedric-h commented 4 years ago

Oh, wow! Nilq sent me here through Discord, but I don't think he ever mentioned that you guys already had a bytecode interpreter. I should've known to look.

I'll spend some time researching bytecode interpreters. The one that you guys have is 165 commits and a couple years out of date, so I may end up starting over from scratch, we'll see.

Looking through your guys's implementation, it's really funny how similar it ended up to my tree based interpreter; the only difference is that you compile everything to instructions and then have another step where you execute.

evolbug commented 4 years ago

Don't worry about the date that much, the transpiler (current) and VM are completely different implementation-wise, and we've been on a hiatus for a while.

The reason we use a bytecode VM is that it's basically the way to achieve performance in an interpreted language before getting into JIT and compiling to native. The implementation we have might be a bit hard to grok right away as we do some fine-grained byte manipulation.

There's some good stuff you can learn about tree and bytecode VMs here: https://www.craftinginterpreters.com/contents.html

evolbug commented 3 years ago

Closing due to not being relevant for current goals