Work to add C style entry points to library that allow most functionality
This commit is contained in:
parent
6206fef4c5
commit
43dede9ae2
|
@ -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)
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue