aboutsummaryrefslogtreecommitdiff
path: root/ShiftOS.Modding.VirtualMachine/Form1.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ShiftOS.Modding.VirtualMachine/Form1.cs')
-rw-r--r--ShiftOS.Modding.VirtualMachine/Form1.cs265
1 files changed, 265 insertions, 0 deletions
diff --git a/ShiftOS.Modding.VirtualMachine/Form1.cs b/ShiftOS.Modding.VirtualMachine/Form1.cs
new file mode 100644
index 0000000..78722a9
--- /dev/null
+++ b/ShiftOS.Modding.VirtualMachine/Form1.cs
@@ -0,0 +1,265 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using ShiftOS.Engine;
+using ShiftOS.Objects.ShiftFS;
+
+namespace ShiftOS.Modding.VirtualMachine
+{
+ [Launcher("ShiftOS Virtual Machine", false)]
+ public partial class Form1 : UserControl, IShiftOSWindow
+ {
+ private byte[] memory = null; //program binary
+ private int programCounter = 0; //current byte
+ private Stack<int> stack = null; //stack
+ private int[] registers = null; //registers
+ private int currentRegister = 0;
+
+
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ public void OnLoad()
+ {
+ }
+
+ public void Execute()
+ {
+ switch ((OpCodes)memory[programCounter])
+ {
+ case OpCodes.DoNothing:
+
+ break;
+ case OpCodes.Add:
+ registers[currentRegister] = registers[currentRegister] + registers[currentRegister + 1];
+ break;
+ case OpCodes.Subtract:
+ registers[currentRegister] = registers[currentRegister] - registers[currentRegister + 1];
+ break;
+ case OpCodes.Multiply:
+ registers[currentRegister] = registers[currentRegister] * registers[currentRegister + 1];
+ break;
+ case OpCodes.Divide:
+ registers[currentRegister] = registers[currentRegister] / registers[currentRegister + 1];
+ break;
+ case OpCodes.Increment:
+ registers[currentRegister]++;
+ break;
+ case OpCodes.Decrement:
+ registers[currentRegister]--;
+ break;
+ case OpCodes.MoveUp:
+ currentRegister++;
+ break;
+ case OpCodes.MoveDown:
+ currentRegister--;
+ break;
+ case OpCodes.Error:
+ Infobox.Show("Error", "An error has occurred inside the VM, we will now halt it.");
+ break;
+ case OpCodes.Jump:
+ stack.Push(programCounter);
+ programCounter = registers[currentRegister];
+ break;
+ case OpCodes.Zero:
+ registers[currentRegister] = 0;
+ break;
+ case OpCodes.Return:
+ programCounter = memory.Length;
+ break;
+ case OpCodes.JumpBack:
+ programCounter = stack.Pop();
+ break;
+ case OpCodes.Out:
+ Console.Write(registers[currentRegister]);
+ break;
+ }
+ }
+
+ public void OnSkinLoad()
+ {
+ }
+
+ public bool OnUnload()
+ {
+ return true;
+ }
+
+ public void OnUpgrade()
+ {
+ }
+
+ private void exitToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ AppearanceManager.Close(this);
+ }
+
+ public void Start()
+ {
+ var th = new System.Threading.Thread(() =>
+ {
+ while(programCounter < memory.Length)
+ {
+ Execute();
+ programCounter++;
+ }
+ });
+ th.IsBackground = true;
+ th.Start();
+ }
+
+ private void openBinaryToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ FileSkimmerBackend.GetFile(new[] { ".svm" }, FileOpenerStyle.Open, new Action<string>((program) =>
+ {
+ memory = Utils.ReadAllBytes(program);
+ programCounter = 0;
+ stack = new Stack<int>();
+ registers = new int[64000];
+ currentRegister = 0;
+ Start();
+ }));
+ }
+ }
+
+ [Namespace("svm")]
+ public static class Compiler
+ {
+ public static byte[] Compile(string prg)
+ {
+ List<OpCodes> program = new List<OpCodes>();
+ foreach(var statement in prg.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ if (!string.IsNullOrEmpty(statement))
+ {
+ string[] statements = statement.Split(' ');
+ switch (statements[0])
+ {
+ case "increment":
+ program.Add(OpCodes.Increment);
+ break;
+ case "decrement":
+ program.Add(OpCodes.Decrement);
+ break;
+ case "mvup":
+ program.Add(OpCodes.MoveUp);
+ break;
+ case "mvdn":
+ program.Add(OpCodes.MoveDown);
+ break;
+ case "set":
+ program.Add(OpCodes.Zero);
+ for(int i = 0; i <= Convert.ToInt32(statements[1]); i++)
+ {
+ program.Add(OpCodes.Increment);
+ }
+ break;
+ case "+":
+ program.Add(OpCodes.Add);
+ break;
+ case "-":
+ program.Add(OpCodes.Subtract);
+ break;
+ case "*":
+ program.Add(OpCodes.Multiply);
+ break;
+ case "/":
+ program.Add(OpCodes.Divide);
+ break;
+ case "out":
+ program.Add(OpCodes.Out);
+ break;
+ case "return":
+ program.Add(OpCodes.Return);
+ break;
+ case "jump":
+ program.Add(OpCodes.Jump);
+ break;
+ case "back":
+ program.Add(OpCodes.JumpBack);
+ break;
+ }
+ }
+ }
+
+ byte[] newPrg = new byte[program.Count];
+ foreach(var oc in program)
+ {
+ newPrg[program.IndexOf(oc)] = (byte)oc;
+ }
+ return newPrg;
+
+ }
+
+ [Command("compile")]
+ [RequiresArgument("input")]
+ [RequiresArgument("output")]
+ public static bool CompileCommand(Dictionary<string, object> args)
+ {
+ string input = args["input"] as string;
+ string output = args["output"] as string;
+ if (!Utils.FileExists(input))
+ {
+ Console.WriteLine("The file you requested does not exist.");
+ return true;
+ }
+
+ if (!output.EndsWith(".svm"))
+ output += ".svm";
+
+ byte[] program = Compile(Utils.ReadAllText(input));
+ Utils.WriteAllBytes(output, program);
+ return true;
+ }
+
+ [Command("read")]
+ [RequiresArgument("input")]
+ public static bool ReadFile(Dictionary<string, object> args)
+ {
+ string input = args["input"] as string;
+ if (Utils.FileExists(input))
+ {
+ foreach(var b in Utils.ReadAllBytes(input))
+ {
+ Console.WriteLine((OpCodes)b);
+ }
+ }
+ else
+ {
+ Console.WriteLine("File doesn't exist.");
+ }
+
+ return true;
+ }
+ }
+
+
+
+ public enum OpCodes : byte
+ {
+ DoNothing = 0x00,
+ Zero = 0x11,
+ Add = 0x01,
+ Subtract = 0x02,
+ Multiply = 0x03,
+ Divide = 0x04,
+ MoveUp = 0x05,
+ MoveDown = 0x051,
+ Increment = 0x06,
+ Decrement = 0x061,
+ Out = 0x07,
+ Jump = 0x08,
+ Return = 0x081,
+ JumpBack = 0x082,
+ Error = 0x9,
+
+ }
+}