inital commit
This commit is contained in:
1 parent
e9773c9161
commit
e8b8565773
36 files changed
+40468
No files matched your search
@@ -0,0 +1,69 @@
|
||||
#ifndef DLANG_TYPES_INCLUDE_HPP
|
||||
#define DLANG_TYPES_INCLUDE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
class DlangTable;
|
||||
class DlangList;
|
||||
struct DlangFunction;
|
||||
|
||||
using VMDataTypes = std::variant<double, bool, std::string, std::shared_ptr<DlangTable>, std::shared_ptr<DlangFunction>, std::shared_ptr<DlangList>>;
|
||||
using CFunction = void(*)(class DlangVM* vm);
|
||||
|
||||
#define TOKEN_TYPES \
|
||||
X(UNIDENTIFIED) \
|
||||
X(KEYWORD) \
|
||||
X(SYNTAX) \
|
||||
X(IDENTIFIER) \
|
||||
X(NUMBER) \
|
||||
X(BOOLEAN) \
|
||||
X(STRING) \
|
||||
X(MATH_IDENT)
|
||||
|
||||
#define OPCODE_TYPES \
|
||||
X(EOC, 0x100) \
|
||||
X(PUSH_INT, 0x101) \
|
||||
X(PUSH_BOOL, 0x102) \
|
||||
X(PUSH_STRING, 0x103) \
|
||||
X(PUSH_VAR, 0x104) \
|
||||
X(DEFINE_VAR, 0x105) \
|
||||
X(STORE_VAR, 0x106) \
|
||||
X(ADD, 0x107) \
|
||||
X(SUB, 0x108) \
|
||||
X(MUL, 0x109) \
|
||||
X(DIV, 0x10A) \
|
||||
X(CALL, 0x10B) \
|
||||
X(JZ, 0x10C) \
|
||||
X(JUMP, 0x10D) \
|
||||
X(GREATER_THAN, 0x10E) \
|
||||
X(LESS_THAN, 0x10F) \
|
||||
X(FUNC_DEF, 0x11A) \
|
||||
X(RET, 0x11B) \
|
||||
X(NEW_TABLE, 0x11C) \
|
||||
X(GET_FIELD, 0x11D) \
|
||||
X(SET_FIELD, 0x11E) \
|
||||
X(POP, 0x11F) \
|
||||
X(CMP, 0x12A) \
|
||||
X(GTE, 0x12B) \
|
||||
X(LTE, 0x12C) \
|
||||
X(AND, 0x12D) \
|
||||
X(OR, 0x12E) \
|
||||
X(PUSH_FUNC, 0x12F) \
|
||||
X(NTE, 0x13A) \
|
||||
X(NEW_LIST, 0x13B) \
|
||||
X(PUSH_LIST, 0x13C) \
|
||||
X(GET_INDEX, 0x13D) \
|
||||
X(SET_INDEX, 0x13E) \
|
||||
X(SIZE, 0x13F) \
|
||||
X(KEYS, 0x14A)
|
||||
|
||||
#include "token.hpp"
|
||||
#include "opcodes.hpp"
|
||||
#include "stack_value.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "list.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,162 @@
|
||||
#ifndef DLANG_TYPES_LIST_HPP
|
||||
#define DLANG_TYPES_LIST_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template<typename type>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
type* _list = nullptr;
|
||||
size_t _size = 0;
|
||||
size_t _capacity = 0;
|
||||
|
||||
void grow()
|
||||
{
|
||||
size_t newCapacity = (_capacity == 0) ? 50 : _capacity + 50;
|
||||
type* newList = new type[newCapacity];
|
||||
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
newList[i] = _list[i];
|
||||
|
||||
delete[] _list;
|
||||
|
||||
_list = newList;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
|
||||
public:
|
||||
List() = default;
|
||||
|
||||
List(const List& other)
|
||||
{
|
||||
_size = other._size;
|
||||
_capacity = other._capacity;
|
||||
if (_capacity > 0)
|
||||
{
|
||||
_list = new type[_capacity];
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
_list[i] = other._list[i];
|
||||
}
|
||||
}
|
||||
|
||||
List& operator=(const List& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
delete[] _list;
|
||||
_list = nullptr;
|
||||
_size = other._size;
|
||||
_capacity = other._capacity;
|
||||
|
||||
if (_capacity > 0)
|
||||
{
|
||||
_list = new type[_capacity];
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
_list[i] = other._list[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~List()
|
||||
{
|
||||
try {
|
||||
delete[] _list;
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
int push(type val)
|
||||
{
|
||||
if (_size >= _capacity)
|
||||
grow();
|
||||
|
||||
_list[_size] = val;
|
||||
return static_cast<int>(_size++);
|
||||
}
|
||||
|
||||
size_t size() const { return _size; }
|
||||
size_t capacity() const { return _capacity; }
|
||||
|
||||
type& operator[](size_t index)
|
||||
{
|
||||
return _list[index];
|
||||
}
|
||||
|
||||
bool Contains(type t) const
|
||||
{
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
if (_list[i] == t)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetOrSet(type value)
|
||||
{
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
if (_list[i] == value)
|
||||
return i;
|
||||
|
||||
return push(value);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename type>
|
||||
class NamedList
|
||||
{
|
||||
private:
|
||||
struct DataType
|
||||
{
|
||||
type data;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
private:
|
||||
List<DataType> _list;
|
||||
|
||||
public:
|
||||
void Set(const std::string& name, type t)
|
||||
{
|
||||
for (int i = 0; i < _list.size(); i++)
|
||||
{
|
||||
if (_list[i].name == name)
|
||||
{
|
||||
_list[i].data = t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DataType dt;
|
||||
dt.name = name;
|
||||
dt.data = t;
|
||||
_list.push(dt);
|
||||
}
|
||||
|
||||
type Get(const std::string& name)
|
||||
{
|
||||
for (int i = 0; i < _list.size(); i++)
|
||||
{
|
||||
if (_list[i].name == name)
|
||||
return _list[i].data;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
type Get(int index)
|
||||
{
|
||||
if (index >= _list.size())
|
||||
return {};
|
||||
|
||||
return _list[index].data;
|
||||
}
|
||||
|
||||
int top()
|
||||
{
|
||||
return _list.size();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef DLANG_TYPES_OPCODES_HPP
|
||||
#define DLANG_TYPES_OPCODES_HPP
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
enum class Opcodes : int64_t {
|
||||
#define X(name, val) name = val,
|
||||
OPCODE_TYPES
|
||||
#undef X
|
||||
};
|
||||
|
||||
constexpr const char* OpcodeToString(Opcodes type)
|
||||
{
|
||||
switch (type) {
|
||||
#define X(name, val) case Opcodes::name: return #name;
|
||||
OPCODE_TYPES
|
||||
#undef X
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef DLANG_TYPES_STACK_HPP
|
||||
#define DLANG_TYPES_STACK_HPP
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include "list.hpp"
|
||||
|
||||
template<typename type, int size>
|
||||
class Stack
|
||||
{
|
||||
private:
|
||||
int _top = 0;
|
||||
type _stack[size];
|
||||
|
||||
public:
|
||||
void push(type t)
|
||||
{
|
||||
if (_top >= size)
|
||||
throw std::runtime_error("Stack tried to go over the stack limit!");
|
||||
|
||||
_stack[_top++] = t;
|
||||
}
|
||||
|
||||
type pop()
|
||||
{
|
||||
if (_top <= 0)
|
||||
return type();
|
||||
|
||||
return _stack[--_top];
|
||||
}
|
||||
|
||||
void pop(int amount)
|
||||
{
|
||||
if ((_top - amount) < 0)
|
||||
throw std::runtime_error("Stack underflow, attempted to pop more items than available on the stack!");
|
||||
|
||||
_top -= amount;
|
||||
}
|
||||
|
||||
type& peek()
|
||||
{
|
||||
if (_top <= 0)
|
||||
{
|
||||
static type empty = {};
|
||||
return empty;
|
||||
}
|
||||
|
||||
return _stack[_top - 1];
|
||||
}
|
||||
|
||||
int top() { return _top; }
|
||||
int max() const { return size; }
|
||||
|
||||
type operator[](int index)
|
||||
{
|
||||
return _stack[index];
|
||||
}
|
||||
};
|
||||
|
||||
struct CallFrame
|
||||
{
|
||||
size_t returnIp;
|
||||
std::vector<double> previousBytecode;
|
||||
NamedList<StackValue> locals;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,116 @@
|
||||
#ifndef DLANG_TYPES_STACK_VALUE_HPP
|
||||
#define DLANG_TYPES_STACK_VALUE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
|
||||
enum class StackValueType
|
||||
{
|
||||
NIL,
|
||||
Int,
|
||||
Bool,
|
||||
String,
|
||||
Table,
|
||||
Function,
|
||||
List
|
||||
};
|
||||
|
||||
static std::string StackValueTypeToString(StackValueType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case StackValueType::NIL: return "NIL"; break;
|
||||
case StackValueType::Int: return "Int"; break;
|
||||
case StackValueType::Bool: return "Bool"; break;
|
||||
case StackValueType::String: return "String"; break;
|
||||
case StackValueType::Table: return "Table"; break;
|
||||
case StackValueType::Function: return "Function"; break;
|
||||
case StackValueType::List: return "List"; break;
|
||||
default: return "Unknown"; break;
|
||||
}
|
||||
}
|
||||
|
||||
struct StackValue
|
||||
{
|
||||
StackValueType type;
|
||||
VMDataTypes data;
|
||||
|
||||
StackValue() { this->type = StackValueType::NIL; };
|
||||
StackValue(StackValueType _type, VMDataTypes _data)
|
||||
{
|
||||
this->type = _type;
|
||||
this->data = std::move(_data);
|
||||
}
|
||||
};
|
||||
|
||||
struct DlangFunction
|
||||
{
|
||||
double bodyAddress;
|
||||
std::vector<std::string> parameters;
|
||||
std::vector<double> bytecodeChunk;
|
||||
|
||||
bool isNative;
|
||||
CFunction nativeFunction;
|
||||
|
||||
static std::shared_ptr<DlangFunction> CreateNative(CFunction function)
|
||||
{
|
||||
auto func = std::make_shared<DlangFunction>();
|
||||
func->isNative = true;
|
||||
func->nativeFunction = function;
|
||||
return func;
|
||||
}
|
||||
|
||||
static std::shared_ptr<DlangFunction> CreateInternal(const std::string& name, double bodyAddy, std::vector<std::string> params)
|
||||
{
|
||||
auto func = std::make_shared<DlangFunction>();
|
||||
func->bodyAddress = bodyAddy;
|
||||
func->parameters = params;
|
||||
func->isNative = false;
|
||||
return func;
|
||||
}
|
||||
};
|
||||
|
||||
class DlangTable
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, StackValue> fields;
|
||||
|
||||
void Set(const std::string& key, StackValue val)
|
||||
{
|
||||
fields[key] = val;
|
||||
}
|
||||
|
||||
bool Get(const std::string& key, StackValue& outVal)
|
||||
{
|
||||
auto it = fields.find(key);
|
||||
if (it != fields.end())
|
||||
{
|
||||
outVal = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class DlangList
|
||||
{
|
||||
public:
|
||||
std::vector<StackValue> values;
|
||||
|
||||
void Push(StackValue val)
|
||||
{
|
||||
values.push_back(val);
|
||||
}
|
||||
|
||||
StackValue Get(int index)
|
||||
{
|
||||
if (index > values.size())
|
||||
return StackValue(); // push nil
|
||||
|
||||
return values.at(index);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef DLANG_TYPES_TOKEN_HPP
|
||||
#define DLANG_TYPES_TOKEN_HPP
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
|
||||
enum class TokenType : int {
|
||||
#define X(name) name,
|
||||
TOKEN_TYPES
|
||||
#undef X
|
||||
};
|
||||
|
||||
constexpr const char* TokenTypeToString(TokenType type)
|
||||
{
|
||||
switch (type) {
|
||||
#define X(name) case TokenType::name: return #name;
|
||||
TOKEN_TYPES
|
||||
#undef X
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
struct PreToken
|
||||
{
|
||||
std::string value;
|
||||
int line;
|
||||
int column;
|
||||
|
||||
static PreToken CreateEmpty()
|
||||
{
|
||||
PreToken t;
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
struct Token
|
||||
{
|
||||
std::string value;
|
||||
TokenType type;
|
||||
|
||||
int line;
|
||||
int column;
|
||||
|
||||
void Print()
|
||||
{
|
||||
printf("[%d:%d] %s: %s\n", line, column, TokenTypeToString(type), value.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user