thoughts about compiler
This commit is contained in:
parent
bdf80f37e6
commit
38496209c0
9 changed files with 78 additions and 47 deletions
|
@ -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({
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
28
NVL/Compiler.cpp
Normal 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
1
NVL/Compiler.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include "Common.h"
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
13
NVL/Parser.h
13
NVL/Parser.h
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue