From 5112d36ae079fef47f70e830cba0cd1d48d2acd7 Mon Sep 17 00:00:00 2001
From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com>
Date: Mon, 19 May 2025 12:45:08 -0500
Subject: [PATCH] yea, sux
---
.idea/.gitignore | 8 +
.idea/JoVa.iml | 2 +
.idea/betterCommentsSettings.xml | 31 +++
.idea/editor.xml | 341 +++++++++++++++++++++++++++
.idea/material_theme_project_new.xml | 10 +
.idea/misc.xml | 7 +
.idea/modules.xml | 8 +
.idea/vcs.xml | 6 +
CMakeLists.txt | 35 +++
main.cpp | 9 +
src/Compiler.cpp | 136 +++++++++++
src/Compiler.h | 20 ++
src/Vm.cpp | 168 +++++++++++++
src/Vm.h | 64 +++++
14 files changed, 845 insertions(+)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/JoVa.iml
create mode 100644 .idea/betterCommentsSettings.xml
create mode 100644 .idea/editor.xml
create mode 100644 .idea/material_theme_project_new.xml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/vcs.xml
create mode 100644 CMakeLists.txt
create mode 100644 main.cpp
create mode 100644 src/Compiler.cpp
create mode 100644 src/Compiler.h
create mode 100644 src/Vm.cpp
create mode 100644 src/Vm.h
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/JoVa.iml b/.idea/JoVa.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/JoVa.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.idea/betterCommentsSettings.xml b/.idea/betterCommentsSettings.xml
new file mode 100644
index 0000000..4f152ed
--- /dev/null
+++ b/.idea/betterCommentsSettings.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/editor.xml b/.idea/editor.xml
new file mode 100644
index 0000000..970f097
--- /dev/null
+++ b/.idea/editor.xml
@@ -0,0 +1,341 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml
new file mode 100644
index 0000000..879b75e
--- /dev/null
+++ b/.idea/material_theme_project_new.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0b76fe5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..72b3444
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..c0cde95
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.15)
+project(JoVa LANGUAGES CXX)
+
+# Set output directories for builds
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin/Debug)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin/Release)
+
+# Set C++ standard
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+if(MSVC)
+ add_compile_options(/W4 /permissive-)
+else()
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+set(SOURCES
+ main.cpp
+ src/Vm.cpp
+ src/Vm.h
+ src/Compiler.cpp
+ src/Compiler.h
+)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_executable(JoVa ${SOURCES})
+
+source_group("Source Files" FILES ${SOURCES})
+
+# Set default build type to Debug if not specified
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
+endif()
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..ace9686
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,9 @@
+#include "src/Vm.h"
+#include "src/Compiler.h"
+
+int main() {
+ auto bytecode = JV::Compiler::CompileExample();
+ JV::VM vm(bytecode);
+ vm.Run();
+ return 0;
+}
diff --git a/src/Compiler.cpp b/src/Compiler.cpp
new file mode 100644
index 0000000..6859d61
--- /dev/null
+++ b/src/Compiler.cpp
@@ -0,0 +1,136 @@
+#include "Compiler.h"
+#include "Vm.h"
+
+namespace JV {
+
+std::vector Compiler::CompileExample() {
+ std::vector code;
+
+ // n = 10
+ code.push_back(OP_CONST);
+ code.push_back(10);
+ code.push_back(OP_STORE); // R4 = n
+ code.push_back(4);
+
+ // alloc heap[n]
+ code.push_back(OP_ALLOC); // heap = malloc(n)
+ code.push_back(10);
+ code.push_back(OP_STORE); // R5 = heap base address
+ code.push_back(5);
+
+ // i = 2
+ code.push_back(OP_CONST);
+ code.push_back(2);
+ code.push_back(OP_STORE); // R0 = i
+ code.push_back(0);
+
+ // a = 0
+ code.push_back(OP_CONST);
+ code.push_back(0);
+ code.push_back(OP_STORE); // R1 = a
+ code.push_back(1);
+
+ // b = 1
+ code.push_back(OP_CONST);
+ code.push_back(1);
+ code.push_back(OP_STORE); // R2 = b
+ code.push_back(2);
+
+ // store fib(0) at heap[0]
+ code.push_back(OP_LOAD); // R5 (heap base)
+ code.push_back(5);
+ code.push_back(OP_CONST); // push 0
+ code.push_back(0);
+ code.push_back(OP_ADD); // heap + 0
+ code.push_back(OP_CONST); // value: 0
+ code.push_back(0);
+ code.push_back(OP_STORE_MEM);
+
+ // print fib(0)
+ code.push_back(OP_CONST); // print 0
+ code.push_back(0);
+ code.push_back(OP_PRINT);
+
+ // store fib(1) at heap[1]
+ code.push_back(OP_LOAD); // R5
+ code.push_back(5);
+ code.push_back(OP_CONST); // +1
+ code.push_back(1);
+ code.push_back(OP_ADD);
+ code.push_back(OP_CONST); // value: 1
+ code.push_back(1);
+ code.push_back(OP_STORE_MEM);
+
+ // print fib(1)
+ code.push_back(OP_CONST);
+ code.push_back(1);
+ code.push_back(OP_PRINT);
+
+ // === loop:
+ int loop_start = code.size();
+
+ // if i >= n: halt
+ code.push_back(OP_LOAD); // i
+ code.push_back(0);
+ code.push_back(OP_LOAD); // n
+ code.push_back(4);
+ code.push_back(OP_SUB);
+ code.push_back(OP_CONST); // if i - n >= 0 → skip CALL
+ code.push_back(0);
+ code.push_back(OP_SUB); // dummy conditional
+ // (TODO: implement real conditional branching)
+
+ // fib = a + b
+ code.push_back(OP_LOAD); // a
+ code.push_back(1);
+ code.push_back(OP_LOAD); // b
+ code.push_back(2);
+ code.push_back(OP_ADD);
+ code.push_back(OP_STORE); // R3 = fib
+ code.push_back(3);
+
+ // store fib(i) in heap[i]
+ code.push_back(OP_LOAD); // R5 (heap base)
+ code.push_back(5);
+ code.push_back(OP_LOAD); // R0 (i)
+ code.push_back(0);
+ code.push_back(OP_ADD); // addr = base + i
+ code.push_back(OP_LOAD); // fib value (R3)
+ code.push_back(3);
+ code.push_back(OP_STORE_MEM);
+
+ // print fib(i)
+ code.push_back(OP_LOAD);
+ code.push_back(3);
+ code.push_back(OP_PRINT);
+
+ // a = b
+ code.push_back(OP_LOAD);
+ code.push_back(2);
+ code.push_back(OP_STORE);
+ code.push_back(1);
+
+ // b = fib
+ code.push_back(OP_LOAD);
+ code.push_back(3);
+ code.push_back(OP_STORE);
+ code.push_back(2);
+
+ // i = i + 1
+ code.push_back(OP_LOAD);
+ code.push_back(0);
+ code.push_back(OP_CONST);
+ code.push_back(1);
+ code.push_back(OP_ADD);
+ code.push_back(OP_STORE);
+ code.push_back(0);
+
+ // jump back to loop
+ code.push_back(OP_CALL);
+ code.push_back(loop_start);
+
+ code.push_back(OP_HALT);
+ return code;
+}
+
+} // namespace JV
diff --git a/src/Compiler.h b/src/Compiler.h
new file mode 100644
index 0000000..66498bf
--- /dev/null
+++ b/src/Compiler.h
@@ -0,0 +1,20 @@
+//
+// Created by spenc on 5/19/2025.
+//
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#include
+#include
+
+namespace JV {
+
+ class Compiler {
+ public:
+ static std::vector CompileExample();
+ };
+
+} // namespace JV
+
+#endif // COMPILER_H
diff --git a/src/Vm.cpp b/src/Vm.cpp
new file mode 100644
index 0000000..a41dc5b
--- /dev/null
+++ b/src/Vm.cpp
@@ -0,0 +1,168 @@
+#include "Vm.h"
+#include
+
+namespace JV
+{
+ VM::VM(const std::vector &bytecode)
+ : m_Bytecode(bytecode), m_IP(0)
+ {
+ m_Registers.fill(0);
+ m_Heap.resize(HEAP_SIZE, 0);
+ }
+
+ int VM::Pop()
+ {
+ int val = m_Stack.top();
+ m_Stack.pop();
+ return val;
+ }
+
+ void VM::Push(int val)
+ {
+ m_Stack.push(val);
+ }
+
+ void VM::Debug()
+ {
+ std::cout << "\n[DEBUG] IP: " << m_IP << "\nStack: ";
+ std::stack temp = m_Stack;
+ std::vector stackDump;
+ while (!temp.empty()) {
+ stackDump.push_back(temp.top());
+ temp.pop();
+ }
+ for (auto it = stackDump.rbegin(); it != stackDump.rend(); ++it)
+ std::cout << *it << " ";
+ std::cout << "\nRegisters: ";
+ for (int r: m_Registers)
+ std::cout << r << " ";
+ std::cout << "\n\nPress Enter to step...\n";
+ std::cin.get();
+ }
+
+ void VM::Run()
+ {
+ while (m_IP < m_Bytecode.size()) {
+ OpCode op = static_cast(m_Bytecode[m_IP++]);
+#ifndef _DEBUG
+ //Debug();
+#endif
+
+ switch (op) {
+ case OP_HALT:
+ return;
+
+ case OP_ALLOC: Alloc();
+ break;
+
+ case OP_STORE_MEM: StoreMem();
+ break;
+ case OP_LOAD_MEM: LoadMem();
+ break;
+
+
+ case OP_CONST:
+ Push(m_Bytecode[m_IP++]);
+ break;
+
+ case OP_STORE:
+ {
+ uint8_t reg = m_Bytecode[m_IP++];
+ m_Registers[reg] = Pop();
+ break;
+ }
+
+ case OP_LOAD:
+ {
+ uint8_t reg = m_Bytecode[m_IP++];
+ Push(m_Registers[reg]);
+ break;
+ }
+
+ case OP_ADD:
+ {
+ int b = Pop(), a = Pop();
+ Push(a + b);
+ break;
+ }
+
+ case OP_SUB:
+ {
+ int b = Pop(), a = Pop();
+ Push(a - b);
+ break;
+ }
+
+ case OP_MUL:
+ {
+ int b = Pop(), a = Pop();
+ Push(a * b);
+ break;
+ }
+
+ case OP_DIV:
+ {
+ int b = Pop(), a = Pop();
+ Push(a / b);
+ break;
+ }
+
+ case OP_PRINT:
+ std::cout << Pop() << std::endl;
+ break;
+
+ case OP_CALL:
+ {
+ uint8_t addr = m_Bytecode[m_IP++];
+ m_CallStack.push(m_IP);
+ m_IP = addr;
+ break;
+ }
+
+ case OP_RET:
+ m_IP = m_CallStack.top();
+ m_CallStack.pop();
+ break;
+
+ case OP_DEBUG:
+ Debug();
+ break;
+
+ default:
+ std::cerr << "Unknown opcode: " << static_cast(op) << "\n";
+ return;
+ }
+ }
+ }
+
+
+ void VM::Alloc()
+ {
+ uint8_t count = m_Bytecode[m_IP++];
+ if (m_HeapPtr + count >= HEAP_SIZE) {
+ std::cerr << "Heap overflow!" << std::endl;
+ return;
+ }
+ Push(static_cast(m_HeapPtr)); // return address
+ m_HeapPtr += count;
+ }
+
+ void VM::StoreMem()
+ {
+ int value = Pop();
+ int addr = Pop();
+ if (addr >= 0 && addr < HEAP_SIZE)
+ m_Heap[addr] = value;
+ else
+ std::cerr << "Invalid memory store at " << addr << std::endl;
+ }
+
+ void VM::LoadMem()
+ {
+ int addr = Pop();
+ if (addr >= 0 && addr < HEAP_SIZE)
+ Push(m_Heap[addr]);
+ else
+ std::cerr << "Invalid memory load at " << addr << std::endl;
+ }
+} // namespace JV
diff --git a/src/Vm.h b/src/Vm.h
new file mode 100644
index 0000000..b69c733
--- /dev/null
+++ b/src/Vm.h
@@ -0,0 +1,64 @@
+#ifndef VM_H
+#define VM_H
+
+#include
+#include
+#include
+#include
+
+namespace JV {
+
+ constexpr int MAX_REGISTERS = 8;
+ constexpr int STACK_SIZE = 1024;
+ static constexpr int HEAP_SIZE = 256; // "size_t" give wrnings
+
+
+
+
+ enum OpCode : uint8_t {
+ OP_HALT = 0,
+ OP_CONST,
+ OP_STORE,
+ OP_LOAD,
+ OP_ADD,
+ OP_SUB,
+ OP_MUL,
+ OP_DIV,
+ OP_PRINT,
+ OP_CALL,
+ OP_RET,
+ OP_ALLOC, // Allocate N cells, return address
+ OP_STORE_MEM, // Stack: [value, addr]
+ OP_LOAD_MEM, // Stack: [addr]
+ OP_DEBUG
+ };
+
+ class VM {
+ public:
+ explicit VM(const std::vector& bytecode);
+ void Run();
+
+ private:
+ std::vector m_Bytecode;
+ std::stack m_Stack;
+ std::vector m_Heap;
+ size_t m_HeapPtr = 0;
+ std::array m_Registers{};
+ std::stack m_CallStack;
+ size_t m_IP = 0;
+
+ int Pop();
+ void Push(int val);
+ void Debug();
+
+ void Alloc();
+ void StoreMem();
+ void LoadMem();
+
+
+
+ };
+
+} // namespace JV
+
+#endif // VM_H