Work to add C style entry points to library that allow most functionality

This commit is contained in:
Deukhoofd 2019-06-05 17:46:46 +02:00
parent 6206fef4c5
commit 43dede9ae2
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
14 changed files with 169 additions and 79 deletions

View File

@ -7,21 +7,9 @@ include_directories(extern)
file(GLOB_RECURSE SRC_FILES "src/*.cpp" "src/*.hpp")
file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp")
add_library(PorygonLang ${SRC_FILES})
add_library(PorygonLang SHARED ${SRC_FILES})
add_executable(PorygonLangTests
${SRC_FILES}
${TEST_FILES})
target_compile_definitions(PorygonLangTests PRIVATE TESTS_BUILD)
find_package( Boost )
include_directories(
${BOOST_INCLUDE_DIRS}
)
target_link_libraries(PorygonLang ${Boost_LIBRARIES} )
target_link_libraries(PorygonLangTests ${Boost_LIBRARIES} )
include(CTest)
target_compile_definitions(PorygonLangTests PRIVATE TESTS_BUILD)

View File

@ -0,0 +1,45 @@
#include "Diagnostics.hpp"
vector<Diagnostic> Diagnostics::GetDiagnostics() {
return _diagnostics;
}
void Diagnostics::Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length) {
_diagnostics.emplace_back(severity, code, start, length);
if (severity >= DiagnosticSeverity::Error){
_hasErrors = true;
}
}
void Diagnostics::LogError(DiagnosticCode code, unsigned int start, unsigned int length) {
Log(DiagnosticSeverity::Error, code, start, length);
}
void Diagnostics::LogWarning(DiagnosticCode code, unsigned int start, unsigned int length) {
Log(DiagnosticSeverity::Warning, code, start, length);
}
void Diagnostics::LogInfo(DiagnosticCode code, unsigned int start, unsigned int length) {
Log(DiagnosticSeverity::Info, code, start, length);
}
bool Diagnostics::HasErrors() {
return _hasErrors;
}
int Diagnostics::DiagnosticsCount() {
return _diagnostics.size();
}
Diagnostic *Diagnostics::GetDiagnosticAt(int position) {
return &_diagnostics[position];
}
extern "C" int GetDiagnosticsCount (Diagnostics* diagnostics){
return diagnostics->DiagnosticsCount();
}
extern "C" Diagnostic* GetDiagnosticAt(Diagnostics* diagnostics, int position){
return diagnostics->GetDiagnosticAt(position);
}

View File

@ -21,31 +21,18 @@ public:
_diagnostics.clear();
}
void Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length){
_diagnostics.emplace_back(severity, code, start, length);
if (severity >= DiagnosticSeverity::Error){
_hasErrors = true;
}
}
void LogError(DiagnosticCode code, unsigned int start, unsigned int length){
Log(DiagnosticSeverity::Error, code, start, length);
}
void Log(DiagnosticSeverity severity, DiagnosticCode code, unsigned int start, unsigned int length);
void LogError(DiagnosticCode code, unsigned int start, unsigned int length);
void LogWarning(DiagnosticCode code, unsigned int start, unsigned int length);
void LogInfo(DiagnosticCode code, unsigned int start, unsigned int length);
void LogWarning(DiagnosticCode code, unsigned int start, unsigned int length){
Log(DiagnosticSeverity::Warning, code, start, length);
}
bool HasErrors();
void LogInfo(DiagnosticCode code, unsigned int start, unsigned int length){
Log(DiagnosticSeverity::Info, code, start, length);
}
vector<Diagnostic> GetDiagnostics();
bool HasErrors(){
return _hasErrors;
}
int DiagnosticsCount();
vector<Diagnostic> GetDiagnostics(){
return _diagnostics;
}
Diagnostic* GetDiagnosticAt(int position);
};

View File

@ -69,8 +69,8 @@ shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(BoundBinaryExpressio
throw;
std::ostringstream strs;
auto left = this -> EvaluateStringExpression(expression->GetLeft());
strs << left->EvaluateString();
strs << *left->EvaluateString();
auto right = this -> EvaluateExpression(expression->GetRight());
strs << right->EvaluateString();
strs << *right->EvaluateString();
return make_shared<StringEvalValue>(strs.str());
}

View File

@ -0,0 +1,46 @@
#import "EvalValue.hpp"
#include <cstring>
extern "C" {
TypeClass GetEvalValueTypeClass(EvalValue* v){
return v->GetType().get()->GetClass();
}
ScriptType* GetEvalValueType(EvalValue* v){
return v->GetType().get();
}
int64_t EvaluateEvalValueInteger(EvalValue* v){
return v->EvaluateInteger();
}
double EvaluateEvalValueFloat(EvalValue* v){
return v->EvaluateFloat();
}
bool EvaluateEvalValueBool(EvalValue* v){
return v->EvaluateBool();
}
const char* EvaluateEvalValueString(EvalValue* v){
return v->EvaluateString() -> c_str();
}
}
#ifdef TESTS_BUILD
#include <catch.hpp>
#include "../src/Script.hpp"
TEST_CASE( "Evaluate String", "[integration]" ) {
auto script = Script::Create("\"foo bar\"");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto lastValue = script->GetLastValue();
REQUIRE(std::strcmp(EvaluateEvalValueString(lastValue), "foo bar") == 0);
delete script;
}
#endif

View File

@ -31,7 +31,7 @@ public:
virtual bool EvaluateBool(){
throw EvaluationException("Can't evaluate this EvalValue as bool.");
}
virtual std::string EvaluateString(){
virtual std::string* EvaluateString(){
throw EvaluationException("Can't evaluate this EvalValue as string.");
}
};
@ -62,12 +62,6 @@ public:
return false;
return this->EvaluateBool() == b->EvaluateBool();
};
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
};
#endif //PORYGONLANG_EVALVALUE_HPP

