Skip to content

Commit

Permalink
Its working
Browse files Browse the repository at this point in the history
  • Loading branch information
ekd123 committed Aug 18, 2013
0 parents commit 8f77085
Show file tree
Hide file tree
Showing 16 changed files with 732 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Readme.txt
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!
3 changes: 3 additions & 0 deletions compiler/Readme
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 ;-).
37 changes: 37 additions & 0 deletions compiler/compiler.tcl
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 }
5 changes: 5 additions & 0 deletions examples/Readme.txt
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.
12 changes: 12 additions & 0 deletions examples/hello.x
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 added examples/hello.x.xbc
Binary file not shown.
12 changes: 12 additions & 0 deletions examples/print-number.x
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 added examples/print-number.x.xbc
Binary file not shown.
48 changes: 48 additions & 0 deletions spec.txt
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!

44 changes: 44 additions & 0 deletions vm/functions.c
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);
}

22 changes: 22 additions & 0 deletions vm/functions.h
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);
54 changes: 54 additions & 0 deletions vm/main.c
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;
}


Loading

0 comments on commit 8f77085

Please sign in to comment.