-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8f77085
Showing
16 changed files
with
732 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# XiaoVM | ||
|
||
A mini VM, also an advanced toy. Kill time together with me, if you like. :-) | ||
|
||
Copyright (c) 2013 Mike Manilone | ||
All rights reserved | ||
|
||
You can freely use this program as an end-user, you can't redistribute it. | ||
|
||
See spec.txt to see how to write Xiao code. | ||
|
||
小 "Xiao" is the Chinese word for "small". | ||
|
||
To have a great experience with XiaoVM, you need to prepare | ||
* glib2 ( yum install glib2-devel ) | ||
* Tcl 8.6 ( yum install tcl ) | ||
|
||
Enjoy! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Compiler | ||
|
||
The compiler is written in Tcl, and depends on Tcl 8.6. The code style is considered really bad and don't follow that (ok... no one will be interested in this VM ;-). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/usr/bin/env tclsh | ||
package require Tcl 8.6 | ||
foreach file $argv { | ||
set f [open $file r] | ||
set fo [open $file.xbc w] | ||
set contents [read $f] | ||
foreach line [split $contents \n] { | ||
set cmd [lindex [split $line { }] 0] | ||
if { $cmd == "" } continue | ||
switch -exact -- $cmd { | ||
";" { | ||
continue } | ||
LOADSTRING { | ||
set str [lrange [split $line { }] 1 end] | ||
puts -nonewline $fo "\x10" | ||
puts -nonewline $fo [format %c [string length $str]] | ||
puts -nonewline $fo $str } | ||
LOADSPECIAL { | ||
set specialname [lindex [split $line { }] 1] | ||
set special {} | ||
puts -nonewline $fo "\x11" | ||
switch -exact -- $specialname { | ||
STOP { | ||
set special "\x00" } } | ||
puts -nonewline $fo $special } | ||
LOADNUMBER { | ||
set number [lindex [split $line { }] 1] | ||
puts -nonewline $fo "\x12" | ||
puts -nonewline $fo [format %c $number] } | ||
CALL { | ||
set name [lindex [split $line { }] 1] | ||
puts -nonewline $fo "\x05" | ||
puts -nonewline $fo "$name\x00" } | ||
default { | ||
error "No such command - $cmd" } } } | ||
close $f | ||
close $fo } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Examples of XiaoVM | ||
|
||
Good. You have reached here. | ||
|
||
Try run these compiled "Xiao ByteCode" (.xbc) with XiaoVM. If you got problems, try compiling them with the compiler. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
; | ||
; Copyright (c) 2013 Mike Manilone | ||
; All rights reserved | ||
; | ||
|
||
LOADSTRING Hello | ||
LOADSPECIAL STOP | ||
CALL io::print | ||
|
||
LOADSTRING world | ||
LOADSPECIAL STOP | ||
CALL io::print |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
; | ||
; Copyright (c) 2013 Mike Manilone | ||
; All rights reserved | ||
; | ||
|
||
LOADNUMBER 100 | ||
LOADSPECIAL STOP | ||
CALL io::print | ||
|
||
LOADNUMBER 2 | ||
LOADSPECIAL STOP | ||
CALL io::print |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# XiaoVM Spec | ||
|
||
## Allowed instructions | ||
|
||
* LOADSTRING | ||
* LOADNUMBER | ||
* LOADSPECIAL | ||
* CALL | ||
|
||
It's easy and fun to add a new function to XiaoVM. | ||
|
||
For the specific number these names represent, read processor.h. | ||
|
||
## Builtins | ||
|
||
* io::print | ||
|
||
## Namespace | ||
|
||
You may wonder what the "::" means. In fact it's nothing more than a string... There isn't built-in namespace support and thus this is a simulation. | ||
|
||
## Lifespan | ||
|
||
LOAD* will create new objects from static data on the heap, and give them the reference count 1. | ||
After CALL is done, reference counts of all the involved objects will automatically be decreased. | ||
|
||
## "Stack"? | ||
|
||
If you read the source you may find I used the term, "stack", in "processor.[ch]". To clarify my point, I have to say it's NOT real stack. See the examples and you'll find why. I have no better names so I simply pick up "stack" and put it there. | ||
|
||
## Limitations | ||
* I didn't pay attention to portability at first, so the bytecode is not portable. This is easy-to-fix because the source code is very short. | ||
* Valgrind reports some "definite" memory leaks. | ||
* The size of any number or length of strings can't be larger than sizeof(char). This is a problem in the compiler but I'm too lazy to fix it. Maybe later I will try 'long', or even 'long long'. | ||
|
||
## Advantages | ||
* It's an extensible framework | ||
* The "assemble language" consists of very simple concepts and functions | ||
* The source code is short and easy-to-read | ||
* The C API is clean and neat | ||
* It's strongly typed! | ||
* It's also very easy to extend with the C API | ||
|
||
## Disadvantages | ||
* The source code is short, thus the function is limited | ||
* Who will expect such VM?! NO ONE WOULD LIKE TO USE THIS! THUS... | ||
* THIS IS NOT STRONGLY MAINTAINED. IT'S JUST A TOY! | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** | ||
* XiaoVM | ||
* | ||
* Copyright (c) 2013 Mike Manilone | ||
* All rights reserved | ||
*/ | ||
#include <glib/gi18n.h> | ||
#include "processor.h" | ||
#include "functions.h" | ||
|
||
int | ||
XVM_builtin_io__print ( | ||
struct XVM_Processor *processor, | ||
int argc, | ||
struct XVM_Object *argv[]) | ||
{ | ||
for (int i = 0; i < argc && argv[i]->user_flags != XVM_SpecialFlag; i++) | ||
{ | ||
switch (argv[i]->type) | ||
{ | ||
case XVM_TYPE_STRING: | ||
g_print ("%s", argv[i]->data.v_string); | ||
break; | ||
case XVM_TYPE_NUMBER: | ||
g_print ("%d", argv[i]->data.v_number); | ||
break; | ||
case XVM_TYPE_OTHER: | ||
g_print ("Object<0x%lX>", GPOINTER_TO_SIZE(argv[i]->data.v_pointer)); | ||
break; | ||
default: | ||
g_assert_not_reached (); | ||
break; | ||
} | ||
} | ||
g_print ("\n"); | ||
return XVM_FUNCALL_OK; | ||
} | ||
|
||
void | ||
xvm_builtins_load_io (struct XVM_Processor *processor) | ||
{ | ||
xvm_processor_provide (processor, "io::print", XVM_builtin_io__print); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* XiaoVM | ||
* | ||
* Copyright (c) 2013 Mike Manilone | ||
* All rights reserved | ||
*/ | ||
#pragma once | ||
|
||
#include <glib.h> | ||
#include "processor.h" | ||
#include "object.h" | ||
|
||
enum XVM_FunCallResult | ||
{ | ||
XVM_FUNCALL_ERROR, | ||
XVM_FUNCALL_OK | ||
}; | ||
|
||
int XVM_builtin_io__print (struct XVM_Processor *processor, | ||
int argc, | ||
struct XVM_Object *argv[]); | ||
void xvm_builtins_load_io (struct XVM_Processor *processor); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* XiaoVM | ||
* | ||
* Copyright (c) 2013 Mike Manilone | ||
* All rights reserved | ||
*/ | ||
#include <locale.h> | ||
#include <glib.h> | ||
#include <glib/gi18n.h> | ||
#include <gio/gio.h> | ||
#include "processor.h" | ||
#include "functions.h" | ||
|
||
gchar * | ||
_load_contents (const gchar *filename, gsize *length) | ||
{ | ||
gchar *contents = NULL; | ||
GError *error = NULL; | ||
GFile *file = g_file_new_for_path (filename); | ||
g_file_load_contents (file, NULL, &contents, length, NULL, &error); | ||
g_object_unref (file); | ||
if (error) | ||
{ | ||
g_error ("%s", error->message); | ||
g_error_free (error); | ||
} | ||
return contents; | ||
} | ||
|
||
gint | ||
main (gint argc, | ||
gchar *argv[]) | ||
{ | ||
setlocale (LC_ALL, ""); | ||
for (int i = 1; argv[i] != NULL; i ++) | ||
{ | ||
gchar *errmsg = NULL; | ||
gsize filelength; | ||
gchar *contents = _load_contents (argv[i], &filelength); | ||
struct XVM_Processor *p = xvm_processor_new (contents, filelength); | ||
xvm_builtins_load_io (p); | ||
xvm_processor_run (p, &errmsg); | ||
xvm_processor_destroy (p); | ||
g_free (contents); | ||
if (errmsg) | ||
{ | ||
g_error ("%s", errmsg); | ||
g_free (errmsg); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
|
Oops, something went wrong.