View File

@ -42,12 +42,6 @@ public:
return _value;
}
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
shared_ptr<EvalValue> Clone() final{
return make_shared<IntegerEvalValue>(_value);
}
@ -70,12 +64,6 @@ public:
return _value;
}
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
shared_ptr<EvalValue> Clone() final{
return make_shared<FloatEvalValue>(_value);
}

View File

@ -22,11 +22,11 @@ public:
bool operator ==(EvalValue* b) final{
if (b->GetType()->GetClass() != TypeClass::String)
return false;
return this->_value == b->EvaluateString();
return this->_value == *b->EvaluateString();
};
string EvaluateString() final{
return _value;
string* EvaluateString() final{
return &_value;
}
shared_ptr<EvalValue> Clone() final{

View File

@ -1,3 +1,7 @@
#include <utility>
#include <utility>
#include <memory>
#include "Evaluator.hpp"
@ -36,7 +40,7 @@ void Evaluator::EvaluateBlockStatement(BoundBlockStatement* statement) {
void Evaluator::EvaluateExpressionStatement(BoundExpressionStatement *statement) {
// Save new value
this->_scriptData->_lastValue = this -> EvaluateExpression(statement->GetExpression());
this->_lastValue = this -> EvaluateExpression(statement->GetExpression());
}
void Evaluator::EvaluateAssignmentStatement(BoundAssignmentStatement *statement) {
@ -169,4 +173,5 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression*
this->EvaluateBlockStatement(function->GetInnerBlock().get());
return nullptr;
}
}

View File

@ -15,6 +15,7 @@ using namespace std;
class Evaluator {
shared_ptr<EvalValue> _result;
shared_ptr<EvalValue> _lastValue;
Script* _scriptData;
EvaluationScope* _evaluationScope;
@ -57,7 +58,9 @@ public:
return _evaluationScope;
}
EvalValue* GetLastValue(){
return _lastValue.get();
}
};

View File

@ -14,18 +14,17 @@ Script* Script::Create(string script) {
Script::Script() {
Diagnostics = new class Diagnostics();
_evaluator = new Evaluator(this);
_lastValue = nullptr;
BoundScript = nullptr;
_boundScript = nullptr;
_scriptVariables = new unordered_map<int, shared_ptr<EvalValue>>(0);
}
void Script::Evaluate() {
_evaluator->Evaluate(BoundScript);
_evaluator->Evaluate(_boundScript);
}
Script::~Script() {
delete this -> Diagnostics;
delete this -> BoundScript;
delete this -> _boundScript;
delete this -> _evaluator;
this->_scriptVariables->clear();
delete this->_scriptVariables;
@ -43,7 +42,7 @@ void Script::Parse(string script) {
if (!Diagnostics->HasErrors()){
unordered_map<int, BoundVariable*> scriptScope;
auto bindScope = new BoundScope(&scriptScope);
this->BoundScript = Binder::Bind(this, parseResult, bindScope);
this->_boundScript = Binder::Bind(this, parseResult, bindScope);
for (const auto& v : scriptScope){
this->_scriptVariables -> insert({v.first, nullptr});
delete v.second;
@ -62,3 +61,30 @@ bool Script::HasVariable(const string &key) {
return f != _scriptVariables->end();
}
EvalValue *Script::GetLastValue() {
return _evaluator->GetLastValue();
}
extern "C" {
Script* CreateScript(char * s){
return Script::Create(s);
}
void EvaluateScript(Script* script){
script->Evaluate();
}
EvalValue* GetLastValue(Script* script){
return script->GetLastValue();
}
bool HasVariable(Script* script, const char* key){
return script->HasVariable(key);
}
EvalValue* GetVariable(Script* script, const char* key){
return script->GetVariable(key);
}
}

View File

@ -1,9 +1,7 @@
#include <utility>
#ifndef PORYGONLANG_SCRIPT_HPP
#define PORYGONLANG_SCRIPT_HPP
#include <utility>
#include <string>
#include <unordered_map>
#include "Diagnostics/Diagnostics.hpp"
@ -19,14 +17,12 @@ using namespace std;
class Script {
friend class Evaluator;
shared_ptr<EvalValue> _lastValue;
Evaluator* _evaluator;
unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables;
BoundScriptStatement* _boundScript;
explicit Script();
void Parse(string script);
BoundScriptStatement* BoundScript;
public:
static Script* Create(string script);
Diagnostics* Diagnostics;
@ -35,12 +31,12 @@ public:
void Evaluate();
EvalValue* GetLastValue(){
return _lastValue.get();
};
EvalValue* GetLastValue();
EvalValue* GetVariable(const string& key);
bool HasVariable(const string& key);
};

View File

@ -0,0 +1,3 @@

View File

@ -9,16 +9,25 @@ TEST_CASE( "Simple String", "[integration]" ) {
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto lastValue = script->GetLastValue();
REQUIRE(lastValue->EvaluateString() == "foo bar");
REQUIRE(*lastValue->EvaluateString() == "foo bar");
delete script;
}
TEST_CASE( "String Concat", "[integration]" ) {
auto script = Script::Create("\"foo\" + \"bar\"");
auto script = Script::Create(R"("foo" + "bar")");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto lastValue = script->GetLastValue();
REQUIRE(lastValue->EvaluateString() == "foobar");
REQUIRE(*lastValue->EvaluateString() == "foobar");
delete script;
}
TEST_CASE( "String Concat 2", "[integration]" ) {
auto script = Script::Create("'foo' + 'bar'");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto lastValue = script->GetLastValue();
REQUIRE(*lastValue->EvaluateString() == "foobar");
delete script;
}