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 SRC_FILES "src/*.cpp" "src/*.hpp")
file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp") file(GLOB_RECURSE TEST_FILES "tests/*.cpp" "tests/*.hpp")
add_library(PorygonLang ${SRC_FILES}) add_library(PorygonLang SHARED ${SRC_FILES})
add_executable(PorygonLangTests add_executable(PorygonLangTests
${SRC_FILES} ${SRC_FILES}
${TEST_FILES}) ${TEST_FILES})
target_compile_definitions(PorygonLangTests PRIVATE TESTS_BUILD) 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)

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

View File

@ -69,8 +69,8 @@ shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(BoundBinaryExpressio
throw; throw;
std::ostringstream strs; std::ostringstream strs;
auto left = this -> EvaluateStringExpression(expression->GetLeft()); auto left = this -> EvaluateStringExpression(expression->GetLeft());
strs << left->EvaluateString(); strs << *left->EvaluateString();
auto right = this -> EvaluateExpression(expression->GetRight()); auto right = this -> EvaluateExpression(expression->GetRight());
strs << right->EvaluateString(); strs << *right->EvaluateString();
return make_shared<StringEvalValue>(strs.str()); 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(){ virtual bool EvaluateBool(){
throw EvaluationException("Can't evaluate this EvalValue as bool."); 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."); throw EvaluationException("Can't evaluate this EvalValue as string.");
} }
}; };
@ -62,12 +62,6 @@ public:
return false; return false;
return this->EvaluateBool() == b->EvaluateBool(); return this->EvaluateBool() == b->EvaluateBool();
}; };
std::string EvaluateString() final{
std::ostringstream strs;
strs << _value;
return strs.str();
}
}; };
#endif //PORYGONLANG_EVALVALUE_HPP #endif //PORYGONLANG_EVALVALUE_HPP

View File

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

View File

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

View File

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

View File

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

View File

@ -14,18 +14,17 @@ Script* Script::Create(string script) {
Script::Script() { Script::Script() {
Diagnostics = new class Diagnostics(); Diagnostics = new class Diagnostics();
_evaluator = new Evaluator(this); _evaluator = new Evaluator(this);
_lastValue = nullptr; _boundScript = nullptr;
BoundScript = nullptr;
_scriptVariables = new unordered_map<int, shared_ptr<EvalValue>>(0); _scriptVariables = new unordered_map<int, shared_ptr<EvalValue>>(0);
} }
void Script::Evaluate() { void Script::Evaluate() {
_evaluator->Evaluate(BoundScript); _evaluator->Evaluate(_boundScript);
} }
Script::~Script() { Script::~Script() {
delete this -> Diagnostics; delete this -> Diagnostics;
delete this -> BoundScript; delete this -> _boundScript;
delete this -> _evaluator; delete this -> _evaluator;
this->_scriptVariables->clear(); this->_scriptVariables->clear();
delete this->_scriptVariables; delete this->_scriptVariables;
@ -43,7 +42,7 @@ void Script::Parse(string script) {
if (!Diagnostics->HasErrors()){ if (!Diagnostics->HasErrors()){
unordered_map<int, BoundVariable*> scriptScope; unordered_map<int, BoundVariable*> scriptScope;
auto bindScope = new BoundScope(&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){ for (const auto& v : scriptScope){
this->_scriptVariables -> insert({v.first, nullptr}); this->_scriptVariables -> insert({v.first, nullptr});
delete v.second; delete v.second;
@ -62,3 +61,30 @@ bool Script::HasVariable(const string &key) {
return f != _scriptVariables->end(); 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 #ifndef PORYGONLANG_SCRIPT_HPP
#define PORYGONLANG_SCRIPT_HPP #define PORYGONLANG_SCRIPT_HPP
#include <utility>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include "Diagnostics/Diagnostics.hpp" #include "Diagnostics/Diagnostics.hpp"
@ -19,14 +17,12 @@ using namespace std;
class Script { class Script {
friend class Evaluator; friend class Evaluator;
shared_ptr<EvalValue> _lastValue;
Evaluator* _evaluator; Evaluator* _evaluator;
unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables; unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables;
BoundScriptStatement* _boundScript;
explicit Script(); explicit Script();
void Parse(string script); void Parse(string script);
BoundScriptStatement* BoundScript;
public: public:
static Script* Create(string script); static Script* Create(string script);
Diagnostics* Diagnostics; Diagnostics* Diagnostics;
@ -35,12 +31,12 @@ public:
void Evaluate(); void Evaluate();
EvalValue* GetLastValue(){ EvalValue* GetLastValue();
return _lastValue.get();
};
EvalValue* GetVariable(const string& key); EvalValue* GetVariable(const string& key);
bool HasVariable(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()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); script->Evaluate();
auto lastValue = script->GetLastValue(); auto lastValue = script->GetLastValue();
REQUIRE(lastValue->EvaluateString() == "foo bar"); REQUIRE(*lastValue->EvaluateString() == "foo bar");
delete script; delete script;
} }
TEST_CASE( "String Concat", "[integration]" ) { TEST_CASE( "String Concat", "[integration]" ) {
auto script = Script::Create("\"foo\" + \"bar\""); auto script = Script::Create(R"("foo" + "bar")");
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); script->Evaluate();
auto lastValue = script->GetLastValue(); 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; delete script;
} }