File main.cpp
Go to the documentation of this file
#include <cstddef>
#include <cstdint>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <pdgl_defs.h>
#include <production_store.h>
#include <toml_parser.h>
#include <resolution_machine.h>
#include <iostream>
#include <random>
#ifdef ENABLE_EMSCRIPTEN
#include <emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
#endif
class PDGL_wasm {
public:
/* cppcheck-suppress passedByValue */
PDGL_wasm(std::string input, size_t stack_size, uint64_t seed);
/* cppcheck-suppress passedByValue */
PDGL_wasm(std::string input, size_t stack_size);
/* cppcheck-suppress passedByValue */
explicit PDGL_wasm(std::string input);
~PDGL_wasm();
bool run();
private:
/* cppcheck-suppress passedByValue */
void init(std::string input, size_t stack_size, uint64_t seed);
std::string language;
prodstr_store_t *store;
resmach_stack_t *stack;
size_t stack_size;
size_t seed;
};
PDGL_wasm::~PDGL_wasm()
{
if (nullptr != this->store)
{
tomlprsr_free(this->store);
}
for (size_t i = 0; i < this->stack_size; i++)
{
delete[] this->stack->partials[i].buff;
}
delete[] this->stack->partials;
delete this->stack;
}
/* cppcheck-suppress passedByValue */
PDGL_wasm::PDGL_wasm(std::string input, size_t stack_size)
{
std::random_device rd;
this->init(input, stack_size, rd());
}
/* cppcheck-suppress passedByValue */
PDGL_wasm::PDGL_wasm(std::string input, size_t stack_size, uint64_t seed)
{
this->init(input, stack_size, seed);
}
/* cppcheck-suppress passedByValue */
PDGL_wasm::PDGL_wasm(std::string input)
{
std::random_device rd;
this->init(input, 100, rd());
}
/* cppcheck-suppress passedByValue */
void PDGL_wasm::init(std::string input, size_t stack_size, uint64_t seed)
{
this->seed = seed;
this->language = input;
this->store = nullptr;
this->stack_size = stack_size;
this->stack = new resmach_stack_t{ nullptr };
this->stack->stack_len = this->stack_size;
this->stack->partials = new resmach_partial_t[this->stack_size];
for (size_t i = 0; i < this->stack_size; i++)
{
this->stack->partials[i].partial_ptr = new char[DEFS_PDGL_MAX_STRING_SIZE];
this->stack->partials[i].buff =
static_cast <const char *>(this->stack->partials[i].partial_ptr);
}
}
bool PDGL_wasm::run()
{
/* Parse the TOML */
this->store = tomlprsr_parse(static_cast <const char *>(this->language.c_str()));
if (nullptr != this->store)
{
srand(this->seed);
/* Run the machine */
unsigned int ret_val = resmach_execute(this->store, this->stack, stdout);
if (ret_val != RESMACH_EXECUTE_SUCCESS)
{
/* When error happens, diagnose it and report. */
std::string error_rpt = "";
if ((ret_val & RESMACH_EXECUTE_NO_ENTRY) == RESMACH_EXECUTE_NO_ENTRY)
{
error_rpt += "* No entry production in toml\n";
}
std::cout << "Error in execution! Found the following:" << std::endl << error_rpt
<< std::endl;
return false;
}
}
else
{
std::cout
<<
"Error in Parsing the toml! Check your toml syntax and check you have an entry production."
<< std::endl;
return false;
}
std::cout << std::endl;
return true;
}
#ifdef ENABLE_EMSCRIPTEN
EMSCRIPTEN_BINDINGS(notewptt)
{
/* clang-format off */
class_<PDGL_wasm>("PDGL")
.constructor<std::string>()
.constructor<std::string,size_t>()
.constructor<std::string,size_t,uint64_t>()
.function("run", &PDGL_wasm::run);
/* clang-format on */
}
#else
int main()
{
std::random_device rd;
/* clang-format off */
std::string str = "[[production]] \n\
name = \"entry\" \n\
type = \"pure\" \n\
replacements = [\"%{a}\"] \n\
terminals = [\"\"] \n\
\n\
[[production]] \n\
name = \"a\" \n\
type = \"pure\" \n\
replacements = [\"(%{a})\", \"%{a}%{a}\", \"\"] \n\
terminals = [\"\"]";
/* clang-format on */
for (size_t i = 0; i < 10; i++)
{
PDGL_wasm *pdgl = new PDGL_wasm(str, 100, rd());
bool success = pdgl->run();
delete pdgl;
if (!success)
{
return 1;
}
}
return 0;
}
#endif