Skip to content

Commit

Permalink
some work to prepare everything to describe semantics and help altoge…
Browse files Browse the repository at this point in the history
…ther
  • Loading branch information
Jakz committed Oct 25, 2018
1 parent f093776 commit bc64816
Show file tree
Hide file tree
Showing 10 changed files with 2,583 additions and 276 deletions.
2,279 changes: 2,279 additions & 0 deletions lex.yy.c

Large diffs are not rendered by default.

364 changes: 182 additions & 182 deletions src/help.cpp

Large diffs are not rendered by default.

27 changes: 14 additions & 13 deletions src/help.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@
#include "defines.h"
#include "value.h"
#include "collection.h"
#include "semantics.h"

#include <map>
#include <set>
#include <string>
#include <vector>

enum Topic
enum class Topic
{
TOPIC_NUMERICS,
TOPIC_BITWISE,
TOPIC_COLLECTIONS,
TOPIC_STACK,
TOPIC_FUNCTIONAL,
TOPIC_UTILITY,
TOPIC_LOGIC,
TOPIC_TEXT
NUMERICS,
BITWISE,
COLLECTIONS,
STACK,
FUNCTIONAL,
UTILITY,
LOGIC,
TEXT
};

struct TypeConstructor
Expand All @@ -48,9 +49,9 @@ struct OpHelpEntry
using string = std::string;

u32 io, oo;
Type i[3];
Type o[3];
Arguments i;
Arguments o;

string desc;
string ident;
Topic topic;
Expand Down Expand Up @@ -197,7 +198,7 @@ class Help
{
private:
static std::multimap<std::string, OpHelpEntry> operators;
static std::multimap<int, TypeConstructor> constructors;
static std::multimap<Type, TypeConstructor> constructors;

static void addConstructor(Type type, TypeConstructor constructor);
static void addOperator(std::string op, OpHelpEntry entry);
Expand Down
60 changes: 1 addition & 59 deletions src/instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,55 +154,6 @@ void filter(VM* vm, const T* collection, Code* predicate)
vm->push(new T(ot));
}

#include "semantics.h"

MicroCode microCode;


namespace math
{
template<typename T, typename U, typename R> struct plus { public: R operator()(T t, U u) { return t + u;} };
template<typename T, typename U, typename R> struct minus { public: R operator()(T t, U u) { return t - u;} };
template<typename T, typename U, typename R> struct times { public: R operator()(T t, U u) { return t * u;} };
template<typename T, typename U, typename R> struct divide { public: R operator()(T t, U u) { return t / u;} };

template<typename T, typename U, typename R> struct lesser { public: R operator()(T t, U u) { return t < u;} };
template<typename T, typename U, typename R> struct greater { public: R operator()(T t, U u) { return t > u;} };

}


void registerFunctions()
{
auto& mc = microCode;

mc.registerNumeric<false, math::plus>(OP_PLUS);
mc.registerNumeric<false, math::minus>(OP_MINUS);
mc.registerNumeric<false, math::times>(OP_TIMES);
mc.registerNumeric<false, math::divide>(OP_DIVIDE);

mc.registerNumeric<true, math::lesser>(OP_LESSER);
mc.registerNumeric<true, math::greater>(OP_GREATER);


mc.registerUnary({ OP_DUPE, TYPE_GENERIC }, { TYPE_GENERIC, TYPE_GENERIC }, [] (VM* vm, const Value& v1) { vm->push(v1); vm->push(v1); });

mc.registerUnary({ OP_NEG, TYPE_COLLECTION }, TYPE_COLLECTION, [] (VM* vm, const Value& v1) { vm->push(v1.collection()->size()); });


const auto& v = mc.vocabulary();

string_joiner<TypeInfo> argsJoiner("", "", ", ", [] (const auto& t) { return t.name(); }, [] (const auto& t) { return t == TYPE_NONE; });

for (const auto& term : v)
{
std::cout << Instruction(term.opcode).svalue() << " " << argsJoiner.join(term.input.t) << " -> " << argsJoiner.join(term.output.t) << std::endl;
}

std::cout << "Registered " << mc.data().size() << " terms." << std::endl;
}


