Skip to content
Open
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
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
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
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
37 changes: 36 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,31 @@ 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::optional<std::vector<std::string>> getSignature() const noexcept
{
if (signature.empty())
{
return std::nullopt;
}
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 +103,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
Loading