mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 10:56:30 +00:00
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 Ins = Ops | number;
|
||||||
export type Program = Ins[];
|
export type Program = Ins[];
|
||||||
|
|
||||||
|
// NOTICE: keep up to date with runtime/arch.hpp
|
||||||
|
|
||||||
export type Ops = typeof Ops;
|
export type Ops = typeof Ops;
|
||||||
export const Ops = {
|
export const Ops = {
|
||||||
Nop: 0,
|
Nop: 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user