These instructions were used because it was more painful to implement
lookups and function calls for operators with the AST body compiler.
This is less of a hurdle now with the list compiler, and since these
instructions are extensive and involve a lot of copy-paste, they have
been removed to help with code bloat.
They may be reintroduced in the future for optimization purposes.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This adds the `Int::new_obj_uncached()` function, which will create a new Int
object without caching it. The `Int::new_obj()` will cache the value if
it inclusively lies between -1 and 255. This is a minor optimization
that should hopefully go a long way with speed and memory footprint.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
ThunkBranch standalone struct was not as useful as I was expecting it
would be. Its logic is now directly stored in Thunk::Branch variant
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
AST body is compiled first to a LISP-like IR via the ListCompiler, which
in turn converts down to a thunk. The direct AST -> Thunk compiler is no
longer needed.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This should hopefully allow us to add more interesting modifications to
the code, and have less boilerplate when implementing new function-based
features.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
The VM now supports the various int comparison methods. An example of a
"pow" method is given to show off recursion, which means we're now
TURING COMPLETE!
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This is to differentiate between methods (which have a 'self' binding)
and functions (which are free).
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* obj::Bool builtin type is used for truthiness and decision-making
* Branches are compiled and seem to be working for basic integer
comparison
* Updated version of Shredder to what is current as of writing
* CheckTruth VM instruction that will explicitly set the condition flag
* Probably some other stuff
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Builtin functions for builtin types. This allows the "hello world"
program to actually work how it's supposed to.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Global names previously would only load once, and then not again because
of issues with how the root scope is compiled. This is fixed.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* VM is able to handle basic runtime errors although there is no way to
catch this in executing code currently
* If a function is called with the wrong number of arguments (arity) it
will invoke a runtime error.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Methods are wrappers created with an owner and a function, which
passes the owner as the first argument when the function is called.
* Fix a small bug in the VM where the pc was being set at the wrong
time
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Builtin functions print and println have been added
* If a global lookup fails, the VM will attempt to look up a builtin
* Vm::call(fun, args) allows interrupting the current execution state
and starting a new function instead. It will return the value left on
top of the stack.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Functions are downcasted to a `Fun` trait, which will construct the
appropriate stack frame.
A few other things have been shifted around that affect internal APIs
while things are still under construction.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* vm::package is no longer needed since the compiler now creates
UserFunRef objects
* Reserved object attributes can be accessed using get_* methods, e.g.
get_plus for ease of use.
* Add some implementations for operator instructions in the VM
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Currently, scopes are only allowed to look at their locals and the
globals. Inner functions cannot refer to values in their parent
functions. This will change eventually.
* Scope lookup is split between globals and locals. Locals are defined
in a scope if they are explicitly assigned to.
* i.e. `a = foo` will treat `a` as a local in the current scope if
it appears anywhere in that scope. This does not extend to
setattrs; `a.b = foo` will not trigger `a` into being a local var.
* `Package` objects are no longer returned from the compiler - instead,
a user function is returned.
* Other various changes and renames
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Functions are compiled in the most naiive way right now. I want to fix
up how scope lookups are done before it becomes too much to update.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* VM Signals are used by running functions to dictate whether a function
should return, or if it should call another function. These signals
can be injected at any time allowing for user functions to inject
themselves at runtime.
* obj::Method is gone since it's not being used yet.
* Obj impls must implement as_any(&self) -> &dyn Any now. This allows
for UserFun and NativeFun to be explicitly cast (among other things,
in the future).
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Code is compiled into a vm:📦:Package which contains the
executable code, the constants, and the local name mappings.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This removes the vtable and attrs members from appearing, which muddies
up what we really care about with ints
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Variables were previously named "Local"s because they described a
local variable - however, this is kind of a misnomer because it
handles globals as well. This has been changed pretty much everywhere
when appropriate (hopefully).
* Renamed obj/names.rs to obj/reserved.rs, freeing up the "names" module
for the new Names handle
* Renamed obj/locals.rs to obj/names.rs, see above
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* rerun_except will ensure a build doesn't rerun if a *.not file is
modified, which it would otherwise do
* Add examples/expr.not with some basic assignment statements and
function calls
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
A vector of instructions and constants can now be decompiled as text on
the terminal to give an idea of what the VM is doing.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
I'm able to compile some basic expressions into instructions using the
`not` binary. Big first step, now we need to introduce branches and
loops to the syntax.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Upon entering a new body, the local scope variables are collected.
* VM instruction PushLocal now uses a `Local` value instead of a `Sym`
value
* Compilation of a new AST body will implicitly create a new scope
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Basic are a more linear way of representing code. Thunks beget basic
blocks, which beget vectors of instructions.
* Basic blocks are also being flattened into a vector of instructions
(hopefully, no tests done yet)
* OH yeah locals can be collected too (but currently are not being
collected in the compiler, that should come soon)
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>