std::string Instruction::svalue() const
{
if (_value.type != TYPE_OPCODE)
Expand Down Expand Up @@ -284,17 +235,8 @@ std::string Instruction::svalue() const

void Instruction::execute(VM *vm) const
{
if (_value.type != TYPE_OPCODE)
{
vm->push(_value);
return;
}

Value v1, v2, v3;

if (microCode.execute(vm, _value.opcode()))
return;


switch (_value.opcode())
{
case OP_SWAP:
Expand Down
2 changes: 2 additions & 0 deletions src/instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class Instruction final
void execute(VM *vm) const;
std::string svalue() const;

bool isValue() const { return _value.type != TYPE_OPCODE; }

Opcode opcode() const { return _value.opcode(); }
const Value& value() const { return _value; }

Expand Down
32 changes: 28 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "vm.h"
#include "instruction.h"
#include "semantics.h"

#include "help.h"

Expand All @@ -22,14 +23,15 @@

using namespace std;

extern void registerFunctions();

int main (int argc, const char * argv[])
{
registerFunctions();
Help::init();
MicroCode mc;
mc.registerDefault();

VM vm;
Help::init();

VM vm(mc);

string input;
bool finished = false;
Expand Down Expand Up @@ -108,3 +110,25 @@ int main (int argc, const char * argv[])
}
}

#include "semantics.h"

void registerUnary(Topic topic, const std::string& name, const std::string& desc,
const std::vector<std::pair<std::string,std::string>>& examples,
Signature signature, Arguments retn,
const decltype(VariantFunction::unary)&& functor)
{

}

void registerFunctions()
{
registerUnary(
Topic::COLLECTIONS, "size", "returns size of the collection",
{{"(1 2 3)_", "3"}, {"{}_", "0"}},
{ OP_NEG, TYPE_COLLECTION }, TYPE_COLLECTION,
[] (VM* vm, const Value& v1) { vm->push(v1.collection()->size()); });



}

43 changes: 42 additions & 1 deletion src/semantics.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "semantics.h"
#include "vm.h"

bool MicroCode::execute(VM* vm, Opcode opcode)
bool MicroCode::execute(VM* vm, Opcode opcode) const
{
const size_t stackSize = vm->stackSize();

Expand Down Expand Up @@ -79,3 +79,44 @@ bool MicroCode::execute(VM* vm, Opcode opcode)

return false;
}


namespace math
{
template<typename T, typename U, typename R> struct plus { public: R operator()(T t, U u) { return t + u;} };
template<typename T, typename U, typename R> struct minus { public: R operator()(T t, U u) { return t - u;} };
template<typename T, typename U, typename R> struct times { public: R operator()(T t, U u) { return t * u;} };
template<typename T, typename U, typename R> struct divide { public: R operator()(T t, U u) { return t / u;} };

template<typename T, typename U, typename R> struct lesser { public: R operator()(T t, U u) { return t < u;} };
template<typename T, typename U, typename R> struct greater { public: R operator()(T t, U u) { return t > u;} };

}

void MicroCode::registerDefault()
{
registerNumeric<false, math::plus>(OP_PLUS);
registerNumeric<false, math::minus>(OP_MINUS);
registerNumeric<false, math::times>(OP_TIMES);
registerNumeric<false, math::divide>(OP_DIVIDE);

registerNumeric<true, math::lesser>(OP_LESSER);
registerNumeric<true, math::greater>(OP_GREATER);


registerUnary({ OP_DUPE, TYPE_GENERIC }, { TYPE_GENERIC, TYPE_GENERIC }, [] (VM* vm, const Value& v1) { vm->push(v1); vm->push(v1); });

registerUnary({ OP_NEG, TYPE_COLLECTION }, TYPE_COLLECTION, [] (VM* vm, const Value& v1) { vm->push(v1.collection()->size()); });


const auto& v = vocabulary();

string_joiner<TypeInfo> argsJoiner("", "", ", ", [] (const auto& t) { return t.name(); }, [] (const auto& t) { return t == TYPE_NONE; });

for (const auto& term : v)
{
std::cout << Instruction(term.opcode).svalue() << " " << argsJoiner.join(term.input.t) << " -> " << argsJoiner.join(term.output.t) << std::endl;
}

std::cout << "Registered " << vocabulary().size() << " terms." << std::endl;
}
30 changes: 17 additions & 13 deletions src/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ struct Arguments
(t[1] == o.t[1] || (t[1] == TYPE_GENERIC && o.t[1] != TYPE_NONE)) &&
(t[2] == o.t[2] || (t[2] == TYPE_GENERIC && o.t[2] != TYPE_NONE));
}

TypeInfo& operator[](size_t index) { return t[index]; }
const TypeInfo& operator[](size_t index) const { return t[index]; }
};

