thoughts about compiler

This commit is contained in:
lachrymaL 2023-04-07 16:04:30 -04:00
parent bdf80f37e6
commit 38496209c0
No known key found for this signature in database
GPG key ID: F3640ACFA174B1C1
9 changed files with 78 additions and 47 deletions

View file

@ -249,8 +249,8 @@ namespace ADVect {
}
int main(int argc, char* argv[]) {
// std::filesystem::current_path("E:\\Archive\\Projects\\NouVeL\\ADVect\\runtime");
std::filesystem::current_path("/Users/lachrymal/Projects/NouVeL/ADVect/runtime/");
std::filesystem::current_path("E:\\Archive\\Projects\\NouVeL\\ADVect\\runtime");
//std::filesystem::current_path("/Users/lachrymal/Projects/NouVeL/ADVect/runtime/");
NVL::Environment::ENVIRONMENT.enter({
{

View file

@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 3.8)
project (NVL)
include_directories("include")
add_library (NVL STATIC "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h")
add_library (NVL STATIC "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h" "Compiler.cpp" "Compiler.h")
# add_executable (NVL "NouVeL.cpp" "Parser.cpp" "Environment.cpp" "Environment.h" "Common.h" )
# TODO: Add tests and install targets if needed.

View file

@ -15,6 +15,7 @@ typedef int64_t i64;
typedef uint64_t u64;
#include <string>
#include <vector>
#include <locale>
#include <codecvt>
@ -24,6 +25,8 @@ namespace NVL {
using Number = f32;
using Char = char16_t;
using String = std::u16string;
template <typename T>
using Vector = std::vector<T>;
static std::wstring_convert<std::codecvt_utf8_utf16<Char>, Char> str_converter;

28
NVL/Compiler.cpp Normal file
View file

@ -0,0 +1,28 @@
#include "Compiler.h"
#include "Parser.h"
#include "Environment.h"
namespace NVL::Compiler {
struct _DirectedGraphNode {
Vector<_DirectedGraphNode*> reached_by;
Vector<std::pair<i32, Vector<Environment::Variable>>> sequence;
};
void Compile(Vector<Parse::Scene>& scenes, i32 entry_scene_index) {
_DirectedGraphNode n{};
Vector<Environment::Variable> procs_used{};
for (auto& c : scenes[entry_scene_index].get()) {
Environment::Variable f = Environment::Eval(c[0]);
Vector<Environment::Variable> s{};
u32 i = 1;
while (i < c.size()) {
s.push_back(Environment::Eval(c[i++]));
}
}
}
void Serialize(_DirectedGraphNode root) {
}
}

1
NVL/Compiler.h Normal file
View file

@ -0,0 +1 @@
#include "Common.h"

View file

@ -12,8 +12,8 @@ namespace NVL::Environment {
}
Variable::Variable(const Number& v) : type(Type::Number), value(v), length(1) {}
Variable::Variable(const String& v) : type(Type::String), value(v), length(1) {}
Variable::Variable(const std::vector<Variable>& v) : type(Type::Array), value(v), length(v.size()) {}
Variable::Variable(const std::function < Variable(std::vector<Variable>)>& v, u32 l) : type(Type::Procedure), value(v), length(l) {}
Variable::Variable(const Vector<Variable>& v) : type(Type::Array), value(v), length(v.size()) {}
Variable::Variable(const std::function < Variable(Vector<Variable>)>& v, u32 l) : type(Type::Procedure), value(v), length(l) {}
bool Variable::operator==(const Variable& other) const {
if (other.type != type)
@ -62,20 +62,20 @@ namespace NVL::Environment {
return Variable(std::get<String>(obj.value));
case Parse::Type::Array:
{
std::vector<Variable> v{};
for (const auto& x : std::get<std::vector<Parse::Object>>(obj.value))
Vector<Variable> v{};
for (const auto& x : std::get<Vector<Parse::Object>>(obj.value))
v.push_back(Eval(x));
return Variable(v);
}
case Parse::Type::Subexpression:
{
return Apply(std::get<std::vector<Parse::Object>>(obj.value));
return Apply(std::get<Vector<Parse::Object>>(obj.value));
}
}
}
Variable Apply(const Parse::Command& c) {
std::vector<Variable> args{};
Vector<Variable> args{};
Variable f = Eval(c[0]);
u32 i = 1;
@ -83,7 +83,7 @@ namespace NVL::Environment {
args.push_back(Eval(c[i++]));
}
if (f.length != -1 && f.length != i - 1) throw std::runtime_error("Function arity mismatch");
return std::get<std::function<Variable(std::vector<Variable>)>>(f.value)(args);
return std::get<std::function<Variable(Vector<Variable>)>>(f.value)(args);
}
void EvalScene(const Parse::Scene& s) {
@ -92,23 +92,23 @@ namespace NVL::Environment {
}
// Check MatchMarkup for more information
MarkupString UnpackMarkupVariable(const std::vector<Variable>& v) {
MarkupString UnpackMarkupVariable(const Vector<Variable>& v) {
MarkupString ms{};
for (const Variable& segment : v) {
const auto& pair = std::get<std::vector<Variable>>(segment.value);
const auto& pair = std::get<Vector<Variable>>(segment.value);
const String s = std::get<String>(pair[0].value);
std::vector<std::pair<String, std::vector<String>>> efs;
for (const Variable& combination : std::get<std::vector<Variable>>(pair[1].value)) {
Vector<std::pair<String, Vector<String>>> efs;
for (const Variable& combination : std::get<Vector<Variable>>(pair[1].value)) {
if (combination.type == Type::String) {
const String ef = std::get<String>(combination.value);
efs.push_back({ ef, {} });
}
else if (combination.type == Type::Array) {
const std::vector<Variable>& ef_t = std::get<std::vector<Variable>>(combination.value);
const Vector<Variable>& ef_t = std::get<Vector<Variable>>(combination.value);
const String& ef = std::get<String>(ef_t[0].value);
const std::vector<Variable>& args = std::get<std::vector<Variable>>(ef_t[1].value);
std::vector<String> ss{};
const Vector<Variable>& args = std::get<Vector<Variable>>(ef_t[1].value);
Vector<String> ss{};
for (const auto& s : args) { ss.push_back(std::get<String>(s.value)); }
efs.push_back({ ef, ss });
}

View file

@ -10,7 +10,7 @@ namespace NVL::Environment {
struct Variable {
Type type;
std::variant<Number, String, std::vector<Variable>, std::function<Variable(std::vector<Variable>)>> value;
std::variant<Number, String, Vector<Variable>, std::function<Variable(Vector<Variable>)>> value;
// Most things will have length 1 (including string); this is mostly for function arity and array length
u32 length;
bool operator==(const Variable& other) const;
@ -18,8 +18,8 @@ namespace NVL::Environment {
Variable(Type t); // Reserved for Nil
Variable(const Number& v);
Variable(const String& v);
Variable(const std::vector<Variable>& v);
Variable(const std::function<Variable(std::vector<Variable>)>& v, u32 l);
Variable(const Vector<Variable>& v);
Variable(const std::function<Variable(Vector<Variable>)>& v, u32 l);
};
class Environment {
@ -41,15 +41,15 @@ namespace NVL::Environment {
struct MarkupSegment {
String str;
std::vector<std::pair<String, std::vector<String>>> efs;
Vector<std::pair<String, Vector<String>>> efs;
};
struct MarkupString {
private:
mutable i32 mem_length = -1;
public:
std::vector<MarkupSegment> segments{};
Vector<MarkupSegment> segments{};
size_t length() const;
MarkupString substr(size_t idx) const;
};
MarkupString UnpackMarkupVariable(const std::vector<Variable>& v);
MarkupString UnpackMarkupVariable(const Vector<Variable>& v);
}

View file

@ -125,8 +125,8 @@ namespace {
return to_NVL_string(buffer.str());
}
std::vector<String> split_string_by_lines(const String& str) {
std::vector<String> lines;
Vector<String> split_string_by_lines(const String& str) {
Vector<String> lines;
size_t pos = 0;
size_t prev = 0;
while ((pos = str.find(NEWLINE, prev)) != String::npos) {
@ -230,7 +230,7 @@ namespace {
Parse::Object ParseArray(const String& f, size_t& pos, u32 layer) {
SkipComments(f, pos);
std::vector<Parse::Object> array{};
Vector<Parse::Object> array{};
array.push_back(ParseExpression(f, pos));
while (PeekToken(f, pos)[0] != ARRAY_CLOSE) {
@ -246,7 +246,7 @@ namespace {
String ParseString(const String& f, size_t& pos) {
SkipComments(f, pos);
std::vector<size_t> discards{};
Vector<size_t> discards{};
auto start = ++pos; // skip opening quote
do {
if (f[pos] == QUOTE) {
@ -352,7 +352,7 @@ namespace {
bool has_markup = false;
// Match tags
std::vector<Parse::Object> segments;
Vector<Parse::Object> segments;
String::const_iterator tags_start(s.cbegin());
while (srell::regex_search(tags_start, s.cend(), tags_match, typer)) {
has_markup = true;
@ -361,13 +361,13 @@ namespace {
if (!before.empty())
segments.push_back({ Parse::Type::Array, {
{ Parse::Type::String, before },
{ Parse::Type::Array, std::vector<Parse::Object>{} }
{ Parse::Type::Array, Vector<Parse::Object>{} }
}});
String inner = tags_match[2].str(); // markupped
// Match markup options
std::vector<Parse::Object> effects{};
Vector<Parse::Object> effects{};
String::const_iterator effects_start(tags_match[1].first);
while (srell::regex_search(effects_start, tags_match[1].second, effects_match, effect)) {
if (effects_match[3].matched) { // no params
@ -376,19 +376,19 @@ namespace {
else { // no params
// Comma split
std::vector<Parse::Object> args;
Vector<Parse::Object> args;
String::const_iterator params_start(effects_match[2].first);
while (srell::regex_search(params_start, effects_match[2].second, params_match, param)) {
size_t temp = 0;
args.push_back(ParseExpression(params_match[1].str() + SEPARATOR.accept[0], temp)); // PeekToken will freak out if I don't do this
params_start = params_match.suffix().first;
}
effects.push_back({ Parse::Type::Array, std::vector<Parse::Object>{ { Parse::Type::String, effects_match[1].str() }, { Parse::Type::Array, args } } });
effects.push_back({ Parse::Type::Array, Vector<Parse::Object>{ { Parse::Type::String, effects_match[1].str() }, { Parse::Type::Array, args } } });
}
effects_start = effects_match.suffix().first;
}
tags_start = tags_match.suffix().first;
segments.push_back({ Parse::Type::Array, std::vector<Parse::Object>{ { Parse::Type::String, inner }, { Parse::Type::Array, effects } } });
segments.push_back({ Parse::Type::Array, Vector<Parse::Object>{ { Parse::Type::String, inner }, { Parse::Type::Array, effects } } });
}
if (has_markup) {
@ -396,15 +396,15 @@ namespace {
if (!end.empty())
segments.push_back({ Parse::Type::Array, {
{ Parse::Type::String, end },
{ Parse::Type::Array, std::vector<Parse::Object>{} }
{ Parse::Type::Array, Vector<Parse::Object>{} }
}});
return { Parse::Type::Array, segments };
}
else {
return { Parse::Type::Array, std::vector<Parse::Object>{
return { Parse::Type::Array, Vector<Parse::Object>{
{ Parse::Type::Array, {
{ Parse::Type::String, s} , { Parse::Type::Array, std::vector<Parse::Object>{} }
{ Parse::Type::String, s} , { Parse::Type::Array, Vector<Parse::Object>{} }
} } }
};
}
@ -489,7 +489,7 @@ namespace NVL::Parse {
if (t != Type::String && t != Type::Symbol) throw std::runtime_error("Bad type when constructing object!");
}
Object::Object(Type t, const std::vector<Object>& v) : type(t), value(v) {
Object::Object(Type t, const Vector<Object>& v) : type(t), value(v) {
if (t != Type::Array && t != Type::Subexpression) throw std::runtime_error("Bad type when constructing object!");
}
@ -500,14 +500,14 @@ namespace NVL::Parse {
if (t != Type::String && t != Type::Symbol) throw std::runtime_error("Bad type when constructing object!");
}
Object::Object(Type t, std::vector<Object>&& v) : type(t), value(std::move(v)) {
Object::Object(Type t, Vector<Object>&& v) : type(t), value(std::move(v)) {
if (t != Type::Array && t != Type::Subexpression) throw std::runtime_error("Bad type when constructing object!");
}
std::vector<Scene> ParseFile(const std::string& path) {
Vector<Scene> ParseFile(const std::string& path) {
String f = read_file_to_string(path);
std::vector<Scene> list {}; // Vector of scenes which each contain a vector of Parses
Vector<Scene> list {}; // Vector of scenes which each contain a vector of Parses
for (size_t i = 0; i < f.length(); i++) {
list.push_back(ParseScene(f, i));
}

View file

@ -1,5 +1,4 @@
#pragma once
#include <vector>
#include <variant>
#include <string>
#include <utility>
@ -13,22 +12,22 @@ namespace NVL::Parse {
Object() = delete;
Object(const Number& v);
Object(Type t, const String& v);
Object(Type t, const std::vector<Object>& v);
Object(Type t, const Vector<Object>& v);
Object(Number&& v);
Object(Type t, String&& v);
Object(Type t, std::vector<Object>&& v);
Object(Type t, Vector<Object>&& v);
Type type;
std::variant<
Number,
String,
std::vector<Object>
Vector<Object>
> value;
};
using Command = std::vector<Object>;
using Command = Vector<Object>;
class Scene {
std::vector<Command> commands{};
Vector<Command> commands{};
public:
String name;
Scene(const String& name) : name(name) {}
@ -43,5 +42,5 @@ namespace NVL::Parse {
}
};
std::vector<Scene> ParseFile(const std::string& path);
Vector<Scene> ParseFile(const std::string& path);
}