Skip to content

Commit

Permalink
Merge pull request #14 from sillydan1/feature/tree_interpreter
Browse files Browse the repository at this point in the history
Feature/tree interpreter
  • Loading branch information
sillydan1 committed Dec 11, 2022
2 parents d3df7d1 + f74524e commit c1beaf0
Show file tree
Hide file tree
Showing 23 changed files with 596 additions and 118 deletions.
40 changes: 0 additions & 40 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,43 +40,3 @@ jobs:
with:
name: library
path: ${{ github.workspace }}/build/libexpr.so
build-windows:
if: ${{ github.event.pull_request.draft == false }}
name: Build For MS Windows Systems
runs-on: windows-latest
env:
CC: x86_64-w64-mingw32-gcc
CXX: x86_64-w64-mingw32-g++
LD: x86_64-w64-mingw32-ld
AR: x86_64-w64-mingw32-ar
AS: x86_64-w64-mingw32-as
NM: x86_64-w64-mingw32-nm
STRIP: x86_64-w64-mingw32-strip
RANLIB: x86_64-w64-mingw32-ranlib
DLLTOOL: x86_64-w64-mingw32-dlltool
OBJDUMP: x86_64-w64-mingw32-objdump
RESCOMP: x86_64-w64-mingw32-windres
steps:
- name: Setup CygWin
uses: egor-tensin/setup-cygwin@v3
with:
packages: flex bison mingw-w64-gcc
- name: Install MinGW
uses: egor-tensin/setup-mingw@v2
with:
cygwin: 1
- name: Checkout Repository
uses: actions/checkout@v2
- name: Initialize Submodules
uses: snickerbockers/submodules-init@v4
- name: Create Build Environment
run: cmake -E make_directory ${{github.workspace}}/build
- name: Configure CMake
shell: bash
working-directory: ${{github.workspace}}/build
run: cmake $GITHUB_WORKSPACE -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc
- name: Build
working-directory: ${{github.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE -j 8
29 changes: 27 additions & 2 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [v2.1.0](https://github.com/sillydan1/expr/releases/tag/v2.1.0) - 2022-12-11

<small>[Compare with v2.0.0](https://github.com/sillydan1/expr/compare/v2.0.0...v2.1.0)</small>

### Bug Fixes
- Add a lookup function to symbol table ([797cdee](https://github.com/sillydan1/expr/commit/797cdeeb170cc1aa465adc0331efafe8a616b671) by Asger Gitz-Johansen).
- Removed tree_interpreter functionality in the demo ([1563f5f](https://github.com/sillydan1/expr/commit/1563f5f0689f45371d14bf4752d9998e23d681f4) by Asger Gitz-Johansen).

### Features
- Add as_string function ([b1bf12a](https://github.com/sillydan1/expr/commit/b1bf12a71cfc4270572b430274e979773ae945a2) by Asger Gitz-Johansen).
- Add tree_compiler class ([feba171](https://github.com/sillydan1/expr/commit/feba17187e915172d2dbb832a089291839611475) by Asger Gitz-Johansen).
- Extend the driver interface be aware of the access modifier ([418ce71](https://github.com/sillydan1/expr/commit/418ce71200423b321767698743ae754ed5cb1e78) by Asger Gitz-Johansen).
- Add variables scopes in the form of trees of symboltables ([8f5ec2b](https://github.com/sillydan1/expr/commit/8f5ec2b9de720562d1ad931ba29dc2f0283699de) by Asger Gitz-Johansen).


## [v2.0.0](https://github.com/sillydan1/expr/releases/tag/v2.0.0) - 2022-09-19

<small>[Compare with v1.7.0](https://github.com/sillydan1/expr/compare/v1.7.0...v2.0.0)</small>
Expand Down Expand Up @@ -52,7 +67,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [v1.4.1](https://github.com/sillydan1/expr/releases/tag/v1.4.1) - 2022-07-19

<small>[Compare with v1.3.2](https://github.com/sillydan1/expr/compare/v1.3.2...v1.4.1)</small>
<small>[Compare with v1.4.0](https://github.com/sillydan1/expr/compare/v1.4.0...v1.4.1)</small>


## [v1.4.0](https://github.com/sillydan1/expr/releases/tag/v1.4.0) - 2022-07-19

<small>[Compare with v1.3.2](https://github.com/sillydan1/expr/compare/v1.3.2...v1.4.0)</small>


## [v1.3.2](https://github.com/sillydan1/expr/releases/tag/v1.3.2) - 2022-05-02
Expand All @@ -77,7 +97,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [v1.1.2](https://github.com/sillydan1/expr/releases/tag/v1.1.2) - 2022-03-05

<small>[Compare with v1.0.0](https://github.com/sillydan1/expr/compare/v1.0.0...v1.1.2)</small>
<small>[Compare with v1.1.0](https://github.com/sillydan1/expr/compare/v1.1.0...v1.1.2)</small>


## [v1.1.0](https://github.com/sillydan1/expr/releases/tag/v1.1.0) - 2022-03-05

<small>[Compare with v1.0.0](https://github.com/sillydan1/expr/compare/v1.0.0...v1.1.0)</small>


## [v1.0.0](https://github.com/sillydan1/expr/releases/tag/v1.0.0) - 2022-03-05
Expand Down
8 changes: 5 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
cmake_minimum_required(VERSION 3.21)
# to generate a changelog, use: (python3 -m pip install git-changelog)
# $ git-changelog -s conventional . -o CHANGELOG.MD
project(expr VERSION 2.0.0)
project(expr VERSION 2.1.0)
include(cmake/CPM.cmake)
configure_file(src/config.h.in config.h)
set(CMAKE_CXX_STANDARD 20)
Expand All @@ -33,12 +33,12 @@ option(ENABLE_Z3 "Enables the download and compilation of the expr::z3_driver dr

# DEPENDENCIES
CPMAddPackage("gh:yalibs/[email protected]")
CPMAddPackage("gh:yalibs/yatree@1.0.1")
CPMAddPackage("gh:yalibs/yatree@1.2.1")
CPMAddPackage("gh:yalibs/[email protected]")
CPMAddPackage("gh:yalibs/[email protected]")
CPMAddPackage("gh:sillydan1/[email protected]")
if(ENABLE_Z3)
CPMAddPackage("gh:Z3Prover/z3#z3-4.11.0")
CPMAddPackage("gh:Z3Prover/z3#z3-4.11.2")
endif()

set(${PROJECT_NAME}_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "expr_BUILD_DIR" FORCE)
Expand Down Expand Up @@ -74,6 +74,8 @@ add_library(${PROJECT_NAME} SHARED
${BISON_expr_parser_OUTPUTS}
${FLEX_expr_lexer_OUTPUTS}
src/drivers/interpreter.cpp
src/drivers/tree_interpreter.cpp
src/drivers/tree_compiler.cpp
src/drivers/compiler.cpp

src/clock.cpp
Expand Down
1 change: 1 addition & 0 deletions include/drivers/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace expr {
auto get_symbol(const std::string &identifier) -> syntax_tree_t override;
void add_tree(const syntax_tree_t& tree) override;
void add_tree(const std::string& identifier, const syntax_tree_t& tree) override;
void add_tree(const std::string& access_modifier, const std::string& identifier, const syntax_tree_t& tree) override;

compiled_expr_collection_t trees;
};
Expand Down
7 changes: 5 additions & 2 deletions include/drivers/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
YY_DECL;

namespace expr {
// TODO: Break this into an interface (functions) and a base abstract class (basic implementation)
using symbol_table_ref_t = std::reference_wrapper<const expr::symbol_table_t>;
using symbol_table_ref_collection_t = std::vector<std::reference_wrapper<const expr::symbol_table_t>>;
struct driver {
Expand All @@ -40,10 +41,12 @@ namespace expr {
virtual auto get_symbol(const std::string &identifier) -> syntax_tree_t = 0;
virtual void add_tree(const syntax_tree_t& tree) = 0;
virtual void add_tree(const std::string& identifier, const syntax_tree_t& tree) = 0;
auto contains(const std::string& identifier) const -> bool {
virtual void add_tree(const std::string& access_modifier, const std::string& identifier, const syntax_tree_t& tree) = 0;
virtual auto contains(const std::string& identifier) const -> bool {
return find(identifier) != end;
}
auto find(const std::string& identifier) const -> expr::symbol_table_t::const_iterator {
virtual auto find(const std::string& identifier) const -> expr::symbol_table_t::const_iterator {
// TODO: Tree of environments
for(auto& env : environments) {
auto env_it = env.get().find(identifier);
if(env_it != env.get().end())
Expand Down
51 changes: 51 additions & 0 deletions include/drivers/generic_symbol_operator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* MIT License
*
* Copyright (c) 2022 Asger Gitz-Johansen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef EXPR_GENERIC_SYMBOL_OPERATOR_H
#define EXPR_GENERIC_SYMBOL_OPERATOR_H
#include "operations.h"

namespace expr {
struct generic_symbol_operator : public arithmetic_operator, boolean_operator, compare_operator {
auto add(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ::operator+(a,b); };
auto sub(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a - b; };
auto mul(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a * b; };
auto div(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a / b; };
auto mod(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a % b; };
auto pow(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a ^ b; };

auto _not(const symbol_value_t &a) const -> symbol_value_t override { return not_(a); }
auto _and(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return and_(a,b); }
auto _or(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return or_(a,b); }
auto _xor(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return xor_(a,b); }
auto _implies(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return implies_(a,b); }

auto gt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return gt_(a,b); }
auto ge(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ge_(a,b); }
auto ee(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ee_(a,b); }
auto ne(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ne_(a,b); }
auto le(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return le_(a,b); }
auto lt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return lt_(a,b); }
};
}

#endif //EXPR_GENERIC_SYMBOL_OPERATOR_H
24 changes: 3 additions & 21 deletions include/drivers/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
#include "operations.h"
#include "drivers/driver.h"
#include "compiler.h"
#include "generic_symbol_operator.h"

namespace expr {
struct interpreter : public driver, arithmetic_operator, boolean_operator, compare_operator {
struct interpreter : public driver, generic_symbol_operator {
interpreter(std::initializer_list<symbol_table_ref_t> environments);
~interpreter() override = default;

Expand All @@ -37,26 +38,7 @@ namespace expr {
auto get_symbol(const std::string& identifier) -> syntax_tree_t override;
void add_tree(const syntax_tree_t& tree) override;
void add_tree(const std::string& identifier, const syntax_tree_t& tree) override;

auto add(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ::operator+(a,b); };
auto sub(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a - b; };
auto mul(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a * b; };
auto div(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a / b; };
auto mod(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a % b; };
auto pow(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a ^ b; };

auto _not(const symbol_value_t &a) const -> symbol_value_t override { return not_(a); }
auto _and(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return and_(a,b); }
auto _or(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return or_(a,b); }
auto _xor(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return xor_(a,b); }
auto _implies(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return implies_(a,b); }

auto gt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return gt_(a,b); }
auto ge(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ge_(a,b); }
auto ee(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ee_(a,b); }
auto ne(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ne_(a,b); }
auto le(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return le_(a,b); }
auto lt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return lt_(a,b); }
void add_tree(const std::string& access_modifier, const std::string& identifier, const syntax_tree_t& tree) override;

symbol_table_t result{};
symbol_value_t expression_result{};
Expand Down
46 changes: 46 additions & 0 deletions include/drivers/tree_compiler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* MIT License
*
* Copyright (c) 2022 Asger Gitz-Johansen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef EXPR_TREE_COMPILER_H
#define EXPR_TREE_COMPILER_H
#include "tree_driver.h"

namespace expr {
struct tree_compiler : tree_driver {
using compiled_expr_t = syntax_tree_t;
#ifndef NDEBUG
using compiled_expr_collection_t = std::map<std::string, compiled_expr_t>;
#else
using compiled_expr_collection_t = std::unordered_map<std::string, compiled_expr_t>;
#endif
explicit tree_compiler(const symbol_table_tree_t::iterator& scope) : tree_driver{scope}, trees{} {}
int parse(const std::string &f) override;
auto get_symbol(const std::string &identifier) -> syntax_tree_t override;
void add_tree(const syntax_tree_t& tree) override;
void add_tree(const std::string& identifier, const syntax_tree_t& tree) override;
void add_tree(const std::string& access_modifier, const std::string& identifier, const syntax_tree_t& tree) override;

compiled_expr_collection_t trees;
};
}

#endif //EXPR_TREE_COMPILER_H
47 changes: 47 additions & 0 deletions include/drivers/tree_driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* MIT License
*
* Copyright (c) 2022 Asger Gitz-Johansen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef EXPR_TREE_DRIVER_H
#define EXPR_TREE_DRIVER_H
#include "driver.h"

namespace expr {
struct tree_driver : public driver {
tree_driver(const symbol_table_tree_t::iterator& it) : driver{}, it{it} {}
auto find(const std::string& identifier) const -> expr::symbol_table_t::const_iterator override {
auto* x = &(*it);
while(x) {
auto i = x->node.find(identifier);
if(i != x->node.end())
return i;
if(!x->parent().has_value())
return end;
x = x->parent().value();
}
return end;
}
private:
symbol_table_tree_t::iterator it;
};
}

#endif //EXPR_TREE_DRIVER_H
Loading

0 comments on commit c1beaf0

Please sign in to comment.