aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-dataloader/v2script/ModifierGrammar.hpp
blob: d6dbb32f26b4c8eb76e6bfce2bed9cf4a79a2eba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#pragma once

#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>

#include <lexy/callback/container.hpp>
#include <lexy/dsl.hpp>

#include <dryad/node.hpp>
#include <dryad/tree.hpp>

#include "openvic-dataloader/NodeLocation.hpp"

#include "SimpleGrammar.hpp"
#include "TriggerGrammar.hpp"
#include "detail/dsl.hpp"

namespace ovdl::v2script::grammar {
   constexpr auto modifier_keyword = LEXY_KEYWORD("modifier", id);
   constexpr auto factor_keyword = LEXY_KEYWORD("factor", id);

   struct FactorStatement {
      static constexpr auto rule = lexy::dsl::position(factor_keyword) >> (lexy::dsl::equal_sign + lexy::dsl::p<Identifier<StringEscapeOption>>);
      static constexpr auto value = dsl::callback<ast::AssignStatement*>(
         [](ast::ParseState& state, NodeLocation loc, ast::IdentifierValue* value) {
            auto* factor = state.ast().create<ast::IdentifierValue>(loc, state.ast().intern("factor"));
            return state.ast().create<ast::AssignStatement>(loc, factor, value);
         });
   };

   struct ModifierList {
      struct expected_factor {
         static constexpr auto name = "expected factor in modifier";
      };

      static constexpr auto rule = [] {
         auto factor_flag = lexy::dsl::context_flag<ModifierList>;

         auto element = (lexy::dsl::p<FactorStatement> >> factor_flag.set()) | lexy::dsl::p<TriggerStatement>;

         return dsl::curly_bracketed.list(factor_flag.create() + element) >> lexy::dsl::must(factor_flag.is_reset()).error<expected_factor>;
      }();

      static constexpr auto value = lexy::as_list<ast::AssignStatementList> >> construct_list<ast::ListValue>;
   };

   struct ModifierStatement {
      static constexpr auto rule =
         lexy::dsl::position(modifier_keyword) >> lexy::dsl::equal_sign >> lexy::dsl::p<ModifierList>;

      static constexpr auto value = dsl::callback<ast::AssignStatement*>(
         [](ast::ParseState& state, NodeLocation loc, ast::ListValue* list) {
            auto* factor = state.ast().create<ast::IdentifierValue>(loc, state.ast().intern("modifier"));
            return state.ast().create<ast::AssignStatement>(loc, factor, list);
         });
   };
}