ArkScript
A small, lisp-inspired, functional scripting language
TypeChecker.hpp
Go to the documentation of this file.
1/**
2 * @file TypeChecker.hpp
3 * @author Lex Plateau (lexplt.dev@gmail.com)
4 * @brief
5 * @date 2022-01-16
6 *
7 * @copyright Copyright (c) 2022-2025
8 *
9 */
10
11#ifndef INCLUDE_ARK_TYPECHECKER_HPP
12#define INCLUDE_ARK_TYPECHECKER_HPP
13
14#include <string>
15#include <vector>
16#include <ostream>
17#include <sstream>
18
20#include <Ark/VM/Value.hpp>
21
22namespace Ark
23{
24 class VM;
25}
26
27namespace 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 [[nodiscard]] bool checkN(const std::vector<Value>& args)
36 {
37 return I >= args.size();
38 }
39
40 template <int I, typename T, typename... Ts>
41 [[nodiscard]] 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 [[nodiscard]] 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 name;
73 std::vector<ValueType> types;
75
76 Typedef(const std::string& type_name, const ValueType type, const bool is_variadic = false) :
77 name(type_name), types { type }, variadic(is_variadic)
78 {}
79
80 Typedef(const std::string& type_name, const std::vector<ValueType>& type_list, const bool is_variadic = false) :
81 name(type_name), types(type_list), variadic(is_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 * @param vm reference to the VM used for pretty printing closures
101 * @param os output stream, default to cout
102 * @param colorize enable output colorizing
103 */
105 const std::string_view& funcname,
106 const std::vector<Contract>& contracts,
107 const std::vector<Value>& args,
108 VM& vm,
109 std::ostream& os = std::cout,
110 bool colorize = true);
111
112 class ARK_API TypeCheckingError final : public Error
113 {
114 public:
115 TypeCheckingError(std::string&& funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args) :
116 Error("TypeCheckingError"),
117 m_funcname(std::move(funcname)),
118 m_contracts(contracts),
119 m_passed_args(args)
120 {}
121
122 [[nodiscard]] std::string details(const bool colorize, VM& vm) const override
123 {
124 std::stringstream stream;
125 generateError(m_funcname, m_contracts, m_passed_args, vm, stream, colorize);
126 return stream.str();
127 }
128
129 private:
130 std::string m_funcname;
131 std::vector<Contract> m_contracts;
132 std::vector<Value> m_passed_args;
133 };
134}
135
136#endif
ArkScript homemade exceptions.
#define ARK_API
Definition Module.hpp:22
Default value type handled by the virtual machine.
The ArkScript virtual machine, executing ArkScript bytecode.
Definition VM.hpp:47
std::vector< Contract > m_contracts
std::vector< Value > m_passed_args
TypeCheckingError(std::string &&funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args)
std::string details(const bool colorize, VM &vm) const override
std::enable_if_t< std::conjunction_v< std::is_same< T, Ts >... > > AllSame
bool checkN(const std::vector< Value > &args)
bool check(const std::vector< Value > &args, Ts... types)
Helper to see if a builtin has been given a wanted set of types.
ARK_API void generateError(const std::string_view &funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args, VM &vm, std::ostream &os=std::cout, bool colorize=true)
Generate an error message based on a given set of types contracts provided argument list.
ValueType
Definition Value.hpp:32
@ Any
Used only for typechecking.
STL namespace.
A contract is a list of typed arguments that a function can follow.
std::vector< Typedef > arguments
A type definition within a contract.
Typedef(const std::string &type_name, const std::vector< ValueType > &type_list, const bool is_variadic=false)
Typedef(const std::string &type_name, const ValueType type, const bool is_variadic=false)
std::vector< ValueType > types