diff --git a/runtime/.clang-format b/runtime/.clang-format new file mode 100644 index 0000000..8929d9b --- /dev/null +++ b/runtime/.clang-format @@ -0,0 +1,6 @@ +Language: Cpp +BasedOnStyle: WebKit +IndentWidth: 4 +ColumnLimit: 80 +IndentCaseLabels: true + diff --git a/runtime/Makefile b/runtime/Makefile new file mode 100644 index 0000000..c591d85 --- /dev/null +++ b/runtime/Makefile @@ -0,0 +1,30 @@ + +CXX_FLAGS = \ + -std=c++20 \ + -Og \ + -fsanitize=address,undefined \ + -pedantic -pedantic-errors \ + -Wall -Wextra -Wpedantic -Wconversion \ + +OUT=build/sliger + +CXX_HEADERS = $(shell find . -name *.hpp) + +CXX_SOURCES = $(shell find . -name *.cpp) + +CXX_OBJECTS = $(patsubst %.cpp,build/%.o,$(CXX_SOURCES)) + +all: build_dir $(OUT) + +$(OUT): $(CXX_OBJECTS) + g++ -o $@ $(CXX_FLAGS) $^ + +build_dir: + mkdir -p build/ + +build/%.o: %.cpp $(CXX_HEADERS) + g++ -c -o $@ $(CXX_FLAGS) $< + +clean: + rm -rf build/ + diff --git a/runtime/arch.hpp b/runtime/arch.hpp new file mode 100644 index 0000000..411758e --- /dev/null +++ b/runtime/arch.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace sliger { + +// NOTICE: keep up to date with src/arch.ts + +enum class Op : uint32_t { + Nop = 0, + PushNull = 1, + PushInt = 2, + PushString = 3, + PushArray = 4, + PushStruct = 5, + PushPtr = 6, + Pop = 7, + LoadLocal = 8, + StoreLocal = 9, + Call = 10, + Return = 11, + Jump = 12, + JumpIfNotZero = 13, + Add = 14, + Subtract = 15, + Multiply = 16, + Divide = 17, + Remainder = 18, + Equal = 19, + LessThan = 20, + And = 21, + Or = 22, + Xor = 23, + Not = 24, +}; + +} diff --git a/runtime/build/main.o b/runtime/build/main.o new file mode 100644 index 0000000..7547f02 Binary files /dev/null and b/runtime/build/main.o differ diff --git a/runtime/build/sliger b/runtime/build/sliger new file mode 100755 index 0000000..4124329 Binary files /dev/null and b/runtime/build/sliger differ diff --git a/runtime/compile_flags.txt b/runtime/compile_flags.txt new file mode 100644 index 0000000..c79d0c3 --- /dev/null +++ b/runtime/compile_flags.txt @@ -0,0 +1,9 @@ +-xc++ +-std=c++20 +-pedantic +-pedantic-errors +-Wall +-Wextra +-Wpedantic +-Wconversion + diff --git a/runtime/main.cpp b/runtime/main.cpp new file mode 100644 index 0000000..1eec9af --- /dev/null +++ b/runtime/main.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main() +{ + // + std::cout << std::format("hello world\n"); +} diff --git a/runtime/value.hpp b/runtime/value.hpp new file mode 100644 index 0000000..1f841f3 --- /dev/null +++ b/runtime/value.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include +#include +#include + +namespace sliger { + +enum class ValueType { + Null, + Int, + Bool, + String, + Ptr, +}; + +class Values; + +struct Null { }; +struct Int { + uint32_t value; +}; +struct Bool { + bool value; +}; +struct String { + std::string value; +}; +struct Ptr { + uint32_t value; +}; + +class Value { +public: + Value(Null&& value) + : m_type(ValueType::Null) + , value(value) + { + } + Value(Int&& value) + : m_type(ValueType::Int) + , value(value) + { + } + Value(Bool&& value) + : m_type(ValueType::Bool) + , value(value) + { + } + Value(String&& value) + : m_type(ValueType::String) + , value(value) + { + } + Value(Ptr&& value) + : m_type(ValueType::Ptr) + , value(value) + { + } + + inline auto type() const -> ValueType { return m_type; }; + + inline auto as_null() -> Null& { return std::get(value); } + inline auto as_null() const -> const Null& { return std::get(value); } + + inline auto as_int() -> Int& { return std::get(value); } + inline auto as_int() const -> const Int& { return std::get(value); } + + inline auto as_bool() -> Bool& { return std::get(value); } + inline auto as_bool() const -> const Bool& { return std::get(value); } + + inline auto as_string() -> String& { return std::get(value); } + inline auto as_string() const -> const String& + { + return std::get(value); + } + + inline auto as_ptr() -> Ptr& { return std::get(value); } + inline auto as_ptr() const -> const Ptr& { return std::get(value); } + +private: + ValueType m_type; + std::variant value; +}; + +} diff --git a/runtime/vm.cpp b/runtime/vm.cpp new file mode 100644 index 0000000..3cba947 --- /dev/null +++ b/runtime/vm.cpp @@ -0,0 +1,51 @@ +#include "vm.hpp" +#include "arch.hpp" +#include +#include + +using namespace sliger; + +void VM::run() +{ + while (!done()) { + auto op = eat_as_op(); + switch (op) { + case Op::Nop: + // nothing + break; + case Op::PushNull: + this->stack.push_back(Null {}); + break; + case Op::PushInt: + if (done()) { + std::cerr + << std::format("program malformed: missing int value"); + } + this->stack.push_back(Null {}); + break; + case Op::PushString: + case Op::PushArray: + case Op::PushStruct: + case Op::PushPtr: + case Op::Pop: + case Op::LoadLocal: + case Op::StoreLocal: + case Op::Call: + case Op::Return: + case Op::Jump: + case Op::JumpIfNotZero: + case Op::Add: + case Op::Subtract: + case Op::Multiply: + case Op::Divide: + case Op::Remainder: + case Op::Equal: + case Op::LessThan: + case Op::And: + case Op::Or: + case Op::Xor: + case Op::Not: + break; + } + } +} diff --git a/runtime/vm.hpp b/runtime/vm.hpp new file mode 100644 index 0000000..eac7227 --- /dev/null +++ b/runtime/vm.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "arch.hpp" +#include "value.hpp" +#include +#include +#include + +namespace sliger { + +class VM { +public: + VM(const std::vector& program) + : program(program.data()) + , program_size(program.size()) + { + } + void run(); + + inline void step() { this->pc += 1; } + + inline auto eat_as_op() -> Op + { + auto value = curr_as_op(); + step(); + return value; + } + + inline auto curr_as_op() const -> Op + { + return static_cast(this->program[this->pc]); + } + + inline auto done() const -> bool { return this->pc >= this->program_size; } + +private: + uint32_t pc = 0; + const Op* program; + size_t program_size; + std::vector stack; + std::vector pool_heap; +}; +} diff --git a/src/arch.ts b/src/arch.ts index db8287a..eaa838c 100644 --- a/src/arch.ts +++ b/src/arch.ts @@ -1,6 +1,8 @@ export type Ins = Ops | number; export type Program = Ins[]; +// NOTICE: keep up to date with runtime/arch.hpp + export type Ops = typeof Ops; export const Ops = { Nop: 0,