Skip to content

Commit f539e0b

Browse files
authored
Merge pull request #360 from ArkScript-lang/refactor/errors
Refactor/errors Former-commit-id: 21d07eb58a548cdcb95df7ddcecb115547f720b5
2 parents ed1503e + 1133be5 commit f539e0b

File tree

15 files changed

+656
-524
lines changed

15 files changed

+656
-524
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,21 @@ jobs:
270270
with:
271271
submodules: recursive
272272

273-
- name: Update LLVM compilers
274-
shell: bash
275-
run: sudo apt-get install -y clang-11 lld-11 libc++-11-dev libc++abi-11-dev clang-tools-11 valgrind
273+
- name: Download artifact
274+
id: download
275+
uses: actions/download-artifact@v2
276+
with:
277+
name: "ubuntu-clang-11"
278+
path: build
276279

277-
- name: Configure CMake Ark
278-
shell: bash
280+
- shell: bash
279281
run: |
280-
cmake -Bbuild \
281-
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
282-
-DCMAKE_C_COMPILER=clang-11 \
283-
-DCMAKE_CXX_COMPILER=clang++-11 \
284-
-DARK_BUILD_EXE=On -DARK_BUILD_MODULES=On
282+
mv build/lib/*.arkm lib/
283+
chmod u+x build/ark build/arkscript
285284
286-
- name: Build ArkScript
285+
- name: Update LLVM compilers
287286
shell: bash
288-
run: cmake --build build --config $BUILD_TYPE
287+
run: sudo apt-get install -y clang-11 lld-11 libc++-11-dev libc++abi-11-dev clang-tools-11 valgrind
289288

290289
- name: Valgrind checks for memory leaks
291290
shell: bash

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
- the VM can have multiple independant context running on the same bytecode
77
- the VM now takes a reference to an `Ark::State` instead of a raw non-owning pointer
88
- adding `ARK_PROFILER_MIPS` to toggle instruction per second calculation
9+
- adding new way to typecheck in builtins
910
- new CI build step now running valgrind to check for memory leaks
11+
- new type checker (to be used by builtins)
12+
- better type errors generation (with the list of arguments, if they are matching or not, and more)
1013

1114
### Changed
1215
- splitting Utils.hpp into multiple files for easier maintenance and contextualisation
1316
- reserving a default scope size of 3, which yields really good performance results compared to nothing being reserved
17+
- upgrading the builtins error handling to use the `BetterTypeError`
18+
- the VM now displays the debug info (ip, pp, sp) at the end of the backtrace instead of the beginning
1419

1520
### Removed
21+
- `BetterTypeError` has been removed in favor of a type checker using templates and an error generator
1622

1723
### Deprecated
1824
- deprecating `VM(State*)` in favor of `VM(State&)`

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ if (ARK_ENABLE_SYSTEM)
184184
target_compile_definitions(ArkReactor PRIVATE -DARK_ENABLE_SYSTEM)
185185
endif()
186186

187+
if (ARK_PROFILER_MIPS)
188+
target_compile_definitions(ArkReactor PRIVATE -DARK_PROFILER_MIPS)
189+
endif()
190+
187191
if (ARK_BUILD_MODULES)
188192
add_subdirectory(${ark_SOURCE_DIR}/lib/modules)
189193
endif()
Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,8 @@
1-
// IO
2-
3-
#define IO_INPUT_TE "input: prompt must be a String"
4-
5-
#define IO_WRITE_ARITY "writeFile needs 2 to 3 arguments: filename, [mode], content"
6-
#define IO_WRITE_TE0 "writeFile: filename must be a String"
7-
#define IO_WRITE_TE1 "writeFile: mode must be a String"
8-
#define IO_WRITE_VE_1 "writeFile: mode must be equal to \"a\" or \"w\""
9-
10-
#define IO_READ_ARITY "readFile needs 1 argument: filename"
11-
#define IO_READ_TE0 "readFile: filename must be a String"
12-
13-
#define IO_EXISTS_ARITY "fileExists? needs 1 argument: filename"
14-
#define IO_EXISTS_TE0 "fileExists?: filename must be a String"
15-
16-
#define IO_LS_ARITY "listFiles needs 1 argument: filename"
17-
#define IO_LS_TE0 "listFiles: filename must be a String"
18-
19-
#define IO_ISDIR_ARITY "isDir? needs 1 argument: path"
20-
#define IO_ISDIR_TE0 "isDir?: path must be a String"
21-
22-
#define IO_MKD_ARITY "makeDir needs 1 argument: filename"
23-
#define IO_MKD_TE0 "makeDir: filename must be a String"
24-
25-
#define IO_RM_ARITY "removeFiles needs at least 1 argument: filename [...]"
26-
#define IO_RM_TE0 "removeFiles: filename must be a String"
27-
281
// List
292

30-
#define LIST_REVERSE_ARITY "list:reverse needs 1 argument: list"
31-
#define LIST_REVERSE_TE0 "list:reverse: list must be a List"
32-
33-
#define LIST_FIND_ARITY "list:find needs 2 arguments: list, value"
34-
#define LIST_FIND_TE0 "list:find: list must be a List"
35-
363
// TO BE DEPRECATED
374
#define LIST_RMAT_ARITY "list:removeAt needs 2 arguments: list, index"
385
#define LIST_RMAT_TE0 "list:removeAt: list must be a List"
396
#define LIST_RMAT_TE1 "list:removeAt: index must be a Number"
407
#define LIST_RMAT_OOR "list:removeAt: index out of range"
418
// --
42-
43-
#define LIST_SLICE_ARITY "list:slice needs 4 arguments: list, start, end, step"
44-
#define LIST_SLICE_TE0 "list:slice: list must be a List"
45-
#define LIST_SLICE_TE1 "list:slice: start must be a Number"
46-
#define LIST_SLICE_TE2 "list:slice: end must be a Number"
47-
#define LIST_SLICE_TE3 "list:slice: step must be a Number"
48-
#define LIST_SLICE_STEP "list:slice: step can not be null"
49-
#define LIST_SLICE_ORDER "list:slice: start position must be less or equal to the end position"
50-
#define LIST_SLICE_OOR "list:slice: indices out of range"
51-
52-
#define LIST_SORT_ARITY "list:sort needs 1 argument: a list"
53-
#define LIST_SORT_TE0 "list:sort: list must be a List"
54-
55-
#define LIST_FILL_ARITY "list:fill needs 2 arguments: size, value"
56-
#define LIST_FILL_TE0 "list:fill: size must be a Number"
57-
58-
#define LIST_SETAT_ARITY "list:setAt needs 3 arguments: list, index, value"
59-
#define LIST_SETAT_TE0 "list:setAt: list must be a List"
60-
#define LIST_SETAT_TE1 "list:setAt: index must be a Number"
61-
62-
// Mathematics
63-
64-
#define MATH_ARITY(name) (name " needs 1 argument: value")
65-
#define MATH_TE0(name) (name ": value must be a Number")
66-
67-
// String
68-
69-
#define STR_FORMAT_ARITY "str:format needs at least 1 argument: string, [values...]"
70-
#define STR_FORMAT_TE0 "str:format: string must be a String"
71-
72-
#define STR_FIND_ARITY "str:find needs 2 arguments: string, substr"
73-
#define STR_FIND_TE0 "str:find: string must be a String"
74-
#define STR_FIND_TE1 "str:find: substr must be a String"
75-
76-
#define STR_RM_ARITY "str:removeAt needs 2 arguments: string, index"
77-
#define STR_RM_TE0 "str:removeAt: string must be a String"
78-
#define STR_RM_TE1 "str:removeAt: index must be a Number"
79-
#define STR_RM_OOR "str:removeAt: index out of range"
80-
81-
#define STR_ORD_ARITY "str:ord needs at least 1 argument: string"
82-
#define STR_ORD_TE0 "str:ord: string must be a String"
83-
84-
#define STR_CHR_ARITY "str:chr needs at least 1 argument: codepoint"
85-
#define STR_CHR_TE0 "str:chr: codepoint must be a Number"
86-
87-
// System
88-
89-
#define SYS_SYS_ARITY "sys:exec needs 1 argument: command"
90-
#define SYS_SYS_TE0 "sys:exec: command must be a String"
91-
92-
#define SYS_SLEEP_ARITY "sleep needs 1 argument: duration (milliseconds)"
93-
#define SYS_SLEEP_TE0 "sleep: duration must be a Number"
94-
95-
#define SYS_EXIT_ARITY "sys:exit needs 1 argument: exit code"
96-
#define SYS_EXIT_TE0 "sys:exit: exit code must be a Number"
97-
98-
// Time

include/Ark/Exceptions.hpp

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,6 @@
2121

2222
namespace Ark
2323
{
24-
class Error : public std::runtime_error
25-
{
26-
public:
27-
explicit Error(const std::string& message = "") :
28-
std::runtime_error(message)
29-
{}
30-
};
31-
32-
/**
33-
* @brief A type error triggered when types don't match
34-
*
35-
*/
36-
class BetterTypeError : public Error
37-
{
38-
public:
39-
BetterTypeError(std::string_view func_name, std::size_t expected_argc, const std::vector<Value>& args);
40-
41-
BetterTypeError& withArg(std::string_view arg_name, ValueType arg_type);
42-
BetterTypeError& withArg(std::string_view arg_name, const std::vector<ValueType>& arg_type);
43-
44-
protected:
45-
std::string_view m_funcname;
46-
std::size_t m_arg_index;
47-
std::size_t m_expected_argc;
48-
std::vector<Value> m_args;
49-
};
50-
5124
/**
5225
* @brief A type error triggered when types don't match
5326
*
@@ -56,7 +29,7 @@ namespace Ark
5629
{
5730
public:
5831
explicit TypeError(const std::string& message) :
59-
std::runtime_error("TypeError: " + message)
32+
std::runtime_error(message)
6033
{}
6134
};
6235

include/Ark/TypeChecker.hpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* @file TypeChecker.hpp
3+
* @author Alexandre Plateau ([email protected])
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+
*/
70+
struct Typedef
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+
*/
89+
struct Contract
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+
void generateError(std::string_view funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args);
102+
}
103+
104+
#endif

include/Ark/VM/Value.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @file Value.hpp
33
* @author Default value type handled by the virtual machine
44
* @brief
5-
* @version 0.2
5+
* @version 0.3
66
* @date 2020-10-27
77
*
88
* @copyright Copyright (c) 2020-2021
@@ -51,7 +51,9 @@ namespace Ark
5151
False = 9,
5252
Undefined = 10,
5353
Reference = 11,
54-
InstPtr = 12
54+
InstPtr = 12,
55+
56+
Any = 99
5557
};
5658

5759
const std::array<std::string, 13> types_to_str = {

0 commit comments

Comments
 (0)