struct Signature
Expand Down Expand Up @@ -142,6 +145,7 @@ class Vocabulary
terms.push_back(Term(signature.opcode, signature.args, Arguments(returnType)));
}

size_t size() const { return terms.size(); }
decltype(terms)::const_iterator begin() const { return terms.begin(); }
decltype(terms)::const_iterator end() const { return terms.end(); }
};
Expand All @@ -150,7 +154,7 @@ void registerFunctions();
class MicroCode
{
private:
std::unordered_map<Signature, VariantFunction, Signature::hash> microCode;
std::unordered_map<Signature, VariantFunction, Signature::hash> table;

struct OpcodeData
{
Expand All @@ -163,11 +167,11 @@ class MicroCode

std::array<OpcodeData, Opcode::OPCODES_COUNT> opcodeData;

const VariantFunction* findBestOverload(Signature s)
const VariantFunction* findBestOverload(Signature s) const
{
/* search for perfect match first */
auto it = microCode.find(s);
if (it != microCode.end()) return &it->second;
auto it = table.find(s);
if (it != table.end()) return &it->second;

/* then try replacing collection types with generic */
s = Signature(
Expand All @@ -177,8 +181,8 @@ class MicroCode
s.args.t[2].isCollection() ? TypeInfo(TYPE_COLLECTION) : s.args.t[2]
);

it = microCode.find(s);
if (it != microCode.end()) return &it->second;
it = table.find(s);
if (it != table.end()) return &it->second;

/* then try with generic types */
s = Signature(
Expand All @@ -187,18 +191,18 @@ class MicroCode
s.args.t[1] != TYPE_NONE ? TYPE_GENERIC : TYPE_NONE,
s.args.t[2] != TYPE_NONE ? TYPE_GENERIC : TYPE_NONE
);
it = microCode.find(s);
if (it != microCode.end()) return &it->second;
it = table.find(s);
if (it != table.end()) return &it->second;

return nullptr;
}

void emplace(const Signature& signature, VariantFunction&& function)
{
if (microCode.find(signature) != microCode.end())
if (table.find(signature) != table.end())
assert(false);

microCode.emplace(std::make_pair(signature, function));
table.emplace(std::make_pair(signature, function));
}

Vocabulary _vocabulary;
Expand All @@ -210,8 +214,6 @@ class MicroCode
}

const Vocabulary& vocabulary() { return _vocabulary; }
const decltype(microCode)& data() { return microCode; }
size_t size() { return microCode.size(); }

void registerUnary(Signature signature, Arguments retn, const decltype(VariantFunction::unary)&& function)
{
Expand Down Expand Up @@ -249,5 +251,7 @@ class MicroCode
registerNumericTemplate<integral_t, integral_t, return_type<integral_t, IS_COMPARISON>, OP>(opcode);
}

bool execute(VM* vm, Opcode opcode);
bool execute(VM* vm, Opcode opcode) const;

void registerDefault();
};
16 changes: 13 additions & 3 deletions src/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "vm.h"

#include "semantics.h"
#include "instruction.h"

void VM::execute(Code *code)
Expand All @@ -31,10 +32,19 @@ void VM::run()
{
while (exec.pc < exec.code->size() && running)
{
const Instruction &i = exec.code->at(exec.pc);
const Instruction& i = exec.code->at(exec.pc);

i.execute(this);
if (i.isValue())
push(i.value());
else
{
if (microcode.execute(this, i.opcode()))
return;

i.execute(this);

}

exec.pc++;
++exec.pc;
}
}
6 changes: 5 additions & 1 deletion src/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "instruction.h"

class Instruction;
class MicroCode;

struct ActivationRecord
{
Expand Down Expand Up @@ -46,8 +47,11 @@ class VM
bool running;
bool stackPreserve;

const MicroCode& microcode;

public:
VM() : valueStack(new stack_t()), exec(ActivationRecord(nullptr)), running(false), stackPreserve(false), lazy(NULL), memory()
VM(MicroCode& microcode) : valueStack(new stack_t()), exec(ActivationRecord(nullptr)), running(false), stackPreserve(false), lazy(NULL), memory(),
microcode(microcode)
{
}

Expand Down

0 comments on commit bc64816

Please sign in to comment.