add c++ runtime

This commit is contained in:
SimonFJ20 2024-11-08 12:22:42 +01:00
parent 86bcf39b65
commit f077a16939
11 changed files with 272 additions and 0 deletions

6
runtime/.clang-format Normal file
View File

@ -0,0 +1,6 @@
Language: Cpp
BasedOnStyle: WebKit
IndentWidth: 4
ColumnLimit: 80
IndentCaseLabels: true

30
runtime/Makefile Normal file
View File

@ -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/

37
runtime/arch.hpp Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include <cstdint>
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,
};
}

BIN
runtime/build/main.o Normal file

Binary file not shown.

BIN
runtime/build/sliger Executable file

Binary file not shown.

View File

@ -0,0 +1,9 @@
-xc++
-std=c++20
-pedantic
-pedantic-errors
-Wall
-Wextra
-Wpedantic
-Wconversion

8
runtime/main.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <format>
#include <iostream>
int main()
{
//
std::cout << std::format("hello world\n");
}

86
runtime/value.hpp Normal file
View File

@ -0,0 +1,86 @@
#pragma once
#include <cstdint>
#include <string>
#include <variant>
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<Null>(value); }
inline auto as_null() const -> const Null& { return std::get<Null>(value); }
inline auto as_int() -> Int& { return std::get<Int>(value); }
inline auto as_int() const -> const Int& { return std::get<Int>(value); }
inline auto as_bool() -> Bool& { return std::get<Bool>(value); }
inline auto as_bool() const -> const Bool& { return std::get<Bool>(value); }
inline auto as_string() -> String& { return std::get<String>(value); }
inline auto as_string() const -> const String&
{
return std::get<String>(value);
}
inline auto as_ptr() -> Ptr& { return std::get<Ptr>(value); }
inline auto as_ptr() const -> const Ptr& { return std::get<Ptr>(value); }
private:
ValueType m_type;
std::variant<Null, Int, Bool, String, Ptr> value;
};
}

51
runtime/vm.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "vm.hpp"
#include "arch.hpp"
#include <format>
#include <iostream>
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;
}
}
}

43
runtime/vm.hpp Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include "arch.hpp"
#include "value.hpp"
#include <cstddef>
#include <cstdint>
#include <vector>
namespace sliger {
class VM {
public:
VM(const std::vector<Op>& 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<Op>(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<Value> stack;
std::vector<Value> pool_heap;
};
}

View File

@ -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,