Commit Graph
25 Commits
Author SHA1 Message Date
Nunuhara Cabbage b3a660f8ec strings: copy-on-write
Only copy strings when they are mutated. This avoids copying strings in
cases where neither the copy nor the original would be modified during
the lifetime of the copy, e.g. when passing strings by-value.

This is purely an optimization.
2019-10-20 21:26:51 -07:00
Nunuhara Cabbage e5ef9f4d2d Implement constructors and methods
Implement CALLMETHOD, SH_STRUCTREF and PUSHSTRUCTPAGE instructions.

Constructors are a bit tricky since SH_LOCALCREATE has to implicitly
call an arbitrary number of functions before it returns (just changing
the instruction pointer only allows for calling a single function).

To get around this, there is now a vm_call() function which is used to
call a function synchronously, before returning from the current
instruction.

Methods are implemented as functions, except that they get a struct page
as local variable -1.

Destructors are still not implemented.
2019-10-20 17:33:22 -07:00
Nunuhara Cabbage 2210696f93 Implement S_REF (struct pass-by-value) 2019-10-20 11:51:16 -07:00
Nunuhara Cabbage d37de6c23a Add tests for some basic language features 2019-10-19 22:53:05 -07:00
Nunuhara Cabbage 49586506d0 Fix memory managment of objects on stack
A few things.

The S_REF instruction creates a _copy_ of the referenced string. Proof:

    FUNC foo
    // string local_string = "foo"
    SH_LOCALREF local_string
    S_PUSH "foo"
    S_ASSIGN
    S_POP

    // prepare argument for bar()
    PUSHLOCALPAGE
    PUSH local_string
    S_REF

    // stealthily alter local_string
    SH_LOCALREF local_string
    S_PUSH "bar"
    S_ASSIGN
    S_POP

    // bar(local_string)
    CALLFUNC bar // local_string is still "foo" in the body of bar()!

Thus, it is not CALLFUNC's responsibility to copy by-value string
arguments. CALLFUNC need only copy the index from the stack into the
local page.

Objects pushed to the stack with SH_LOCALREF, SH_GLOBALREF and REF do
not gain a reference. They are already referenced by the page they
belong to.

I believe the implementation of S_REF is still not quite right. What
I've noticed is that System40.exe is able to distinguish between strings
pushed with S_REF/S_PUSH and strings pushed with
SH_LOCALREF/SH_GLOBALREF/REF. It seems the former are r-values and the
latter are l-values (i.e. the latter can be assigned to, but not the
former), and the VM will throw an error if you try to assign to an
r-value.
The underlying implementation is not clear to me. Both types appear to
be indices into the heap, which suggests that the distinguishing factor
must be stored either in the object itself, or as part of the pointer to
an object. Perhaps its as simple as a flag marking an object as an
r-value?
2019-10-19 21:36:52 -07:00
Nunuhara Cabbage 7ba5626675 Support simple struct/class usage
No constructors, destructors or methods--just simple data structures.
2019-10-19 08:18:22 -07:00
Nunuhara Cabbage 82c3f81d52 Add rudimentary unit testing via AIN file
Building 'test/test.pje' with the SDK compiler produces a file at
'test/Run/test.ain' which can be run with xsystem4 to test various
features.

Not the greatest testing method, but it works.
2019-10-16 20:16:19 -07:00
Nunuhara Cabbage 7fa8c28d9d Fix string_find for shift-jis 2019-10-16 20:11:16 -07:00
Nunuhara Cabbage 736f6dcad0 Fix ASSIGN and F_ASSIGN
Same as previous commit, assigned value is pushed to the stack.
2019-10-16 18:24:58 -07:00
Nunuhara Cabbage 503ec4cdb1 Fix arithmetic assignment instructions
The assigned value is pushed to the stack.
2019-10-15 21:51:47 -07:00
Nunuhara Cabbage 12242c087f strings: handle shift-jis 2019-10-14 18:09:00 -07:00
Nunuhara Cabbage 55f3991546 Implement more string instructions
Implement all of the string instructions that I could get the compiler
to generate code for. Still ASCII-only.
2019-10-14 14:18:09 -07:00
Nunuhara Cabbage cc2a2c594a Floating point instructions 2019-10-13 21:32:17 -07:00
Nunuhara Cabbage b7bdd17a50 Add global variables
PUSHGLOBALPAGE and SH_GLOBALREF instructions.
2019-10-13 20:00:11 -07:00
Nunuhara Cabbage 8a40058c81 Overhaul VM design
Overhaul the VM design to more closely resemble System40.exe. See
system4.md for further details.
2019-10-13 17:51:22 -07:00
Nunuhara Cabbage 827e0a85d7 S_ASSIGN & fix SH_LOCALREF for strings 2019-10-10 21:26:41 -07:00
Nunuhara Cabbage 769e0ce0c3 Add argument types to instruction table
Not really useful for the VM, but could be used for an objdump-like
utility.
2019-10-10 07:16:48 -07:00
Nunuhara Cabbage 92710dc06a INC/DEC and DUP* instructions
Random note: The SDK compiler generates some pretty strange code for
'n++' when 'n' is a reference:

    instruction                state of stack after instruction
    -----------                --------------------------------
    PUSHLOCALPAGE              ; P(ref n)
    PUSH <variable index of n> ; P(ref n),V(ref n)
    REFREF                     ; P(n),V(n)
    DUP2                       ; P(n),V(n),P(n),V(n)
    REF                        ; P(n),V(n),n
    DUP_X2                     ; n,P(n),V(n),n
    POP                        ; n,P(n),V(n)
    INC                        ; n
    POP                        ;

This would seem to be completely equivalent to the following:

    PUSHLOCALPAGE
    PUSH <variable index of n>
    REFREF
    INC
2019-10-07 19:32:56 -07:00
Nunuhara Cabbage e629d0ad3e Use vm_value for frame_stack & implement S_REF 2019-10-07 18:30:20 -07:00
Nunuhara Cabbage 3925c8ea96 Unify stack & string_stack
Use an array of unions for the stack. I'm still not sure if System40.exe
uses separate stack for string operations or not. Need to check if POP
after S_PUSH removes the pushed string.
2019-10-07 18:04:36 -07:00
Nunuhara Cabbage 53dc8a7a44 strings: store size together with text in memory 2019-10-07 16:54:46 -07:00
Nunuhara Cabbage 626e4f47d7 Arithmetic assignment instructions (+=, -=, etc.) 2019-10-07 16:12:24 -07:00
Nunuhara Cabbage 587dc34ddb Implement ASSIGN and basic arithmetic instructions 2019-10-06 22:32:50 -07:00
Nunuhara Cabbage eb63980294 Call system.Exit after returning from main
A bit of a hack: we insert an extra 'CALLSYS 0x0' instruction
(system.Exit) at the end of the code section, then set up a stack frame
so that when main() returns, it jumps to that instruction.
2019-10-06 20:58:03 -07:00
Nunuhara Cabbage 84df756faf Initial commit
An assortment of instructions have been implemented so far, mostly basic
stuff such as stack management. The following program can be executed:

int main(void)
{
    hello(2);
    for (;;) {
        system.Peek();
        system.Sleep(1);
    }
    return 0;
}

void hello(int n)
{
    int i;
    for (i = 0; i < n; i++) {
        system.Output("Hello, world! " + string(i));
    }
}
2019-10-06 19:35:36 -07:00