From b686fe00fb8dc5a7ccc56b9e38c1e65646ed50d8 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Fri, 5 May 2023 11:59:02 +0300 Subject: [PATCH] fixes, more information in errors --- .gitmodules | 3 + include/build_visitor.hpp | 2 +- include/error_handling.hpp | 31 ++++++-- include/interpreter_tree.hpp | 119 ++++++++++++++++++++++++++++++- include/parse_tree.hpp | 4 ++ src/build_visitor.cpp | 134 ++++++++++++++++++++++++++++++++--- src/link_symbols_visitor.cpp | 9 +-- src/main.cpp | 5 ++ src/type_check_visitor.cpp | 112 +++++++++++++++++------------ tests/memory.lang | 2 +- 10 files changed, 356 insertions(+), 65 deletions(-) diff --git a/.gitmodules b/.gitmodules index 7c5db61..01357f7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lang-parser"] path = lang-parser url = https://codeberg.org/ProgramSnail/lang-parser.git +[submodule "tree-sitter"] + path = tree-sitter + url = https://github.com/tree-sitter/tree-sitter.git diff --git a/include/build_visitor.hpp b/include/build_visitor.hpp index 3902624..06672d4 100644 --- a/include/build_visitor.hpp +++ b/include/build_visitor.hpp @@ -134,7 +134,7 @@ private: void Visit(ExtendedName* node) override; - void Visit(AnyIdentifier* node) override; // std::string + // // void Visit(AnyIdentifier* node) override; // std::string void Visit(FloatNumberLiteral* node) override; void Visit(NumberLiteral* node) override; diff --git a/include/error_handling.hpp b/include/error_handling.hpp index aee85cb..c52af2a 100644 --- a/include/error_handling.hpp +++ b/include/error_handling.hpp @@ -1,11 +1,31 @@ #pragma once +#include "interpreter_tree.hpp" #include +#include namespace error_handling { -inline void HandleParsingError(const std::string& message, std::pair place) { - std::cout << "Parsing Error: " << message << " at (" << place.first << ", " << place.second << ").\n"; +inline void PrintPosition(std::ostream& out, + std::pair start_position, + std::pair end_position) { + out << '[' + << start_position.first + << ", " + << start_position.second + << "] - [" + << end_position.first + << ", " + << end_position.second + << ']'; +} + +inline void HandleParsingError(const std::string& message, + std::pair start_position, + std::pair end_position) { + std::cout << "Parsing Error: " << message << " at "; + PrintPosition(std::cout, start_position, end_position); + std::cout << ".\n"; exit(1); } @@ -14,8 +34,11 @@ inline void HandleInternalError(const std::string& message, const std::string& p exit(1); } -inline void HandleTypecheckError(const std::string& message) { // TODO: place in code - std::cout << "Typecheck Error: " << message << ".\n"; +inline void HandleTypecheckError(const std::string& message, + const interpreter::tokens::BaseNode& node) { // TODO: place in code + std::cout << "Typecheck Error: " << message << " at "; + PrintPosition(std::cout, node.start_position, node.end_position); + std::cout << ".\n"; exit(1); } diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 52aa78a..72e7180 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -11,6 +11,11 @@ namespace interpreter::tokens { +struct BaseNode { + std::pair start_position; + std::pair end_position; +}; + // ----------------- Declarations ----------------- using AnyIdentifier = std::string; @@ -236,6 +241,8 @@ struct ParametrizedType; // Identifiers, constants, etc. ----------------- struct ExtendedName { + BaseNode base; + std::string name; }; @@ -254,16 +261,22 @@ using Pattern = std::variant< // ----------------- Sources ----------------- struct SourceFile { + BaseNode base; + std::vector statements; }; // ----------------- Namespaces, partittions ----------------- struct PartitionSources { + BaseNode base; + std::vector statements; }; struct Partition { + BaseNode base; + enum PartitionName { Test, Interface, @@ -275,10 +288,14 @@ struct Partition { }; struct NamespaceSources { + BaseNode base; + std::vector statements; }; struct Namespace { + BaseNode base; + enum Modifier { Const, Var }; std::optional modifier; // modifier => variable namespace TypeIdentifier type; @@ -291,12 +308,16 @@ struct Namespace { // ----------------- Definitions ----------------- struct ImportStatement { + BaseNode base; + std::optional name; std::string module_name; std::vector symbols; }; struct AliasDefinitionStatement { + BaseNode base; + enum {Alias, Type, Let} modifier; TypeIdentifier type; std::vector parameters; @@ -306,6 +327,8 @@ struct AliasDefinitionStatement { }; struct VariableDefinitionStatement { + BaseNode base; + enum { Var, Const } modifier; enum { Move, Assign } assignment_modifier; AnyName name; @@ -313,6 +336,8 @@ struct VariableDefinitionStatement { }; struct FunctionDeclaration { + BaseNode base; + ExtendedName name; std::vector> parameters; std::unique_ptr type; @@ -321,6 +346,8 @@ struct FunctionDeclaration { }; struct FunctionDefinitionStatement { + BaseNode base; + bool is_inline; std::unique_ptr definition; SuperExpression value; @@ -329,6 +356,8 @@ struct FunctionDefinitionStatement { }; struct TypeDefinitionStatement { + BaseNode base; + enum { Struct, Class } modifier; std::unique_ptr definition; AnyType value; @@ -337,6 +366,8 @@ struct TypeDefinitionStatement { }; struct AbstractTypeDefinitionStatement { + BaseNode base; + enum { Basic, Abstract } modifier; std::unique_ptr type; @@ -345,6 +376,8 @@ struct AbstractTypeDefinitionStatement { }; struct TypeclassDefinitionStatement { + BaseNode base; + std::unique_ptr definition; std::vector> requirements; @@ -354,17 +387,23 @@ struct TypeclassDefinitionStatement { // Definition parts ----------------- struct FunctionDefinition { + BaseNode base; + enum { Operator, Function } modifier; ExtendedName name; std::vector arguments; }; struct TypeDefinition { + BaseNode base; + std::unique_ptr type; std::vector> parameters; }; struct AnyAnnotatedType { + BaseNode base; + AnyTypeIdentifier type; std::vector> typeclasses; }; @@ -372,48 +411,66 @@ struct AnyAnnotatedType { // ----------------- Flow control ----------------- struct TypeConstructorPatternParameter { + BaseNode base; + std::optional name; PatternToken value; }; struct TypeConstructorPattern { + BaseNode base; + std::unique_ptr constructor; std::vector parameters; }; struct MatchCase { + BaseNode base; + Pattern value; std::optional condition; std::optional statement; }; struct Match { + BaseNode base; + Expression value; std::vector matches; }; struct Condition { + BaseNode base; + std::vector conditions; // if, elif std::vector statements; // if, elif, else }; struct DoWhileLoop { + BaseNode base; + Expression condition; Expression statement; }; struct WhileLoop { + BaseNode base; + Expression condition; Expression statement; }; struct ForLoop { + BaseNode base; + AnyName variable; Expression interval; Expression statement; }; struct LoopLoop { + BaseNode base; + Expression statement; }; @@ -426,32 +483,44 @@ using BlockStatement = std::variant< std::unique_ptr>; struct Block { + BaseNode base; + std::vector statements; }; struct ScopedStatement { + BaseNode base; + SuperExpression statement; }; // Operators ----------------- struct BinaryOperatorExpression { + BaseNode base; + OperatorIdentifier operator_name; SubExpression left_expression; SubExpression right_expression; }; struct UnaryOperatorExpression { + BaseNode base; + OperatorIdentifier operator_name; Expression expression; }; struct ReferenceExpression { + BaseNode base; + std::vector references; std::unique_ptr expression; }; struct AccessExpression { + BaseNode base; + std::unique_ptr name; SubExpressionToken id; }; @@ -459,6 +528,8 @@ struct AccessExpression { // Other Expressions ----------------- struct FunctionCallExpression { + BaseNode base; + std::optional, std::unique_ptr>> prefix; ExtendedName name; @@ -467,18 +538,26 @@ struct FunctionCallExpression { }; struct TupleExpression { + BaseNode base; + std::vector expressions; }; struct VariantExpression { + BaseNode base; + std::vector expressions; }; struct ReturnExpression { + BaseNode base; + Expression expression; }; struct TypeConstructorParameter { + BaseNode base; + enum AssignmentModifier { Move, Assign }; std::optional name; std::optional asignment_modifier; @@ -486,11 +565,15 @@ struct TypeConstructorParameter { }; struct TypeConstructor { + BaseNode base; + std::unique_ptr constructor; std::vector parameters; }; struct LambdaFunction { + BaseNode base; + std::vector> parameters; std::vector arguments; Expression expression; @@ -500,24 +583,34 @@ struct LambdaFunction { }; struct ArrayExpression { + BaseNode base; + std::vector elements; }; // Name ----------------- struct NameExpression { + BaseNode base; + std::vector names; }; struct TupleName { + BaseNode base; + std::vector names; }; struct VariantName { + BaseNode base; + std::vector names; }; struct AnnotatedName { + BaseNode base; + NameIdentifier name; std::optional type; }; @@ -527,20 +620,28 @@ struct AnnotatedName { // Type ----------------- struct FunctionType { + BaseNode base; + std::vector types; }; struct TupleType { + BaseNode base; + std::optional type; std::vector, std::unique_ptr>> entities; }; struct VariantType { + BaseNode base; + std::optional type; std::vector>> constructors; }; struct ParametrizedType { + BaseNode base; + AnyTypeIdentifier type; std::vector> parameters; @@ -548,6 +649,8 @@ struct ParametrizedType { }; struct TypeExpression { + BaseNode base; + std::vector path; ParametrizedType type; @@ -558,6 +661,8 @@ struct TypeExpression { }; struct ExtendedScopedAnyType { + BaseNode base; + std::vector references; AnyType type; }; @@ -565,6 +670,8 @@ struct ExtendedScopedAnyType { // Typeclass ----------------- struct ParametrizedTypeclass { + BaseNode base; + TypeclassIdentifier typeclass; std::vector> parameters; @@ -575,21 +682,31 @@ struct ParametrizedTypeclass { // ----------------- Identifiers, constants, etc. ----------------- struct FloatNumberLiteral { + BaseNode base; + double value; }; struct NumberLiteral { + BaseNode base; + int64_t value; }; struct StringLiteral { + BaseNode base; + std::string value; }; struct CharLiteral { + BaseNode base; + char value; }; -struct UnitLiteral {}; +struct UnitLiteral { + BaseNode base; +}; } // namespace interpereter::tokens diff --git a/include/parse_tree.hpp b/include/parse_tree.hpp index 630abd0..2cb5c33 100644 --- a/include/parse_tree.hpp +++ b/include/parse_tree.hpp @@ -121,6 +121,10 @@ public: ~ParseTree() { ts_tree_delete(tree_); } + + bool IsProperlyParsed() { // TODO: check + return !GetRoot().HasError(); + } private: TSTree* tree_; std::string source_; // for token value extraction diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 836e439..fb0a41b 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -8,8 +8,15 @@ namespace interpreter { +void SetPosition(BaseNode& base_node, parser::ParseTree::Node& parse_node) { + base_node.start_position = parse_node.GetStartPoint(); + base_node.end_position = parse_node.GetEndPoint(); +} + // Sources ----------------- void BuildVisitor::Visit(SourceFile* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); @@ -26,6 +33,8 @@ void BuildVisitor::Visit(SourceFile* node) { // Namespaces, partitions ----------------- void BuildVisitor::Visit(PartitionSources* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); @@ -40,6 +49,8 @@ void BuildVisitor::Visit(PartitionSources* node) { } void BuildVisitor::Visit(Partition* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; std::string name = parse_node.ChildByFieldName("name").GetValue(); @@ -59,6 +70,8 @@ void BuildVisitor::Visit(Partition* node) { } void BuildVisitor::Visit(NamespaceSources* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); @@ -73,6 +86,8 @@ void BuildVisitor::Visit(NamespaceSources* node) { } void BuildVisitor::Visit(Namespace* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); @@ -86,8 +101,7 @@ void BuildVisitor::Visit(Namespace* node) { } } - current_node_ = parse_node.ChildByFieldName("type"); - Visit(&node->type); + node->type = parse_node.ChildByFieldName("type").GetValue(); current_node_ = parse_node.ChildByFieldName("scope"); Visit(&node->scope); @@ -98,6 +112,8 @@ void BuildVisitor::Visit(Namespace* node) { // Definitions ----------------- void BuildVisitor::Visit(ImportStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t excluded_child_count = 0; @@ -119,8 +135,7 @@ void BuildVisitor::Visit(ImportStatement* node) { node->symbols.resize(child_count - excluded_child_count); for (size_t i = 0; i < child_count - excluded_child_count; ++i) { - current_node_ = parse_node.NthNamedChild(i + excluded_child_count); - Visit(&node->symbols[i]); + node->symbols[i] = parse_node.NthNamedChild(i + excluded_child_count).GetValue(); } } @@ -128,6 +143,8 @@ void BuildVisitor::Visit(ImportStatement* node) { } void BuildVisitor::Visit(AliasDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); @@ -159,6 +176,8 @@ void BuildVisitor::Visit(AliasDefinitionStatement* node) { } void BuildVisitor::Visit(VariableDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); @@ -185,6 +204,8 @@ void BuildVisitor::Visit(VariableDefinitionStatement* node) { } void BuildVisitor::Visit(FunctionDeclaration* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->name.name = parse_node.ChildByFieldName("name").GetValue(); @@ -208,6 +229,8 @@ void BuildVisitor::Visit(FunctionDeclaration* node) { } void BuildVisitor::Visit(FunctionDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->is_inline = (parse_node.NthChild(1).GetValue() == "inline"); @@ -223,6 +246,8 @@ void BuildVisitor::Visit(FunctionDefinitionStatement* node) { } void BuildVisitor::Visit(TypeDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); @@ -243,6 +268,8 @@ void BuildVisitor::Visit(TypeDefinitionStatement* node) { } void BuildVisitor::Visit(AbstractTypeDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; std::string modifier = parse_node.NthChild(0).GetValue(); @@ -260,6 +287,8 @@ void BuildVisitor::Visit(AbstractTypeDefinitionStatement* node) { } void BuildVisitor::Visit(TypeclassDefinitionStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("definition"); @@ -361,6 +390,8 @@ void BuildVisitor::Visit(SourceStatement& node) { // Definition parts void BuildVisitor::Visit(FunctionDefinition* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->name.name = parse_node.ChildByFieldName("name").GetValue(); @@ -385,6 +416,8 @@ void BuildVisitor::Visit(FunctionDefinition* node) { } void BuildVisitor::Visit(TypeDefinition* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("type"); @@ -405,6 +438,8 @@ void BuildVisitor::Visit(TypeDefinition* node) { } void BuildVisitor::Visit(AnyAnnotatedType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->type = parse_node.ChildByFieldName("type").GetValue(); @@ -427,6 +462,8 @@ void BuildVisitor::Visit(AnyAnnotatedType* node) { // Flow control ----------------- void BuildVisitor::Visit(TypeConstructorPatternParameter* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); @@ -445,6 +482,8 @@ void BuildVisitor::Visit(TypeConstructorPatternParameter* node) { } void BuildVisitor::Visit(TypeConstructorPattern* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("constructor"); @@ -509,6 +548,8 @@ void BuildVisitor::Visit(Pattern& node) { } void BuildVisitor::Visit(MatchCase* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("value"); @@ -536,6 +577,8 @@ void BuildVisitor::Visit(MatchCase* node) { } void BuildVisitor::Visit(Match* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("value"); @@ -556,6 +599,8 @@ void BuildVisitor::Visit(Match* node) { } void BuildVisitor::Visit(Condition* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); @@ -577,6 +622,8 @@ void BuildVisitor::Visit(Condition* node) { } void BuildVisitor::Visit(DoWhileLoop* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); @@ -589,6 +636,8 @@ void BuildVisitor::Visit(DoWhileLoop* node) { } void BuildVisitor::Visit(WhileLoop* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("condition"); @@ -600,6 +649,8 @@ void BuildVisitor::Visit(WhileLoop* node) { current_node_ = parse_node; } void BuildVisitor::Visit(ForLoop* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("variable"); @@ -615,6 +666,8 @@ void BuildVisitor::Visit(ForLoop* node) { } void BuildVisitor::Visit(LoopLoop* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); @@ -684,6 +737,8 @@ void BuildVisitor::Visit(BlockStatement& node) { } void BuildVisitor::Visit(Block* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t statement_count = parse_node.NamedChildCount(); @@ -831,6 +886,8 @@ void BuildVisitor::Visit(SuperExpression& node) { } void BuildVisitor::Visit(ScopedStatement* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("statement"); @@ -842,6 +899,8 @@ void BuildVisitor::Visit(ScopedStatement* node) { // Operators void BuildVisitor::Visit(BinaryOperatorExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("left_expression"); @@ -856,6 +915,8 @@ void BuildVisitor::Visit(BinaryOperatorExpression* node) { } void BuildVisitor::Visit(UnaryOperatorExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->operator_name = parse_node.ChildByFieldName("operator_name").GetValue(); @@ -867,6 +928,8 @@ void BuildVisitor::Visit(UnaryOperatorExpression* node) { } void BuildVisitor::Visit(ReferenceExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); @@ -891,6 +954,8 @@ void BuildVisitor::Visit(ReferenceExpression* node) { } void BuildVisitor::Visit(AccessExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("name"); @@ -906,6 +971,8 @@ void BuildVisitor::Visit(AccessExpression* node) { // Other expressions void BuildVisitor::Visit(FunctionCallExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t excluded_child_count = 0; @@ -958,6 +1025,8 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { } void BuildVisitor::Visit(TupleExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t expressions_count = parse_node.NamedChildCount(); @@ -973,6 +1042,8 @@ void BuildVisitor::Visit(TupleExpression* node) { } void BuildVisitor::Visit(VariantExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t expressions_count = parse_node.NamedChildCount(); @@ -988,6 +1059,8 @@ void BuildVisitor::Visit(VariantExpression* node) { } void BuildVisitor::Visit(ReturnExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("expression"); @@ -997,6 +1070,8 @@ void BuildVisitor::Visit(ReturnExpression* node) { } void BuildVisitor::Visit(TypeConstructorParameter* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); @@ -1021,6 +1096,8 @@ void BuildVisitor::Visit(TypeConstructorParameter* node) { } void BuildVisitor::Visit(TypeConstructor* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; current_node_ = parse_node.ChildByFieldName("constructor"); @@ -1042,6 +1119,8 @@ void BuildVisitor::Visit(TypeConstructor* node) { } void BuildVisitor::Visit(LambdaFunction* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); @@ -1073,6 +1152,8 @@ void BuildVisitor::Visit(LambdaFunction* node) { } void BuildVisitor::Visit(ArrayExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t elements_count = parse_node.NamedChildCount(); @@ -1102,6 +1183,8 @@ void BuildVisitor::Visit(LoopControlExpression& node) { // Name void BuildVisitor::Visit(NameExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.NamedChildCount(); @@ -1116,6 +1199,8 @@ void BuildVisitor::Visit(NameExpression* node) { } void BuildVisitor::Visit(TupleName* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t names_count = parse_node.NamedChildCount(); @@ -1132,6 +1217,8 @@ void BuildVisitor::Visit(TupleName* node) { } void BuildVisitor::Visit(VariantName* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t names_count = parse_node.NamedChildCount(); @@ -1148,6 +1235,8 @@ void BuildVisitor::Visit(VariantName* node) { } void BuildVisitor::Visit(AnnotatedName* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->name = parse_node.ChildByFieldName("name").GetValue(); @@ -1189,6 +1278,8 @@ void BuildVisitor::Visit(AnyName& node) { // Type void BuildVisitor::Visit(FunctionType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t types_count = parse_node.NamedChildCount(); @@ -1204,6 +1295,8 @@ void BuildVisitor::Visit(FunctionType* node) { } void BuildVisitor::Visit(TupleType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t current_node_n = 0; @@ -1239,6 +1332,8 @@ void BuildVisitor::Visit(TupleType* node) { } void BuildVisitor::Visit(VariantType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t current_node_n = 0; @@ -1274,6 +1369,8 @@ void BuildVisitor::Visit(VariantType* node) { } void BuildVisitor::Visit(TypeExpression* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t excluded_child_count = 0; @@ -1337,6 +1434,8 @@ void BuildVisitor::Visit(AnyType& node) { } void BuildVisitor::Visit(ExtendedScopedAnyType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; size_t child_count = parse_node.ChildCount(); @@ -1362,9 +1461,12 @@ void BuildVisitor::Visit(ExtendedScopedAnyType* node) { // Typeclass void BuildVisitor::Visit(ParametrizedTypeclass* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; - node->typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); + std::string prefixed_typeclass = parse_node.ChildByFieldName("typeclass").GetValue(); // prefix # removed + node->typeclass = prefixed_typeclass.substr(1, prefixed_typeclass.size() - 1); size_t child_count = parse_node.NamedChildCount(); @@ -1385,6 +1487,8 @@ void BuildVisitor::Visit(ParametrizedTypeclass* node) { void BuildVisitor::Visit(ParametrizedType* node) { + SetPosition(node->base, current_node_); + auto parse_node = current_node_; node->type = parse_node.ChildByFieldName("type").GetValue(); @@ -1407,6 +1511,8 @@ void BuildVisitor::Visit(ParametrizedType* node) { // Identifiers, constants, etc. ----------------- void BuildVisitor::Visit(ExtendedName* node) { + SetPosition(node->base, current_node_); + size_t child_count = current_node_.NamedChildCount(); if (child_count > 1) { node->name = current_node_.GetValue(); @@ -1415,29 +1521,39 @@ void BuildVisitor::Visit(ExtendedName* node) { } } -void BuildVisitor::Visit(AnyIdentifier* node) { // std::string - *node = current_node_.GetValue(); -} +// void BuildVisitor::Visit(AnyIdentifier* node) { // std::string +// *node = current_node_.GetValue(); +// } void BuildVisitor::Visit(FloatNumberLiteral* node) { + SetPosition(node->base, current_node_); + node->value = std::stod(current_node_.GetValue()); } void BuildVisitor::Visit(NumberLiteral* node) { + SetPosition(node->base, current_node_); + node->value = std::stoll(current_node_.GetValue()); } void BuildVisitor::Visit(StringLiteral* node) { + SetPosition(node->base, current_node_); + std::string literal = current_node_.GetValue(); node->value = literal.substr(1, literal.size() - 2); } void BuildVisitor::Visit(CharLiteral* node) { + SetPosition(node->base, current_node_); + std::string literal = current_node_.GetValue(); node->value = literal.substr(1, literal.size() - 2).back(); // TODO: special symbols, etc. } -void BuildVisitor::Visit(UnitLiteral* node) {} +void BuildVisitor::Visit(UnitLiteral* node) { + SetPosition(node->base, current_node_); +} void BuildVisitor::Visit(Literal& node) { auto parse_node = current_node_; diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 775df69..c5c7986 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -18,8 +18,9 @@ void LinkSymbolsVisitor::Visit(Namespace* node) { } if (maybe_type.has_value() && maybe_typeclass.has_value()) { - error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)"); + error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)", node->base); } + if (maybe_type.has_value()) { node->link_type_id_ = maybe_type.value(); } @@ -50,14 +51,14 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type); if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) { - error_handling::HandleTypecheckError("Type or constructor not found"); + error_handling::HandleTypecheckError("Type or constructor not found", node->base); } if (node->constructor_id_.has_value()) { utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id; if (node->type_id_.has_value() && node->type_id_.value() != constructor_type_id) { - error_handling::HandleTypecheckError("Contructor and type with same name have different types"); + error_handling::HandleTypecheckError("Contructor and type with same name have different types", node->base); } node->type_id_ = constructor_type_id; @@ -96,7 +97,7 @@ void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check if (maybe_typeclass.has_value()) { node->typeclass_id_ = maybe_typeclass.value(); } else { - error_handling::HandleTypecheckError("Type not found"); + error_handling::HandleTypecheckError("Type not found", node->base); } } diff --git a/src/main.cpp b/src/main.cpp index 4f18847..7224127 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "../include/interpreter_tree.hpp" #include "../include/build_visitor.hpp" #include "../include/print_visitor.hpp" +#include "../include/error_handling.hpp" int main(int argc, char** argv) { // TODO, only test version if (argc < 2 || argc > 2) { @@ -29,6 +30,10 @@ int main(int argc, char** argv) { // TODO, only test version parser::ParseTree parse_tree(source); + if (!parse_tree.IsProperlyParsed()) { + error_handling::HandleParsingError("There are some parsing errors in file.", {0, 0}); + } + std::unique_ptr source_file = std::make_unique(); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 4aa49a9..b9870a9 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -17,7 +17,6 @@ void TypeCheckVisitor::Visit(SourceFile* node) { for (auto& statement : node->statements) { Visitor::Visit(statement); } - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } @@ -27,13 +26,11 @@ void TypeCheckVisitor::Visit(PartitionSources* node) { for (auto& statement : node->statements) { Visitor::Visit(statement); } - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } void TypeCheckVisitor::Visit(Partition* node) { Visit(&node->scope); - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } @@ -41,15 +38,27 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { for (auto& statement : node->statements) { Visitor::Visit(statement); } - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } void TypeCheckVisitor::Visit(Namespace* node) { if (node->modifier.has_value()) { // TODO + if (node->link_typeclass_id_.has_value()) { + + } + + if (node->link_type_id_.has_value()) { + + } + // Visit(node->link_type_id_); + // context_manager_.EnterVariableContext(node->name.value().name, - // context_manager_.AddType(info::type::DefinedType {node->type_id_.value()})); + // context_manager_.AddType(info::type::DefinedType {node->type_id_.value()})); + } else { + if (node->link_typeclass_id_.has_value()) { // ?? + error_handling::HandleTypecheckError("Typeclass can't have not variable namespace", node->base); + } } namespace_visitor_.EnterNamespace(node->type); @@ -57,7 +66,6 @@ void TypeCheckVisitor::Visit(Namespace* node) { Visit(&node->scope); namespace_visitor_.ExitNamespace(); - current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } @@ -119,7 +127,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { const info::definition::Function& function_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_); if (!function_info.declaration.has_value()) { - error_handling::HandleTypecheckError("Function defined, but not declared"); + error_handling::HandleTypecheckError("Function defined, but not declared", node->base); } const info::definition::FunctionDeclaration& declaration = function_info.declaration.value(); @@ -133,7 +141,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { // TODO: add recursive typeclasses from typeclass tree current_type_ = context_manager_.AddType(info::type::AbstractType(parameter.type, requirements)); // TODO: move requirements if (!context_manager_.DefineLocalAbstractType(parameter.type, current_type_)) { - error_handling::HandleTypecheckError("Can't define function parameter type: type redefinition"); + error_handling::HandleTypecheckError("Can't define function parameter type: type redefinition", node->base); } } @@ -141,7 +149,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { for (size_t i = 0; i < node->definition->arguments.size(); ++i) { Visitor::Visit(*declaration.argument_types[i]); // TODO: ConstructAnyType if (!context_manager_.DefineVariable(node->definition->arguments[i].name, current_type_, true)) { // TODO: watch to reference - error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition"); + error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base); } } @@ -150,7 +158,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { Visitor::Visit(node->value); if (!context_manager_.EqualTypes(return_type, current_type_)) { - error_handling::HandleTypecheckError("Wrong function return type"); + error_handling::HandleTypecheckError("Wrong function return type", node->base); } context_manager_.ExitContext(); @@ -183,7 +191,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { // TODO: add recursive typeclasses from typeclass tree current_type_ = context_manager_.AddType(info::type::AbstractType(node->type->type, requirements)); if (!context_manager_.DefineLocalAbstractType(node->type->type, current_type_)) { - error_handling::HandleTypecheckError("Can't define basic/bastract type: type redefinition"); + error_handling::HandleTypecheckError("Can't define basic/bastract type: type redefinition", node->base); } current_type_ = context_manager_.AddType(info::type::InternalType::Unit); @@ -316,7 +324,7 @@ void TypeCheckVisitor::Visit(ForLoop* node) { std::optional maybe_interval_type = context_manager_.GetType(current_type_); if (!maybe_interval_type.has_value()) { - error_handling::HandleTypecheckError("For loop interval type mismatch"); + error_handling::HandleTypecheckError("For loop interval type mismatch", node->base); } current_type_ = context_manager_.AddType(maybe_interval_type.value()->GetElementsType()); @@ -351,7 +359,7 @@ void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (prob is_first_returned_type = false; } else { if (!context_manager_.EqualTypes(type, returned_type_.value())) { - error_handling::HandleTypecheckError("Different return types in block"); + error_handling::HandleTypecheckError("Different return types in block", node->base); } } } @@ -381,25 +389,25 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name); if (!maybe_operator_id.has_value()) { - error_handling::HandleTypecheckError("Operator not found"); + error_handling::HandleTypecheckError("Operator not found", node->base); } const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); if (!operator_info.declaration.has_value()) { - error_handling::HandleTypecheckError("Operator declaration not found"); + error_handling::HandleTypecheckError("Operator declaration not found", node->base); } if (!operator_info.definition.has_value()) { // TODO: builtin - error_handling::HandleTypecheckError("Operator definition not found"); + error_handling::HandleTypecheckError("Operator definition not found", node->base); } if (operator_info.argument_count != 2) { - error_handling::HandleTypecheckError("Operator wrong argument count"); + error_handling::HandleTypecheckError("Operator wrong argument count", node->base); } if (operator_info.declaration->parameters.size() > 0) { - error_handling::HandleTypecheckError("Operator with parameters"); + error_handling::HandleTypecheckError("Operator with parameters", node->base); } Visitor::Visit(*operator_info.declaration.value().argument_types[0]); @@ -421,25 +429,25 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) { auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name); if (!maybe_operator_id.has_value()) { - error_handling::HandleTypecheckError("Operator not found"); + error_handling::HandleTypecheckError("Operator not found", node->base); } const info::definition::Function& operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); if (!operator_info.declaration.has_value()) { - error_handling::HandleTypecheckError("Operator declaration not found"); + error_handling::HandleTypecheckError("Operator declaration not found", node->base); } if (!operator_info.definition.has_value()) { // TODO: builtin - error_handling::HandleTypecheckError("Operator definition not found"); + error_handling::HandleTypecheckError("Operator definition not found", node->base); } if (operator_info.argument_count != 1) { - error_handling::HandleTypecheckError("Operator wrong argument count"); + error_handling::HandleTypecheckError("Operator wrong argument count", node->base); } if (operator_info.declaration->parameters.size() > 0) { - error_handling::HandleTypecheckError("Operator with parameters"); + error_handling::HandleTypecheckError("Operator with parameters", node->base); } Visitor::Visit(*operator_info.declaration.value().argument_types[0]); @@ -466,7 +474,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { std::optional maybe_type_value = context_manager_.GetType(current_type_); if (!maybe_type_value.has_value()) { - error_handling::HandleTypecheckError("Access type mismatch"); + error_handling::HandleTypecheckError("Access type mismatch", node->base); } current_type_ = maybe_type_value.value()->GetElementsType(); @@ -483,7 +491,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { // guaranteed, that name.size() > 0 if (node->name.name[0] == '_') { // TODO: manage pointers to function - error_handling::HandleInternalError("Builtin functions/methods weren't implemented yet", "TypeCheckVisitor.FunctionCallExpresssion"); + error_handling::HandleInternalError("Builtin functions/methods weren't implemented yet", + "TypeCheckVisitor.FunctionCallExpresssion"); } if (node->prefix.has_value()) { @@ -494,7 +503,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { std::optional maybe_expression_type = context_manager_.GetType(current_type_); if (!maybe_expression_type.has_value()) { - error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type"); + error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", node->base); } utils::IdType type_id = maybe_expression_type.value()->GetTypeId(); @@ -502,7 +511,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { const std::optional& maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { - error_handling::HandleInternalError("Functions/Methods implemented only for AnyType", "TypeCheckVisitor.FunctionCallExpresssion"); + error_handling::HandleInternalError("Functions/Methods implemented only for AnyType", + "TypeCheckVisitor.FunctionCallExpresssion"); } // TODO: better decision ?? @@ -529,20 +539,20 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } if (!maybe_function_id.has_value()) { - error_handling::HandleTypecheckError("Can't find function"); // InterlnalError ?? + error_handling::HandleTypecheckError("Can't find function", node->base); // InterlnalError ?? } std::optional maybe_function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_function_id.value()).declaration; if (!maybe_function_declaration.has_value()) { - error_handling::HandleTypecheckError("No function declaration found for function in function call expression"); + error_handling::HandleTypecheckError("No function declaration found for function in function call expression", node->base); } info::definition::FunctionDeclaration function_declaration = maybe_function_declaration.value(); // if (function_declaration.parameters.size() != node->parameters.size()) { - error_handling::HandleTypecheckError("Mismatched parameter count in function call expression"); + error_handling::HandleTypecheckError("Mismatched parameter count in function call expression", node->base); } for (size_t i = 0; i < node->parameters.size(); ++i) { Visit(node->parameters[i].get()); @@ -550,7 +560,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { std::string parameter_name = function_declaration.parameters[i].type; if (context.count(parameter_name) != 0) { - error_handling::HandleInternalError("Local abstract types with same name in one context", "TypeCheckVisitor.FunctionCallExpresssion"); // TypecheckError ?? + error_handling::HandleInternalError("Local abstract types with same name in one context", + "TypeCheckVisitor.FunctionCallExpresssion"); // TypecheckError ?? } context[parameter_name] = current_type_; } @@ -558,7 +569,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { // if (function_declaration.argument_types.size() + 1 != node->arguments.size()) { - error_handling::HandleTypecheckError("Mismatched argument count in function call expression"); + error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base); } for (size_t i = 0; i < node->arguments.size(); ++i) { Visitor::Visit(node->arguments[i]); @@ -611,7 +622,7 @@ void Visitor::Visit(TypeConstructorParameter* node) {} // Handeled in TypeConstr void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor names, etc. // Visit(node->constructor.get()); if (!node->constructor->constructor_id_.has_value()) { - error_handling::HandleTypecheckError("Type constructor name not found"); + error_handling::HandleTypecheckError("Type constructor name not found", node->base); } if (!node->constructor->type_id_.has_value()) { @@ -646,7 +657,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor TupleType* constructor_fields = constructor_info.constructor_tuple_node.value(); if (constructor_fields->entities.size() != node->parameters.size()) { - error_handling::HandleTypecheckError("Type constructor parameters count mismatch"); + error_handling::HandleTypecheckError("Type constructor parameters count mismatch", node->base); } for (size_t i = 0; i < node->parameters.size(); ++i) { @@ -655,11 +666,11 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor if (node->parameters[i].name.has_value()) { if (!constructor_fields->entities[i].first.has_value() || constructor_fields->entities[i].first.value().name != node->parameters[i].name.value().name) { - error_handling::HandleTypecheckError("Type constructor: name of parameter and name in constructor don't match each other"); + error_handling::HandleTypecheckError("Type constructor: name of parameter and name in constructor don't match each other", node->base); } } else { if (constructor_fields->entities[i].first.has_value()) { - error_handling::HandleTypecheckError("Type constructor: unnamed pprameter corresponds named field"); + error_handling::HandleTypecheckError("Type constructor: unnamed pprameter corresponds named field", node->base); } } @@ -673,7 +684,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor } else { if (node->parameters.size() > 0) { - error_handling::HandleTypecheckError("Parameters for untyped type constructor"); + error_handling::HandleTypecheckError("Parameters for untyped type constructor", node->base); } } @@ -683,7 +694,8 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor // TODO void TypeCheckVisitor::Visit(LambdaFunction* node) { - error_handling::HandleInternalError("Unimplemented (unsolved type deduction problems)", "TypeCheckVisitor.LambdaFunction"); + error_handling::HandleInternalError("Unimplemented (unsolved type deduction problems)", + "TypeCheckVisitor.LambdaFunction"); } void TypeCheckVisitor::Visit(ArrayExpression* node) { @@ -695,7 +707,7 @@ void TypeCheckVisitor::Visit(ArrayExpression* node) { elements_type = current_type_; } else { if (!context_manager_.EqualTypes(elements_type, current_type_)) { - error_handling::HandleTypecheckError("Different element types in array expression"); + error_handling::HandleTypecheckError("Different element types in array expression", node->base); } } } @@ -742,11 +754,11 @@ void TypeCheckVisitor::Visit(TupleName* node) { std::optional maybe_type_value = context_manager_.GetType(type); if (maybe_type_value.has_value()) { - error_handling::HandleTypecheckError("Mismatched types in tuple variable definition"); + error_handling::HandleTypecheckError("Mismatched types in tuple variable definition", node->base); } if (maybe_type_value.value()->GetFields().size() != node->names.size()) { - error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition"); + error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition", node->base); } for (size_t i = 0; i < node->names.size(); ++i) { current_type_ = maybe_type_value.value()->GetFields()[i].second; @@ -767,11 +779,11 @@ void TypeCheckVisitor::Visit(VariantName* node) { std::optional maybe_type_value = context_manager_.GetType(type); if (!maybe_type_value.has_value()) { - error_handling::HandleTypecheckError("Mismatched types in variant variable definition"); + error_handling::HandleTypecheckError("Mismatched types in variant variable definition", node->base); } if (maybe_type_value.value()->GetConstructors().size() != node->names.size()) { - error_handling::HandleTypecheckError("Mismatched variant count in variant variable definition"); + error_handling::HandleTypecheckError("Mismatched variant count in variant variable definition", node->base); } for (size_t i = 0; i < node->names.size(); ++i) { @@ -873,8 +885,18 @@ void TypeCheckVisitor::Visit(TypeExpression* node) { error_handling::HandleInternalError("No any type found", "TypeCheckVisitor.TypeExpression"); } + std::optional maybe_local_abstract_type = context_manager_.GetLocalAbstractType(node->type.type); + if (node->path.size() == 0 && maybe_local_abstract_type.has_value()) { + current_type_ = maybe_local_abstract_type.value(); + } + Visitor::Visit(*maybe_type_info.value().value); - current_type_ = TypeInContext(current_type_, context); // TODO: check + current_type_ = TypeInContext(current_type_, context); + + if (node->array_size.has_value()) { + current_type_ = context_manager_.AddType( + info::type::ArrayType(node->array_size.value(), current_type_, context_manager_.GetTypeManager())); + } } void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) { @@ -936,7 +958,7 @@ void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type, const info::definition::AnyType& type_info = maybe_type_info.value(); if (type_info.parameters.size() != type.parameters.size()) { - error_handling::HandleTypecheckError("Wrong type parameters count"); + error_handling::HandleTypecheckError("Wrong type parameters count", type.base); } for (size_t i = 0; i < type.parameters.size(); ++i) { diff --git a/tests/memory.lang b/tests/memory.lang index c36f930..6419e3f 100644 --- a/tests/memory.lang +++ b/tests/memory.lang @@ -1,5 +1,5 @@ struct StructWithRef = - & @Int_ + & @Int_0 decl test_memory : Unit -> Unit def test_memory = {