Age | Commit message (Collapse) | Author |
|
When an error occurred, because prog->ptr was incremented beforehand
the trace would show the next instruction as the culprit rather than
the actual instruction. This commit fixes that by incrementing the
program if and only if the command was run successfully.
|
|
In vm_execute_all set the program pointer to the start address in the
header of the program payload.
|
|
|
|
Very barebones, essentially a simple refactor.
I need to introduce a feature to append to a program as well, but as
it's a flexible structure it will likely have to be functional.
|
|
Stack, call stack and heap are evaluated to check for leaks.
|
|
Very easy overall, printing the call stack not so much.
|
|
Not necessary when you can just push the relevant word onto the stack
then just do OP_JUMP_STACK.
|
|
|
|
Happened because we weren't printing all relevant words due to
naturally flooring the result of division. Here I ceil the division
to ensure we get the maximal number of words necessary.
|
|
|
|
Very easy, they just pop a word then defer to their normal versions.
This is probably the best case where a macro works directly so I
didn't even need to write a function form for them first. One thing
is that then names for the macros are quite bad right now, probably
need renaming.
|
|
|
|
Pretty simple implementation, nothing massive.
In VERBOSE mode, heap is tracked for any allocations/deletions,
printing it if so.
|
|
Pretty simple, required some new types of errors. Obviously there's
space for a macro for the differing instruction implementations, but
these things need to be tested a bit more before I can do that.
|
|
As PUSH_REGISTER and MOV have the same signature of taking a word as
input, DUP may as well be part of it.
This leads to a larger discussion about how signatures of functions
matter: I may need to do a cleanup at some point.
|
|
Now need to create some instructions which manage the heap
|
|
word register 0 refers to the first 8 bytes of the dynamic array.
Hence the used counter should be at least 8 bytes. This deals with
those issues. Also print more useful information in
vm_print_registers (how many byte|hword|word registers are currently
in use, how many are available).
|
|
Lucky surprise: OP_PLUS follows the same principle rules as the
bitwise operators in that they return the same type as the input.
Therefore I can simply use the same macro to implement it and MULT as
those. Very nice.
|
|
By default I initialise the registers with 8 words, though this may
not be necessary for your purposes.
|
|
This is because: say we have {a, b} where a is on top of the stack. A
comparator C applies in the order C(b, a) i.e. b `C` a. The previous
version did a `C` b which was wrong.
|
|
This means the stack should be heap allocated, which makes sense as
beyond 1KB one should really be using the heap rather than the stack.
|
|
Stack based machines generally need "variable space". This may be
quite via a symbol-to-word association a list, a hashmap, or some
other system. Here I decide to go for the simplest: extending the
register system to a dynamic/infinite number of them. This means, in
practice, that we may use a theoretically infinite number of indexed
words, hwords and bytes to act as variable space. This means that the
onus is on those who are targeting this virtual machine to create
their own association system to create syntactic variables: all the
machinery is technically installed within the VM, without the veneer
that causes extra cruft.
|
|
|
|
A negative number under 2s complement can never be equal to its
positive as the top bit *must* be on. If two numbers are equivalent
bit-by-bit then they are equal for both signed and unsigned numbers.
|
|
This pushes a datum of the same type as the operands, which is why it
cannot use the comparator macro as that always pushes bytes.
|
|
Anything other than char (which can just use print.byte to print the
hex) and byte (which prints hexes anyway), all other types may be
forced to print a hex rather than a number if PRINT_HEX is 1.
|
|
I've made a single macro which defines a function through some common
metric, removing code duplication. Not particularly readable per se,
but using a macro expansion in your IDE allows one to inspect the code.
|
|
These new members are just signed versions of the previous members.
This makes type punning and usage for signed versions easier than
before (no need for memcpy).
|
|
|
|
So much reused code, I definitely need to find a way to make this cleaner.
|
|
|
|
As it has no dependencies on vm specifically, and it's more necessary
for any vendors who wish to target the virtual machine, it makes more
sense for inst to be a lib module rather than a vm module.
|
|
Just need to call their unsigned versions.
All comparators should push bytes as it makes return types uniform.
|
|
otherwise
Changed VERBOSE checks to ensure a degree of information.
|
|
Will cause error if used currently, which is fine.
|
|
Comparing signed and unsigned versions of numbers. Same for EQ as
well.
Notice the irregular pattern of BYTE, CHAR, INT, HWORD,LONG,WORD as
OPCODE_IS_TYPE requires the subcodes to be surrounded by BYTE and
WORD.
|
|
Prints useful and pretty messages when verbose being at least 1.
|
|
|
|
This is due to checking for equality instead of just greater than in
darr->used against darr->available.
|
|
This is an easy fix.
|
|
Doesn't make sense for them to be in the VM module when they have a
more general purpose now.
|
|
Also prints a usage for incorrect usage.
|
|
Easier to write includes now just using < with the module name, in
comparison to using relative paths.
|
|
|
|
|
|
Changed folder names for sake of clarity (will be introducing a new
build target soon), and Makefile can now easily support more targets.
|