diff --git a/src/eval.cpp b/src/eval.cpp index e43e047..9dfea19 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -444,7 +444,7 @@ EvalResult eval(Node &ast, Memory &memory, vector history) { return value; } break; - case NodeType::LIncr: { + case NodeType::LIncr: { // ++ and -- work on any type but nothing happens with non-arithmetic types Token identifier_token = get(node.children[0]); string identifier = get(identifier_token.data); diff --git a/src/include/errors.hpp b/src/include/errors.hpp index 277d58e..2cf2927 100644 --- a/src/include/errors.hpp +++ b/src/include/errors.hpp @@ -58,6 +58,9 @@ enum class ErrorType { using ErrorData = variant; +/** + * Base class for errors that arise from incorrect user input, they are divided in 4 sub-classes +*/ class UserError : public exception { public: explicit UserError(ErrorType type, CodePosition pos, ErrorData data = {}) @@ -100,6 +103,9 @@ public: const StackTrace trace; }; +/** + * Base class for exceptions used internally for control +*/ class InternalError : public exception { public: explicit InternalError(CodePosition pos = {}) diff --git a/src/include/execute.hpp b/src/include/execute.hpp index b9e5dc7..12adc0b 100644 --- a/src/include/execute.hpp +++ b/src/include/execute.hpp @@ -16,6 +16,9 @@ typedef struct ExecArgs { bool dump_mem=false; } ExecArgs; +/** + * Encapsulates interpretation steps from raw input to the result +*/ EvalResult execute(vector input, Memory& memory, int initial_line=0, ExecArgs args={}); #endif \ No newline at end of file diff --git a/src/include/lexer.hpp b/src/include/lexer.hpp index 2ae887c..4afb664 100644 --- a/src/include/lexer.hpp +++ b/src/include/lexer.hpp @@ -8,7 +8,7 @@ using namespace std; /* - Parses a string into a vector of tokens + Parses a vector of strings (one for each line) into a vector of tokens */ vector tokenize(vector str, int initial_line=0); diff --git a/src/include/memory.hpp b/src/include/memory.hpp index 9a8c4b8..5e6b81b 100644 --- a/src/include/memory.hpp +++ b/src/include/memory.hpp @@ -17,7 +17,7 @@ class Memory { void remove_scope(void); MemoryVar& get(string identifier); - Scope& get_function_scope(void); + Scope& get_function_scope(void); // get closest function scope void declare(string identifier, Type type); void update(string identifier, EvalResult value); diff --git a/src/include/types.hpp b/src/include/types.hpp index 2c59225..e2e534f 100644 --- a/src/include/types.hpp +++ b/src/include/types.hpp @@ -21,7 +21,7 @@ enum class TypeType { }; using ArgDefinition = tuple; -using FunctionPrototype = vector; +using FunctionPrototype = vector; // The return type comes first, unnamed types are represented by an empty string using TypeData = variant; struct Type { @@ -39,7 +39,7 @@ enum class TokenType { Break, Continue, Return, Comma }; -using TokenData = variant; +using TokenData = variant; struct CodePosition { int line; @@ -189,7 +189,7 @@ struct InnerNode { CodePosition pos; }; -// A Leaf is always corresponding to a Token +// Leaves are systematically associated with a token, that's why we re-use this type /** * Node: AST @@ -205,13 +205,17 @@ struct ParseReturn { */ struct MemoryVar; -using Closure = unordered_map>; +using Closure = unordered_map>; // map of pointers to memory vars using UserFunction = tuple; enum class InternalCall { ClearMemory, DumpMemory, DumpHistory }; +/** + * UserFunction: user defined functions are represented by an AST and a closure + * InternalCall: for standard library functions +*/ using Function = variant; using EvalResult = variant; @@ -229,8 +233,8 @@ struct Scope { unordered_map vars; int depth; ScopeType type; - MemoryVar* fn; - CodePosition entry_pos; + MemoryVar* fn; // For function scopes only + CodePosition entry_pos; // For function scopes only, call position }; #endif \ No newline at end of file diff --git a/src/include/utils.hpp b/src/include/utils.hpp index 1b83b8e..82cb352 100644 --- a/src/include/utils.hpp +++ b/src/include/utils.hpp @@ -35,7 +35,7 @@ vector split_string(const string& input, char delimiter); string type_type_to_string(TypeType type); /** - * Check if two types are equal + * Check recursively if two types are equal */ bool equal_types(Type type1, Type type2); diff --git a/src/lexer.cpp b/src/lexer.cpp index e716c87..d889e31 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -10,6 +10,7 @@ regex INT_REGEX ("\\d+"); regex DOUBLE_REGEX ("\\d+\\.\\d*|\\d*\\.\\d+"); regex IDENTIFIER_REGEX ("[A-Za-z_]\\w*"); +// A list of tokens with simple parsing logic vector> simple_tokens = { { "if", TokenType::If }, { "else", TokenType::Else }, diff --git a/src/parser.cpp b/src/parser.cpp index 66d0b01..a54009b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -181,6 +181,7 @@ ParseReturn parse_statement(vector tokens) { type = NodeType::While; break; default: + throw exception(); break; // Impossible }