add c++ runtime
This commit is contained in:
parent
86bcf39b65
commit
f077a16939
6
runtime/.clang-format
Normal file
6
runtime/.clang-format
Normal file
@ -0,0 +1,6 @@
|
||||
Language: Cpp
|
||||
BasedOnStyle: WebKit
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 80
|
||||
IndentCaseLabels: true
|
||||
|
30
runtime/Makefile
Normal file
30
runtime/Makefile
Normal 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
37
runtime/arch.hpp
Normal 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
BIN
runtime/build/main.o
Normal file
Binary file not shown.
BIN
runtime/build/sliger
Executable file
BIN
runtime/build/sliger
Executable file
Binary file not shown.
9
runtime/compile_flags.txt
Normal file
9
runtime/compile_flags.txt
Normal file
@ -0,0 +1,9 @@
|
||||
-xc++
|
||||
-std=c++20
|
||||
-pedantic
|
||||
-pedantic-errors
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Wconversion
|
||||
|
8
runtime/main.cpp
Normal file
8
runtime/main.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
//
|
||||
std::cout << std::format("hello world\n");
|
||||
}
|
86
runtime/value.hpp
Normal file
86
runtime/value.hpp
Normal 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
51
runtime/vm.cpp
Normal 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
43
runtime/vm.hpp
Normal 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;
|
||||
};
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user