v0.4.3-alpha
[Fix] 修复builtin type的方法可能会导致 bad_variant_access的问题。现在Function严格区分3中函数:
Normal, Builtin, MemberType
[Feat] 增加了 Repl! 通过 Fig -r/--repl进入。目前必须写分号,且异常产生时因为获取不到源文件会有意想不到的问题 :(
[Impl] 精简了Context类,减少内存占用。当然,一些内置函数名获取不了了
后续的 Fig lang standard (目前还没有)中内置函数(MemberType/Builtin)严格无异常抛出
[Feat] 写了个Simple Compiler 和 Bytecode VM作为测试。性能拉跨。优化目前停止
[...] 剩下的忘了~
This commit is contained in:
62
src/IR/IR.hpp
Normal file
62
src/IR/IR.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/fig_string.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
namespace Fig::IR
|
||||
{
|
||||
using Reg = uint16_t;
|
||||
using Label = uint32_t;
|
||||
|
||||
constexpr Reg INVALID_REG = 0xFFFF;
|
||||
|
||||
enum class Op : uint8_t
|
||||
{
|
||||
// ---- control ----
|
||||
Nop,
|
||||
Jmp,
|
||||
Br, // conditional branch
|
||||
Ret,
|
||||
Call,
|
||||
|
||||
// ---- arithmetic ----
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
|
||||
// ---- compare ----
|
||||
Lt,
|
||||
Le,
|
||||
Gt,
|
||||
Ge,
|
||||
Eq,
|
||||
|
||||
// ---- data ----
|
||||
LoadImm, // immediate -> reg
|
||||
Mov,
|
||||
};
|
||||
|
||||
struct Inst
|
||||
{
|
||||
Op op;
|
||||
|
||||
Reg dst; // 结果寄存器
|
||||
Reg a; // operand a
|
||||
Reg b; // operand b
|
||||
|
||||
int64_t imm; // immediate / jump offset
|
||||
};
|
||||
|
||||
struct Function
|
||||
{
|
||||
FString name;
|
||||
|
||||
uint16_t paramCount;
|
||||
uint16_t localCount; // 不含参数
|
||||
uint16_t regCount; // param + locals + temps
|
||||
|
||||
std::vector<Inst> code;
|
||||
};
|
||||
};
|
||||
74
src/IR/IRInterpreter.hpp
Normal file
74
src/IR/IRInterpreter.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <IR/IR.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace Fig::IR
|
||||
{
|
||||
struct VirtualMachine
|
||||
{
|
||||
std::vector<Function *> functions;
|
||||
|
||||
int64_t execute(Function *fn, const int64_t *args)
|
||||
{
|
||||
assert(fn != nullptr);
|
||||
std::vector<int64_t> regs(fn->regCount);
|
||||
// load params
|
||||
|
||||
size_t ip = 0;
|
||||
|
||||
while (ip < fn->code.size())
|
||||
{
|
||||
const Inst &ins = fn->code[ip++];
|
||||
|
||||
switch (ins.op)
|
||||
{
|
||||
case Op::Nop: break;
|
||||
|
||||
case Op::LoadImm: regs[ins.dst] = ins.imm; break;
|
||||
|
||||
case Op::Mov: regs[ins.dst] = regs[ins.a]; break;
|
||||
|
||||
case Op::Add: regs[ins.dst] = regs[ins.a] + regs[ins.b]; break;
|
||||
|
||||
case Op::Sub: regs[ins.dst] = regs[ins.a] - regs[ins.b]; break;
|
||||
|
||||
case Op::Mul: regs[ins.dst] = regs[ins.a] * regs[ins.b]; break;
|
||||
|
||||
case Op::Div: regs[ins.dst] = regs[ins.a] / regs[ins.b]; break;
|
||||
|
||||
case Op::Lt: regs[ins.dst] = regs[ins.a] < regs[ins.b]; break;
|
||||
|
||||
case Op::Le: regs[ins.dst] = regs[ins.a] <= regs[ins.b]; break;
|
||||
|
||||
case Op::Gt: regs[ins.dst] = regs[ins.a] > regs[ins.b]; break;
|
||||
|
||||
case Op::Ge: regs[ins.dst] = regs[ins.a] >= regs[ins.b]; break;
|
||||
|
||||
case Op::Eq: regs[ins.dst] = regs[ins.a] == regs[ins.b]; break;
|
||||
|
||||
case Op::Jmp: ip = static_cast<size_t>(static_cast<int64_t>(ip) + ins.imm); break;
|
||||
|
||||
case Op::Br:
|
||||
if (regs[ins.a] == 0) { ip = static_cast<size_t>(static_cast<int64_t>(ip) + ins.imm); }
|
||||
break;
|
||||
|
||||
case Op::Call: {
|
||||
// currently supports 1-arg call via reg a
|
||||
Function *callee = functions.at(static_cast<size_t>(ins.imm));
|
||||
int64_t arg0 = regs[ins.a];
|
||||
int64_t ret = execute(callee, &arg0);
|
||||
regs[ins.dst] = ret;
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::Ret: return regs[ins.a];
|
||||
}
|
||||
}
|
||||
|
||||
// unreachable normally
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}; // namespace Fig::IR
|
||||
14
src/IR/ir_test_main.cpp
Normal file
14
src/IR/ir_test_main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <IR/IRInterpreter.hpp>
|
||||
#include <IR/IR.hpp>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace Fig;
|
||||
IR::VirtualMachine vm;
|
||||
|
||||
using namespace IR;
|
||||
IR::Inst fib_ir[] = {
|
||||
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user