2015-08-09 19:43:47 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
#include "tsvm.hpp"
|
|
|
|
|
|
|
|
#include "trainscript.tab.h"
|
|
|
|
#include "trainscript.l.h"
|
|
|
|
|
|
|
|
namespace trainscript
|
|
|
|
{
|
|
|
|
Module *VM::load(const void *buffer, size_t length)
|
|
|
|
{
|
|
|
|
void *internalStorage = malloc(length);
|
|
|
|
memcpy(internalStorage, buffer, length);
|
|
|
|
|
|
|
|
Module *module = new Module();
|
|
|
|
|
|
|
|
ParserData data;
|
|
|
|
data.buffer = reinterpret_cast<char*>(internalStorage);
|
|
|
|
data.index = 0;
|
|
|
|
data.length = length;
|
|
|
|
data.module = module;
|
|
|
|
yylex_init_extra(&data, &data.scanner);
|
|
|
|
|
|
|
|
bool valid = yyparse(&data) == 0;
|
|
|
|
|
|
|
|
yylex_destroy(data.scanner);
|
|
|
|
free(internalStorage);
|
|
|
|
|
|
|
|
if(valid) {
|
|
|
|
return module;
|
|
|
|
} else {
|
|
|
|
delete module;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Module *VM::load(const char *text)
|
|
|
|
{
|
|
|
|
return VM::load(reinterpret_cast<const void*>(text), static_cast<size_t>(strlen(text)));
|
|
|
|
}
|
|
|
|
|
|
|
|
Module::Module() :
|
|
|
|
variables()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Module::~Module()
|
|
|
|
{
|
|
|
|
for(auto val : methods) {
|
|
|
|
delete val.second;
|
|
|
|
}
|
|
|
|
for(auto val : variables) {
|
|
|
|
delete val.second;
|
|
|
|
}
|
|
|
|
}
|
2015-08-09 22:15:36 +00:00
|
|
|
|
|
|
|
Variable Method::invoke(std::vector<Variable> arguments)
|
|
|
|
{
|
|
|
|
LocalContext context;
|
|
|
|
if(this->returnValue.second.type.usable()) {
|
|
|
|
context.insert({ this->returnValue.first, &this->returnValue.second });
|
|
|
|
}
|
|
|
|
if(arguments.size() != this->arguments.size()) {
|
|
|
|
printf("MECKER anzahl!\n");
|
|
|
|
return Variable();
|
|
|
|
}
|
|
|
|
for(size_t i = 0; i < this->arguments.size(); i++) {
|
|
|
|
if(this->arguments[i].second.type != arguments[i].type) {
|
|
|
|
printf("MECKER argtyp!\n");
|
|
|
|
return Variable();
|
|
|
|
}
|
|
|
|
context.insert({this->arguments[i].first, new Variable(arguments[i]) });
|
|
|
|
}
|
|
|
|
for(auto local : this->locals) {
|
|
|
|
context.insert({ local.first, new Variable(local.second) });
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this->block->execute(context);
|
|
|
|
|
|
|
|
return this->returnValue.second;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace ops
|
|
|
|
{
|
|
|
|
Variable add(Variable lhs, Variable rhs)
|
|
|
|
{
|
|
|
|
switch(lhs.type.id) {
|
|
|
|
case TypeID::Int:return mkvar(lhs.integer + rhs.integer);
|
|
|
|
case TypeID::Real: return mkvar(lhs.real + rhs.real);
|
|
|
|
default: printf("addition not supported for %s.\n", typeName(lhs.type.id)); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Variable subtract(Variable lhs, Variable rhs)
|
|
|
|
{
|
|
|
|
switch(lhs.type.id) {
|
|
|
|
case TypeID::Int: return mkvar(lhs.integer - rhs.integer);
|
|
|
|
case TypeID::Real:return mkvar(lhs.real - rhs.real);
|
|
|
|
default: printf("subtraction not supported for %s.\n", typeName(lhs.type.id)); return mkvar(TypeID::Void);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Variable multiply(Variable lhs, Variable rhs)
|
|
|
|
{
|
|
|
|
switch(lhs.type.id) {
|
|
|
|
case TypeID::Int: return mkvar(lhs.integer * rhs.integer);
|
|
|
|
case TypeID::Real: return mkvar(lhs.real * rhs.real);
|
|
|
|
default: printf("multiplication not supported for %s.\n", typeName(lhs.type.id)); return mkvar(TypeID::Void);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Variable divide(Variable lhs, Variable rhs)
|
|
|
|
{
|
|
|
|
switch(lhs.type.id) {
|
|
|
|
case TypeID::Int: return mkvar(lhs.integer / rhs.integer);
|
|
|
|
case TypeID::Real: return mkvar(lhs.real / rhs.real);
|
|
|
|
default: printf("division not supported for %s.\n", typeName(lhs.type.id)); return mkvar(TypeID::Void);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Variable modulo(Variable lhs, Variable rhs)
|
|
|
|
{
|
|
|
|
switch(lhs.type.id) {
|
|
|
|
case TypeID::Int: return mkvar(lhs.integer % rhs.integer);
|
|
|
|
// case TypeID::Real: mkvar(lhs.real % rhs.real);
|
|
|
|
default: printf("modulo not supported for %s.\n", typeName(lhs.type.id)); return mkvar(TypeID::Void);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-08-09 19:43:47 +00:00
|
|
|
}
|