Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
cmake_minimum_required(VERSION 3.26)
project(cura-formulae-engine)

include(CTest)

find_package(standardprojectsettings REQUIRED)
option(ENABLE_TESTS "Build with unit test" ON)
option(EXTENSIVE_WARNINGS "Build with all warnings" ON)
option(ENABLE_APPS "Build apps example" ON)

if (ENABLE_TESTS AND NOT BUILD_TESTING)
message(STATUS "ENABLE_TESTS is ON, forcing BUILD_TESTING=ON so CTest can discover tests")
set(BUILD_TESTING ON CACHE BOOL "Enable CTest" FORCE)
endif ()

find_package(spdlog REQUIRED)
find_package(lexy REQUIRED)
find_package(zeus_expected REQUIRED)
Expand Down Expand Up @@ -59,6 +66,7 @@ set(CURA_FORMULAE_ENGINE__SRC
src/ast/slice_expr.cpp
src/ast/tuple_expr.cpp
src/ast/variable_expr.cpp
src/ast/property_access_expr.cpp
src/parser/parser.cpp
src/ast/binary_expr/binary_expr.cpp
src/ast/binary_expr/add_expr.cpp
Expand Down
2 changes: 1 addition & 1 deletion conandata.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version: "1.1.0"
version: "1.2.0"
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/binary_expr/binary_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct BinaryExpr : Expr
ExprPtr lhs;
ExprPtr rhs;

BinaryExpr(ExprPtr lhs, ExprPtr rhs)
BinaryExpr(ExprPtr&& lhs, ExprPtr&& rhs)
: lhs(std::move(lhs))
, rhs(std::move(rhs))
{
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/condition_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct ConditionExpr final : Expr
ExprPtr condition;
ExprPtr else_expr;

ConditionExpr(ExprPtr then_expr, ExprPtr condition, ExprPtr else_expr)
ConditionExpr(ExprPtr&& then_expr, ExprPtr&& condition, ExprPtr&& else_expr)
: then_expr(std::move(then_expr))
, condition(std::move(condition))
, else_expr(std::move(else_expr))
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/expr_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct ExprPtr final : Expr

std::unique_ptr<Expr> ptr;

ExprPtr(std::unique_ptr<Expr> ptr)
ExprPtr(std::unique_ptr<Expr>&& ptr)
: ptr(std::move(ptr))
{
}
Expand Down
15 changes: 14 additions & 1 deletion include/cura-formulae-engine/ast/fn_application_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@ namespace CuraFormulaeEngine::ast

struct FnApplicationExpr final : Expr
{
struct KeywordArg
{
std::string name;
ExprPtr value;

[[nodiscard]] bool deepEq(const KeywordArg& other) const noexcept
{
return name == other.name && value.deepEq(other.value);
}
};

ExprPtr fn;
std::vector<ExprPtr> args;
std::vector<KeywordArg> kwargs;

FnApplicationExpr(ExprPtr fn, std::vector<ExprPtr> args)
FnApplicationExpr(ExprPtr&& fn, std::vector<ExprPtr>&& args, std::vector<KeywordArg>&& kwargs = {})
: fn(std::move(fn))
, args(std::move(args))
, kwargs(std::move(kwargs))
{
}

Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/index_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct IndexExpr final : Expr
ExprPtr array;
ExprPtr index;

IndexExpr(ExprPtr array, ExprPtr index)
IndexExpr(ExprPtr&& array, ExprPtr&& index)
: array(std::move(array))
, index(std::move(index))
{
Expand Down
4 changes: 2 additions & 2 deletions include/cura-formulae-engine/ast/list_comprehension_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct ListComprehensionExpr final : Expr
ExprPtr iterable;
std::vector<ExprPtr> conditions;

loop(ExprPtr iterator_key, ExprPtr iterable, std::vector<ExprPtr> conditions)
loop(ExprPtr&& iterator_key, ExprPtr&& iterable, std::vector<ExprPtr>&& conditions)
: iterator_key(std::move(iterator_key))
, iterable(std::move(iterable))
, conditions(std::move(conditions))
Expand All @@ -32,7 +32,7 @@ struct ListComprehensionExpr final : Expr
ExprPtr iterator;
std::vector<loop> loops;

ListComprehensionExpr(ExprPtr iterator, std::vector<loop> loops)
ListComprehensionExpr(ExprPtr&& iterator, std::vector<loop>&& loops)
: iterator(std::move(iterator))
, loops(std::move(loops))
{
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/list_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct ListExpr final : Expr
{
std::vector<ExprPtr> elements;

ListExpr(std::vector<ExprPtr> elements)
ListExpr(std::vector<ExprPtr>&& elements)
: elements(std::move(elements))
{
}
Expand Down
33 changes: 33 additions & 0 deletions include/cura-formulae-engine/ast/property_access_expr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "cura-formulae-engine/ast/ast.h"
#include "expr_ptr.h"

#include <string>

namespace CuraFormulaeEngine::ast
{

struct PropertyAccessExpr final : Expr
{
ExprPtr object;
std::string property;

PropertyAccessExpr(ExprPtr&& object, std::string&& property)
: object(std::move(object))
, property(std::move(property))
{
}

[[nodiscard]] std::string toString() const noexcept final;

[[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final;

[[nodiscard]] std::unordered_set<std::string> freeVariables() const noexcept final;

[[nodiscard]] bool deepEq(const Expr& other) const noexcept final;

void visitAll(std::function<void(const Expr&)> visitor) const noexcept final;
};

} // namespace CuraFormulaeEngine::ast
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/slice_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct SliceExpr final : Expr
std::optional<ExprPtr> end_index;
std::optional<ExprPtr> step_size;

SliceExpr(ExprPtr array, std::optional<ExprPtr> start_index, std::optional<ExprPtr> end_index, std::optional<ExprPtr> step_size)
SliceExpr(ExprPtr&& array, std::optional<ExprPtr>&& start_index, std::optional<ExprPtr>&& end_index, std::optional<ExprPtr>&& step_size)
: array(std::move(array))
, start_index(std::move(start_index))
, end_index(std::move(end_index))
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/tuple_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct TupleExpr final : Expr
{
std::vector<ExprPtr> elements;

TupleExpr(std::vector<ExprPtr> elements)
TupleExpr(std::vector<ExprPtr>&& elements)
: elements(std::move(elements))
{
}
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/unary_expr/unary_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct UnaryExpr : Expr
{
ExprPtr operand;

explicit UnaryExpr(ExprPtr operand)
explicit UnaryExpr(ExprPtr&& operand)
: operand(std::move(operand))
{
}
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/ast/variable_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct VariableExpr final : Expr
{
std::string name;

VariableExpr(std::string name)
VariableExpr(std::string&& name)
: name(std::move(name))
{
}
Expand Down
10 changes: 10 additions & 0 deletions include/cura-formulae-engine/env/int_fn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@

#include "cura-formulae-engine/eval.h"

#include <string>
#include <vector>

namespace CuraFormulaeEngine::env
{

struct IntFunction
{
[[nodiscard]] eval::Result operator()(const std::vector<eval::Value>& args) const noexcept;
[[nodiscard]] std::vector<std::string> getSignature() const noexcept;
};

extern const IntFunction int_function;
extern const eval::Value::fn_t int_fn;

} // namespace CuraFormulaeEngine::env
10 changes: 10 additions & 0 deletions include/cura-formulae-engine/env/math_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@

#include "cura-formulae-engine/eval.h"

#include <string>
#include <vector>

namespace CuraFormulaeEngine::env
{

struct MathLogFunction
{
[[nodiscard]] eval::Result operator()(const std::vector<eval::Value>& args) const noexcept;
[[nodiscard]] std::vector<std::string> getSignature() const noexcept;
};

extern const MathLogFunction math_log_function;
extern const eval::Value::fn_t math_log;

} // namespace CuraFormulaeEngine::env
10 changes: 10 additions & 0 deletions include/cura-formulae-engine/env/min.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@

#include "cura-formulae-engine/eval.h"

#include <string>
#include <vector>

namespace CuraFormulaeEngine::env
{

struct MinFunction
{
[[nodiscard]] eval::Result operator()(const std::vector<eval::Value>& args) const noexcept;
[[nodiscard]] std::vector<std::string> getSignature() const noexcept;
};

extern const MinFunction min_function;
extern const eval::Value::fn_t min;

} // namespace CuraFormulaeEngine::env
10 changes: 10 additions & 0 deletions include/cura-formulae-engine/env/round.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@

#include "cura-formulae-engine/eval.h"

#include <string>
#include <vector>

namespace CuraFormulaeEngine::env
{

struct RoundFunction
{
[[nodiscard]] eval::Result operator()(const std::vector<eval::Value>& args) const noexcept;
[[nodiscard]] std::vector<std::string> getSignature() const noexcept;
};

extern const RoundFunction round_function;
extern const eval::Value::fn_t round;

} // namespace CuraFormulaeEngine::env
33 changes: 32 additions & 1 deletion include/cura-formulae-engine/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <cstddef>
#include <functional>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
#include <zeus/expected.hpp>
Expand All @@ -44,7 +45,27 @@ struct Value
{
using fn_t = std::function<Result(const std::vector<Value>&)>;

std::variant<bool, double, std::int64_t, std::string, std::vector<Value>, fn_t, std::nullptr_t> value = nullptr;
struct rich_fn_t
{
fn_t operation;
std::vector<std::string> signature;

[[nodiscard]] Result operator()(const std::vector<Value>& args) const noexcept
{
if (! operation)
{
return zeus::unexpected(Error::TypeMismatch);
}
return operation(args);
}

[[nodiscard]] std::vector<std::string> getSignature() const noexcept
{
return signature;
}
};

std::variant<bool, double, std::int64_t, std::string, std::vector<Value>, fn_t, rich_fn_t, std::unordered_map<std::string, Value>, std::nullptr_t> value = nullptr;

Value() noexcept = default;

Expand Down Expand Up @@ -78,6 +99,16 @@ struct Value
{
}

Value(const rich_fn_t& value) noexcept
: value{ value }
{
}

Value(const std::unordered_map<std::string, Value>& value) noexcept
: value{ value }
{
}

Value(const std::nullptr_t& value) noexcept
: value{ value }
{
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/formula.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ parsing parts. For instance, function application and array indexing. The gramma
similar.

```
FN APPLICATION : { variable } '(' { expression } ')'
FN APPLICATION : { variable } '(' { expression | identifier '=' expression } ')'
ARRAY INDEXING : { variable } '[' { expression } ']'
```
Comment thread
casperlamboo marked this conversation as resolved.

Expand Down
14 changes: 1 addition & 13 deletions include/cura-formulae-engine/parser/math_expr_grammar.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@
#include "cura-formulae-engine/ast/expr_ptr.h"
#include "cura-formulae-engine/ast/unary_expr/neg_expr.h"
#include "cura-formulae-engine/ast/unary_expr/not_expr.h"
#include "bool_grammar.h"
#include "list_grammar.h"
#include "none_grammar.h"
#include "number_grammar.h"
#include "parens_grammar.h"
#include "string_grammar.h"
#include "variable_or_fn_application_grammar_or_array_indexing_grammar.h"

#include <lexy/callback/adapter.hpp>
Expand All @@ -35,13 +29,7 @@ struct MathExprGrammar : lexy::expression_production

// clang-format off
static constexpr auto atom
= lexy::dsl::p<BoolGrammar>
| lexy::dsl::p<NoneGrammar>
| lexy::dsl::p<NumberGrammar>
| lexy::dsl::p<ParensGrammar>
| lexy::dsl::p<StringGrammar>
| lexy::dsl::p<ListGrammar>
| lexy::dsl::p<VariableOrFnApplicationGrammarOrArrayIndexingGrammar>;
= lexy::dsl::p<VariableOrFnApplicationGrammarOrArrayIndexingGrammar>;
// clang-format on

static constexpr auto op_pow = lexy::dsl::op(LEXY_LIT("**"));
Expand Down
2 changes: 1 addition & 1 deletion include/cura-formulae-engine/parser/variable_grammar.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace CuraFormulaeEngine::parser

struct VariableGrammar : lexy::token_production
{
static constexpr auto rule = lexy::dsl::identifier(lexy::dsl::ascii::alpha_digit_underscore / lexy::dsl::lit_c<'.'>);
static constexpr auto rule = lexy::dsl::identifier(lexy::dsl::ascii::alpha_digit_underscore);
static constexpr auto value = lexy::callback<ast::ExprPtr>([](const auto&& variable)
{
return ast::ExprPtr(std::make_unique<ast::VariableExpr>(std::string(variable.begin(), variable.end())));
Expand Down
Loading