ArkScript
A small, fast, functional and scripting language for video games
TypeChecker.hpp
Go to the documentation of this file.
1 /**
2  * @file TypeChecker.hpp
3  * @author Alexandre Plateau (lexplt.dev@gmail.com)
4  * @brief
5  * @version 0.3
6  * @date 2022-01-16
7  *
8  * @copyright Copyright (c) 2022
9  *
10  */
11 
12 #ifndef INCLUDE_ARK_TYPECHECKER_HPP
13 #define INCLUDE_ARK_TYPECHECKER_HPP
14 
15 #include <limits>
16 #include <string>
17 #include <vector>
18 #include <type_traits>
19 
20 #define NOMINMAX
21 #include <Ark/VM/Value.hpp>
22 
23 #ifdef max
24 # undef max
25 #endif
26 
27 namespace Ark::types
28 {
29  namespace details
30  {
31  template <typename T, typename... Ts>
32  using AllSame = std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...>>;
33 
34  template <int I>
35  bool checkN([[maybe_unused]] const std::vector<Value>& args)
36  {
37  return true;
38  }
39 
40  template <int I, typename T, typename... Ts>
41  bool checkN(const std::vector<Value>& args, T type, Ts... xs)
42  {
43  if (I >= args.size() || (type != ValueType::Any && args[I].valueType() != type))
44  return false;
45  return checkN<I + 1>(args, xs...);
46  }
47  }
48 
49  /**
50  * @brief Helper to see if a builtin has been given a wanted set of types
51  *
52  * @tparam Ts Variadic argument list composed of ValueTypes
53  * @param args arguments passed to the function
54  * @param types accepted types
55  * @return true if the contract is respected
56  * @return false otherwise
57  */
58  template <typename... Ts, typename = details::AllSame<ValueType, Ts...>>
59  bool check(const std::vector<Value>& args, Ts... types)
60  {
61  if (sizeof...(types) != args.size())
62  return false;
63  return details::checkN<0>(args, types...);
64  }
65 
66  /**
67  * @brief A type definition within a contract
68  *
69  */
71  {
72  std::string_view name;
73  std::vector<ValueType> types;
74  bool variadic;
75 
76  Typedef(std::string_view name, ValueType type, bool variadic = false) :
77  name(name), types { { type } }, variadic(variadic)
78  {}
79 
80  Typedef(std::string_view name, const std::vector<ValueType>& types, bool variadic = false) :
81  name(name), types(types), variadic(variadic)
82  {}
83  };
84 
85  /**
86  * @brief A contract is a list of typed arguments that a function can follow
87  *
88  */
90  {
91  std::vector<Typedef> arguments;
92  };
93 
94  /**
95  * @brief Generate an error message based on a given set of types contracts provided argument list
96  *
97  * @param funcname ArkScript name of the function
98  * @param contracts types contracts the function can follow
99  * @param args provided argument list
100  */
101  ARK_API void generateError [[noreturn]] (std::string_view funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args);
102 }
103 
104 #endif
#define ARK_API
Definition: Platform.hpp:41
std::enable_if_t< std::conjunction_v< std::is_same< T, Ts >... > > AllSame
Definition: TypeChecker.hpp:32
bool checkN([[maybe_unused]] const std::vector< Value > &args)
Definition: TypeChecker.hpp:35
bool check(const std::vector< Value > &args, Ts... types)
Helper to see if a builtin has been given a wanted set of types.
Definition: TypeChecker.hpp:59
ARK_API void generateError(std::string_view funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args)
Generate an error message based on a given set of types contracts provided argument list.
Definition: TypeChecker.cpp:82
ValueType
Definition: Value.hpp:40
A contract is a list of typed arguments that a function can follow.
Definition: TypeChecker.hpp:90
std::vector< Typedef > arguments
Definition: TypeChecker.hpp:91
A type definition within a contract.
Definition: TypeChecker.hpp:71
std::string_view name
Definition: TypeChecker.hpp:72
Typedef(std::string_view name, const std::vector< ValueType > &types, bool variadic=false)
Definition: TypeChecker.hpp:80
Typedef(std::string_view name, ValueType type, bool variadic=false)
Definition: TypeChecker.hpp:76
std::vector< ValueType > types
Definition: TypeChecker.hpp:73