diff --git a/source/parser/ast/include/config/AST_Declarations.def b/source/parser/ast/include/config/AST_Declarations.def index 0c228f0..6773413 100644 --- a/source/parser/ast/include/config/AST_Declarations.def +++ b/source/parser/ast/include/config/AST_Declarations.def @@ -13,7 +13,7 @@ #ifndef __AST_DECLARATIONS_DEF__ #define __AST_DECLARATIONS_DEF__ -#define DECLS(MACRO) \ +#define DECLS(MACRO) \ MACRO(RequiresParamDecl) \ MACRO(RequiresParamList) \ MACRO(EnumMemberDecl) \ @@ -21,6 +21,7 @@ MACRO(TypeBoundList) \ MACRO(TypeBoundDecl) \ MACRO(RequiresDecl) \ + MACRO(ModuleDecl) \ MACRO(StructDecl) \ MACRO(ConstDecl) \ MACRO(ClassDecl) \ @@ -31,6 +32,6 @@ MACRO(VarDecl) \ MACRO(FFIDecl) \ MACRO(LetDecl) \ - MACRO(OpDecl) \ + MACRO(OpDecl) #endif // __AST_DECLARATIONS_DEF__ \ No newline at end of file diff --git a/source/parser/ast/include/config/AST_Expressions.def b/source/parser/ast/include/config/AST_Expressions.def index c7ff5fe..e4fb703 100644 --- a/source/parser/ast/include/config/AST_Expressions.def +++ b/source/parser/ast/include/config/AST_Expressions.def @@ -21,7 +21,6 @@ MACRO(NamedArgumentExpr) \ MACRO(ArgumentExpr) \ MACRO(ArgumentListExpr) \ - MACRO(GenericArgumentExpr) \ MACRO(GenericInvokeExpr) \ MACRO(GenericInvokePathExpr) \ MACRO(ScopePathExpr) \ diff --git a/source/parser/ast/include/config/AST_modifiers.hh b/source/parser/ast/include/config/AST_modifiers.hh index 4beec32..ac52d4d 100644 --- a/source/parser/ast/include/config/AST_modifiers.hh +++ b/source/parser/ast/include/config/AST_modifiers.hh @@ -424,6 +424,10 @@ __AST_BEGIN { } } + // so if we set the modifiers to another Modifiers object + // we can copy the expected_modifiers and allowed_modifiers and verify if the other + // object has the modifiers we are looking for + static bool is_modifier(const token::Token &tok, ExpectedModifier modifier) { switch (modifier) { case ExpectedModifier::StorageSpec: @@ -444,11 +448,17 @@ __AST_BEGIN { return false; } } + static bool is_modifier(const token::Token &tok) { + return StorageSpecifier::is_storage_specifier(tok) || + AccessSpecifier::is_access_specifier(tok) || + FunctionSpecifier::is_function_specifier(tok) || + ClassSpecifier::is_class_specifier(tok); + } [[nodiscard]] bool find_add(const token::Token ¤t_token) { if (allowed_modifiers.find(current_token.token_kind()) == allowed_modifiers.end()) { - return false; + return false; // not a modifier } for (const auto &modifier_type : expected_modifiers) { diff --git a/source/parser/ast/include/core/AST_nodes.hh b/source/parser/ast/include/core/AST_nodes.hh index 633f3a7..76cf665 100644 --- a/source/parser/ast/include/core/AST_nodes.hh +++ b/source/parser/ast/include/core/AST_nodes.hh @@ -83,8 +83,6 @@ __AST_NODE_BEGIN { return parse_ArgumentExpr(std ::forward(args)...); } else if constexpr (std ::is_same_v) { return parse_ArgumentListExpr(std ::forward(args)...); - } else if constexpr (std ::is_same_v) { - return parse_GenericArgumentExpr(std ::forward(args)...); } else if constexpr (std ::is_same_v) { return parse_GenericInvokeExpr(std ::forward(args)...); } else if constexpr (std ::is_same_v) { @@ -140,7 +138,6 @@ __AST_NODE_BEGIN { p_r parse_ScopePathExpr(p_r<> lhs = null); p_r parse_ArrayAccessExpr(p_r<> lhs = null); p_r parse_ArgumentListExpr(); - p_r parse_GenericArgumentExpr(); p_r parse_GenericInvokeExpr(); p_r parse_GenericInvokePathExpr(); p_r parse_ArrayLiteralExpr(); @@ -156,7 +153,7 @@ __AST_NODE_BEGIN { p_r parse_InstOfExpr(p_r<> lhs = null); p_r parse_Type(); p_r parse_AsyncThreading(); - p_r parse_FunctionCallExpr(p_r<> lhs = null, p_r<> gens = null); + p_r parse_FunctionCallExpr(p_r<> lhs = null); }; /* @@ -326,7 +323,9 @@ __AST_NODE_BEGIN { return parse_LetDecl(std ::forward(args)...); } else if constexpr (std ::is_same_v) { return parse_OpDecl(std ::forward(args)...); - }; + } else if constexpr (std ::is_same_v) { + return parse_ModuleDecl(std ::forward(args)...); + } } private: @@ -340,17 +339,18 @@ __AST_NODE_BEGIN { p_r parse_TypeBoundList(); p_r parse_TypeBoundDecl(); p_r parse_RequiresDecl(); - p_r parse_StructDecl(); + p_r parse_ModuleDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_StructDecl(const std::shared_ptr& modifiers = nullptr); p_r parse_ConstDecl(); - p_r parse_ClassDecl(); - p_r parse_InterDecl(); - p_r parse_EnumDecl(); - p_r parse_TypeDecl(); - p_r parse_FuncDecl(); - p_r parse_VarDecl(); - p_r parse_FFIDecl(); - p_r parse_LetDecl(); - p_r parse_OpDecl(); + p_r parse_ClassDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_InterDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_EnumDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_TypeDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_FuncDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_VarDecl(bool force_type = false, bool force_value = false); + p_r parse_FFIDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_LetDecl(const std::shared_ptr& modifiers = nullptr); + p_r parse_OpDecl(const std::shared_ptr& modifiers = nullptr); }; } // namespace __AST_BEGIN diff --git a/source/parser/ast/include/nodes/AST_Declarations.hh b/source/parser/ast/include/nodes/AST_Declarations.hh index 76e9dbc..7dfba53 100644 --- a/source/parser/ast/include/nodes/AST_Declarations.hh +++ b/source/parser/ast/include/nodes/AST_Declarations.hh @@ -25,66 +25,73 @@ __AST_NODE_BEGIN { class RequiresParamDecl final : public Node { BASE_CORE_METHODS(RequiresParamDecl); - + // RequiresParamDecl := 'const'? (S.NamedVarSpecifier) ('=' E)? explicit RequiresParamDecl(bool /* unused */) {} NodeT var; - NodeT<> value; - bool is_const = false; + NodeT<> value; + bool is_const = false; }; class RequiresParamList final : public Node { BASE_CORE_METHODS(RequiresParamList); - + // RequiresParamList := (RequiresParamDecl (',' RequiresParamDecl)*)? - explicit RequiresParamList(NodeT first) { (this->params).emplace_back(std::move(first)); } - + explicit RequiresParamList(NodeT first) { + (this->params).emplace_back(std::move(first)); + } + NodeV params; }; class EnumMemberDecl final : public Node { BASE_CORE_METHODS(EnumMemberDecl); - + // EnumMemberDecl := E.IdentExpr ('=' E)? - explicit EnumMemberDecl(NodeT name) : name(std::move(name)) {} + explicit EnumMemberDecl(NodeT name) + : name(std::move(name)) {} NodeT name; - NodeT<> value; + NodeT<> value; }; - + class UDTDeriveDecl final : public Node { BASE_CORE_METHODS(UDTDeriveDecl); - + // UDTDeriveDecl := 'derives' (VisDecl? E.Type (',' VisDecl? E.Type)*)? - explicit UDTDeriveDecl(std::pair, AccessSpecifier> first) { (this->derives).emplace_back(std::move(first)); } - + explicit UDTDeriveDecl(std::pair, AccessSpecifier> first) { + (this->derives).emplace_back(std::move(first)); + } + std::vector, AccessSpecifier>> derives; }; class TypeBoundList final : public Node { BASE_CORE_METHODS(TypeBoundList); - + // TypeBoundList := (TypeBoundDecl (',' TypeBoundDecl)*)? - explicit TypeBoundList(NodeT bound) { (this->bounds).emplace_back(std::move(bound)); } + explicit TypeBoundList(NodeT bound) { + (this->bounds).emplace_back(std::move(bound)); + } NodeV bounds; }; class TypeBoundDecl final : public Node { BASE_CORE_METHODS(TypeBoundDecl); - - // TypeBoundDecl := InstOfExpr + // TypeBoundDecl := InstOfExpr NodeT bound; }; class RequiresDecl final : public Node { BASE_CORE_METHODS(RequiresDecl); - + // RequiresDecl := 'requires' '<' RequiresParamList '>' ('if' TypeBoundList)? - explicit RequiresDecl(NodeT params) : params(std::move(params)) {} + explicit RequiresDecl(NodeT params) + : params(std::move(params)) {} NodeT params; NodeT bounds; @@ -92,7 +99,7 @@ __AST_NODE_BEGIN { class StructDecl final : public Node { BASE_CORE_METHODS(StructDecl); - + // StructDecl := 'const'? VisDecl? 'struct' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite explicit StructDecl(bool /* unused */) {} @@ -101,24 +108,29 @@ __AST_NODE_BEGIN { NodeT generics; NodeT body; - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::AccessSpec, Modifiers::ExpectedModifier::ClassSpec); + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::ClassSpec, + Modifiers::ExpectedModifier::AccessSpec); }; class ConstDecl final : public Node { BASE_CORE_METHODS(ConstDecl); - + // ConstDecl := VisDecl? 'const' SharedModifiers VarDecl* ';' NodeV vars; - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); }; class ClassDecl final : public Node { BASE_CORE_METHODS(ClassDecl); - - // ClassDecl := 'const'? VisDecl? 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + // ClassDecl := 'const'? VisDecl? 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? + // S.Suite + + explicit ClassDecl(bool /* unused */) {} + + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::ClassSpec, + Modifiers::ExpectedModifier::AccessSpec); NodeT name; NodeT derives; NodeT generics; @@ -127,10 +139,14 @@ __AST_NODE_BEGIN { class InterDecl final : public Node { BASE_CORE_METHODS(InterDecl); - - // InterDecl := 'const'? VisDecl? 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + // InterDecl := 'const'? VisDecl? 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? + // S.Suite + + explicit InterDecl(bool /* unused */) {} + + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::ClassSpec, + Modifiers::ExpectedModifier::AccessSpec); NodeT name; NodeT derives; NodeT generics; @@ -139,21 +155,22 @@ __AST_NODE_BEGIN { class EnumDecl final : public Node { BASE_CORE_METHODS(EnumDecl); - + // EnumDecl := VisDecl? 'enum' ('derives' E.Type)? E.ObjInitExpr + explicit EnumDecl(bool /* unused */) {} - AccessSpecifier vis; - NodeT name; - NodeT derives; - NodeT body; + Modifiers vis = Modifiers(Modifiers::ExpectedModifier::AccessSpec); + NodeT name; + NodeT derives; + NodeV members; }; class TypeDecl final : public Node { BASE_CORE_METHODS(TypeDecl); - + // TypeDecl := VisDecl? 'type' E.IdentExpr RequiresDecl? '=' E ';' - AccessSpecifier vis; + Modifiers vis = Modifiers(Modifiers::ExpectedModifier::AccessSpec); NodeT name; NodeT generics; NodeT<> value; @@ -161,10 +178,14 @@ __AST_NODE_BEGIN { class FuncDecl final : public Node { BASE_CORE_METHODS(FuncDecl); - - // FuncDecl := SharedModifiers? 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? ('->' E.TypeExpr)? (S.Suite | ';' | '=' ('default' | 'delete')) - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + // FuncDecl := SharedModifiers? 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? ('->' + // E.TypeExpr)? (S.Suite | ';' | '=' ('default' | 'delete')) + + explicit FuncDecl(bool /* unused */) {} + + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec, + Modifiers::ExpectedModifier::AccessSpec); Modifiers qualifiers = Modifiers(Modifiers::ExpectedModifier::FuncQual); NodeT name; @@ -176,42 +197,65 @@ __AST_NODE_BEGIN { class VarDecl final : public Node { BASE_CORE_METHODS(VarDecl); - + // VarDecl := S.NamedVarSpecifier ('=' E)? ~ also pass in a bool to force type need + explicit VarDecl(NodeT var, NodeT<> value = nullptr) + : var(std::move(var)) + , value(std::move(value)) {} NodeT var; - NodeT<> value; + NodeT<> value; }; class FFIDecl final : public Node { BASE_CORE_METHODS(FFIDecl); - + // FFIDecl := VisDecl? 'ffi' L.StringLiteral D - AccessSpecifier vis; + Modifiers vis = Modifiers(Modifiers::ExpectedModifier::AccessSpec); NodeT name; NodeT<> value; }; class LetDecl final : public Node { BASE_CORE_METHODS(LetDecl); - + // LetDecl := VisDecl? 'let' SharedModifiers VarDecl* ';' + explicit LetDecl(bool /* unused */) {} - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + Modifiers vis = Modifiers(Modifiers::ExpectedModifier::AccessSpec); NodeV vars; }; class OpDecl final : public Node { BASE_CORE_METHODS(OpDecl); - + // OpDecl := SharedModifiers? 'op' T FuncDecl[no_SharedModifiers=true] - Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec); + Modifiers modifiers = Modifiers(Modifiers::ExpectedModifier::FuncSpec, + Modifiers::ExpectedModifier::AccessSpec); token::Token op; NodeT func; }; + class ModuleDecl final : public Node { + BASE_CORE_METHODS(ModuleDecl); + + // ModuleDecl := 'inline'? 'module' E.PathExpr S.Suite + explicit ModuleDecl(NodeT name, + NodeT body, + bool inline_module = false) + + : body(std::move(body)) + , name(std::move(name)) + , inline_module(inline_module) {} + + NodeT body; + NodeT name; + bool inline_module = false; + }; + } // namespace __AST_NODE_BEGIN #endif // __AST_DECLARATIONS_H__ \ No newline at end of file diff --git a/source/parser/ast/include/nodes/AST_Expressions.hh b/source/parser/ast/include/nodes/AST_Expressions.hh index c0a8903..9f7ef3a 100644 --- a/source/parser/ast/include/nodes/AST_Expressions.hh +++ b/source/parser/ast/include/nodes/AST_Expressions.hh @@ -14,6 +14,7 @@ #define __AST_EXPRESSIONS_H__ #include "parser/ast/include/config/AST_config.def" +#include "parser/ast/include/config/AST_modifiers.hh" #include "parser/ast/include/core/AST_nodes.hh" #include "parser/ast/include/types/AST_types.hh" @@ -116,22 +117,8 @@ __AST_NODE_BEGIN { NodeV<> args; }; - class GenericArgumentExpr final : public Node { // := GenericPositionalArgumentExpr - // | GenericNamedArgumentExprExpr - BASE_CORE_METHODS(GenericArgumentExpr); - - explicit GenericArgumentExpr(NodeT<> value); - - enum class ArgumentType { - Positional, - Keyword, - }; - - NodeT<> value; - }; - class GenericInvokeExpr final - : public Node { // := '<' GenericArgumentExpr ((',' GenericArgumentExpr)*)? '>' + : public Node { // := '<' Type ((',' Type)*)? '>' BASE_CORE_METHODS(GenericInvokeExpr); explicit GenericInvokeExpr(NodeT<> args) { @@ -339,22 +326,15 @@ __AST_NODE_BEGIN { class Type final : public Node { // := IdentExpr BASE_CORE_METHODS(Type); - enum class TypeType { - Identifier, - Pointer, - Reference, - Lambda, - }; - explicit Type(NodeT<> value) - : value(std::move(value)) - , type(TypeType::Identifier) {} + : value(std::move(value)) {} explicit Type(NodeT value) - : value(std::move(value)) - , type(TypeType::Lambda) {} + : value(std::move(value)) {} + explicit Type(bool /* unused */) {} NodeT<> value; - TypeType type; + NodeT generics; + Modifiers specifiers = Modifiers(Modifiers::ExpectedModifier::TypeSpec); }; class AsyncThreading final : public Node { // := IdentExpr diff --git a/source/parser/ast/source/nodes/Decls.cc b/source/parser/ast/source/nodes/Decls.cc index ac0000e..b7869ec 100644 --- a/source/parser/ast/source/nodes/Decls.cc +++ b/source/parser/ast/source/nodes/Decls.cc @@ -48,37 +48,38 @@ /// [x] * Declaration * D /// /// /// /// STS * /* generics and type bounds */ /// -/// [ ] * RequiresParamDecl * 'const'? (S.NamedVarSpecifier) ('=' E)? /// -/// [ ] * RequiresParamList * (RequiresParamDecl (',' RequiresParamDecl)*)? /// -/// [ ] * TypeBoundDecl * 'if' InstOfExpr /// -/// [ ] * TypeBoundList * (TypeBoundDecl (',' TypeBoundDecl)*)? /// -/// [ ] * RequiresDecl * 'requires' '<' RequiresParamList '>' TypeBoundList? /// -/// [ ] * EnumMemberDecl * E.IdentExpr ('=' E)? /// -/// [ ] * UDTDeriveDecl * 'derives' (E.Type (',' E.Type)*)? /// +/// [x] * RequiresParamDecl * 'const'? (S.NamedVarSpecifier) ('=' E)? /// +/// [x] * RequiresParamList * (RequiresParamDecl (',' RequiresParamDecl)*)? /// +/// [x] * TypeBoundDecl * 'if' InstOfExpr /// +/// [x] * TypeBoundList * (TypeBoundDecl (',' TypeBoundDecl)*)? /// +/// [x] * RequiresDecl * 'requires' '<' RequiresParamList '>' TypeBoundList? /// +/// [x] * EnumMemberDecl * E.IdentExpr ('=' E)? /// +/// [x] * UDTDeriveDecl * 'derives' (E.Type (',' E.Type)*)? /// /// /// /// /* declaration helpers */ /// -/// [ ] * StorageSpecifier * 'ffi' | 'static' | 'async' | 'eval' /// -/// [ ] * FFISpecifier * 'class' | 'interface' | 'struct' | 'enum' | 'union' | 'type' /// -/// [ ] * TypeQualifier * 'const' | 'module' | 'yield' | 'async' | 'ffi' | 'static' /// -/// [ ] * AccessSpecifier * 'pub' | 'priv' | 'prot' | 'intl' /// -/// [ ] * FunctionSpecifier * 'inline' | 'async' | 'static' | 'const' | 'eval' | 'other' /// -/// [ ] * FunctionQualifier * 'default' | 'panic' | 'delete' | 'const' /// +/// [x] * StorageSpecifier * 'ffi' | 'static' | 'async' | 'eval' /// +/// [x] * FFISpecifier * 'class' | 'interface' | 'struct' | 'enum' | 'union' | 'type' /// +/// [x] * TypeQualifier * 'const' | 'module' | 'yield' | 'async' | 'ffi' | 'static' /// +/// [x] * AccessSpecifier * 'pub' | 'priv' | 'prot' | 'intl' /// +/// [x] * FunctionSpecifier * 'inline' | 'async' | 'static' | 'const' | 'eval' | 'other' /// +/// [x] * FunctionQualifier * 'default' | 'panic' | 'delete' | 'const' /// /// /// -/// [ ] * VisDecl * AccessSpecifier // -/// [ ] * VarDecl * S.NamedVarSpecifier ('=' E)? ~ also pass in a bool to force type need // -/// [ ] * SharedModifiers * (FunctionSpecifier)*)? /// +/// [x] * VisDecl * AccessSpecifier // +/// [x] * VarDecl * S.NamedVarSpecifier ('=' E)? ~ also pass in a bool to force type need // +/// [x] * SharedModifiers * (FunctionSpecifier)*)? /// /// /// /// /* declaration nodes */ /// /// [ ] * FFIDecl * VisDecl? 'ffi' L.StringLiteral D /// /// [ ] * LetDecl * VisDecl? 'let' SharedModifiers VarDecl* ';' /// /// [ ] * ConstDecl * VisDecl? 'const' SharedModifiers VarDecl* ';' /// /// [ ] * TypeDecl * VisDecl? 'type' E.IdentExpr RequiresDecl? '=' E ';' /// -/// [ ] * EnumDecl * VisDecl? 'enum' ('derives' E.Type)? E.ObjInitExpr /// +/// [x] * EnumDecl * VisDecl? 'enum' ('derives' E.Type)? E.ObjInitExpr /// /// [ ] * OpDecl * SharedModifiers? 'op' T FuncDecl[no_SharedModifiers=true] /// -/// [ ] * FuncDecl * SharedModifiers? 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? S.Suite -/// [ ] * StructDecl* 'const'? VisDecl? 'struct' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite -/// [ ] * ClassDecl * 'const'? VisDecl? 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite -/// [ ] * InterDecl * 'const'? VisDecl? 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite +/// [x] * FuncDecl * SharedModifiers? 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? S.Suite +/// [x] * StructDecl* 'const'? VisDecl? 'struct' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite +/// [x] * ClassDecl * 'const'? VisDecl? 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite +/// [x] * InterDecl * 'const'? VisDecl? 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite +/// [x] * ModuleDecl* 'inline'? 'module' E.PathExpr S.Suite /// /// /// /// [ ] * ExtDecl * 'extend' E.PathExpr UDTDeriveDecl? S.Suite /* TODO: dont forget */ /// /// /// @@ -95,12 +96,14 @@ #include "neo-pprint/include/hxpprint.hh" #include "parser/ast/include/config/AST_config.def" #include "parser/ast/include/config/AST_generate.hh" +#include "parser/ast/include/config/AST_modifiers.hh" #include "parser/ast/include/config/case_types.def" #include "parser/ast/include/core/AST_nodes.hh" #include "parser/ast/include/nodes/AST_Expressions.hh" #include "parser/ast/include/types/AST_jsonify_visitor.hh" #include "parser/ast/include/types/AST_types.hh" #include "token/include/generate.hh" +#include "token/include/token_list.hh" AST_NODE_IMPL(Declaration, RequiresParamDecl) { IS_NOT_EMPTY; @@ -172,7 +175,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, RequiresParamList) { params.push_back(get_node_json(param)); } - json.section("RequiresParamList").add("params", params); + json.section("RequiresParamList", params); } // ---------------------------------------------------------------------------------------------- // @@ -252,7 +255,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, UDTDeriveDecl) { derives.push_back(derive.second.to_json()); } - json.section("UDTDeriveDecl").add("derives", derives); + json.section("UDTDeriveDecl", derives); } // ---------------------------------------------------------------------------------------------- // @@ -285,7 +288,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, TypeBoundList) { bounds.push_back(get_node_json(bound)); } - json.section("TypeBoundList").add("bounds", bounds); + json.section("TypeBoundList", bounds); } // ---------------------------------------------------------------------------------------------- // @@ -338,14 +341,23 @@ AST_NODE_IMPL_VISITOR(Jsonify, RequiresDecl) { // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, StructDecl) { +AST_NODE_IMPL(Declaration, StructDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // StructDecl := Modifiers 'struct' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite + // StructDecl := Modifiers 'struct' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite NodeT node = make_node(true); - while (node->modifiers.find_add(CURRENT_TOK)) { - iter.advance(); // skip modifier + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->modifiers.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for struct")); + } + } + } else { + while (node->modifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } } IS_EXCEPTED_TOKEN(token::KEYWORD_STRUCT); @@ -370,6 +382,11 @@ AST_NODE_IMPL(Declaration, StructDecl) { node->generics = generics.value(); } + if (CURRENT_TOKEN_IS(token::PUNCTUATION_SEMICOLON)) { // forward declaration + iter.advance(); // skip ';' + return node; + } + ParseResult body = state_parser.parse(); RETURN_IF_ERROR(body); @@ -378,7 +395,8 @@ AST_NODE_IMPL(Declaration, StructDecl) { return node; } -AST_NODE_IMPL_VISITOR(Jsonify, StructDecl) { json.section("StructDecl") +AST_NODE_IMPL_VISITOR(Jsonify, StructDecl) { + json.section("StructDecl") .add("name", get_node_json(node.name)) .add("derives", get_node_json(node.derives)) .add("generics", get_node_json(node.generics)) @@ -388,9 +406,9 @@ AST_NODE_IMPL_VISITOR(Jsonify, StructDecl) { json.section("StructDecl") // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, ConstDecl) { +AST_NODE_IMPL(Declaration, ConstDecl) { /* TODO - MAYBE REMOVE */ IS_NOT_EMPTY; - // ConstDecl := VisDecl? 'const' SharedModifiers VarDecl* ';' + // ConstDecl := Modifiers 'const' Modifiers VarDecl* ';' NOT_IMPLEMENTED; } @@ -399,42 +417,233 @@ AST_NODE_IMPL_VISITOR(Jsonify, ConstDecl) { json.section("ConstDecl"); } // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, ClassDecl) { +AST_NODE_IMPL(Declaration, ClassDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // ClassDecl := const'? VisDecl? 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite + // ClassDecl := Modifiers 'class' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite - NOT_IMPLEMENTED; + NodeT node = make_node(true); + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->modifiers.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for class")); + } + } + } else { + while (node->modifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_CLASS); + iter.advance(); // skip 'class' + + ParseResult name = expr_parser.parse(); + RETURN_IF_ERROR(name); + + node->name = name.value(); + + if (CURRENT_TOKEN_IS(token::KEYWORD_DERIVES)) { + ParseResult derives = parse(); + RETURN_IF_ERROR(derives); + + node->derives = derives.value(); + } + + if (CURRENT_TOKEN_IS(token::KEYWORD_REQUIRES)) { + ParseResult generics = parse(); + RETURN_IF_ERROR(generics); + + node->generics = generics.value(); + } + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_SEMICOLON)) { // forward declaration + iter.advance(); // skip ';' + return node; + } + + ParseResult body = state_parser.parse(); + RETURN_IF_ERROR(body); + + node->body = body.value(); + + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, ClassDecl) { json.section("ClassDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, ClassDecl) { + json.section("ClassDecl") + .add("name", get_node_json(node.name)) + .add("derives", get_node_json(node.derives)) + .add("generics", get_node_json(node.generics)) + .add("body", get_node_json(node.body)) + .add("modifiers", node.modifiers.to_json()); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, InterDecl) { +AST_NODE_IMPL(Declaration, InterDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // InterDecl := const'? VisDecl? 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite + // InterDecl := Modifiers 'interface' E.IdentExpr UDTDeriveDecl? RequiresDecl? S.Suite - NOT_IMPLEMENTED; + NodeT node = make_node(true); + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->modifiers.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for interface")); + } + } + } else { + while (node->modifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_INTERFACE); + iter.advance(); // skip 'interface' + + ParseResult name = expr_parser.parse(); + RETURN_IF_ERROR(name); + + node->name = name.value(); + + if (CURRENT_TOKEN_IS(token::KEYWORD_DERIVES)) { + ParseResult derives = parse(); + RETURN_IF_ERROR(derives); + + node->derives = derives.value(); + } + + if (CURRENT_TOKEN_IS(token::KEYWORD_REQUIRES)) { + ParseResult generics = parse(); + RETURN_IF_ERROR(generics); + + node->generics = generics.value(); + } + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_SEMICOLON)) { // forward declaration + return std::unexpected( + PARSE_ERROR(CURRENT_TOK, "forward declaration's are not allowed for interface's")); + } + + ParseResult body = state_parser.parse(); + RETURN_IF_ERROR(body); + + node->body = body.value(); + + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, InterDecl) { json.section("InterDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, InterDecl) { + json.section("InterDecl") + .add("name", get_node_json(node.name)) + .add("derives", get_node_json(node.derives)) + .add("generics", get_node_json(node.generics)) + .add("body", get_node_json(node.body)) + .add("modifiers", node.modifiers.to_json()); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, EnumDecl) { +AST_NODE_IMPL(Declaration, EnumDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // EnumDecl := VisDecl? 'enum' ('derives' E.Type)? E.ObjInitExpr + // EnumDecl := Modifiers 'enum' ('derives' E.Type)? (('{' (EnumMemberDecl (',' + // EnumMemberDecl)*)? '}') | (':' (EnumMemberDecl (',' EnumMemberDecl)*) ';')) - NOT_IMPLEMENTED; + NodeT node = make_node(true); + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->vis.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for enum")); + } + } + } else { + while (node->vis.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_ENUM); + iter.advance(); // skip 'enum' + + ParseResult name = expr_parser.parse(); + RETURN_IF_ERROR(name); + + node->name = name.value(); + + if (CURRENT_TOKEN_IS(token::KEYWORD_DERIVES)) { + iter.advance(); // skip 'derives' + + ParseResult derives = expr_parser.parse(); + RETURN_IF_ERROR(derives); + + node->derives = derives.value(); + } + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_OPEN_BRACE)) { + iter.advance(); // skip '{' + + while (CURRENT_TOKEN_IS(token::IDENTIFIER)) { + ParseResult member = parse(); + RETURN_IF_ERROR(member); + + node->members.emplace_back(member.value()); + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_COMMA)) { + iter.advance(); // skip ',' + } + } + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_CLOSE_BRACE); + iter.advance(); // skip '}' + + } else if (CURRENT_TOKEN_IS(token::PUNCTUATION_COLON)) { + iter.advance(); // skip ':' + + while (CURRENT_TOKEN_IS(token::IDENTIFIER)) { + ParseResult member = parse(); + RETURN_IF_ERROR(member); + + node->members.emplace_back(member.value()); + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_COMMA)) { + iter.advance(); // skip ',' + } + } + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_SEMICOLON); + iter.advance(); // skip ';' + + } else { + return std::unexpected(PARSE_ERROR(CURRENT_TOK, "expected enum body")); + } + + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, EnumDecl) { json.section("EnumDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, EnumDecl) { + std::vector members; + + for (const auto &member : node.members) { + members.push_back(get_node_json(member)); + } + + json.section("EnumDecl") + .add("derives", get_node_json(node.derives)) + .add("members", members) + .add("vis", node.vis.to_json()) + .add("name", get_node_json(node.name)); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, TypeDecl) { +AST_NODE_IMPL(Declaration, TypeDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // TypeDecl := VisDecl? 'type' E.IdentExpr RequiresDecl? '=' E ';' + // TypeDecl := Modifiers 'type' E.IdentExpr RequiresDecl? '=' E ';' NOT_IMPLEMENTED; } @@ -443,31 +652,163 @@ AST_NODE_IMPL_VISITOR(Jsonify, TypeDecl) { json.section("TypeDecl"); } // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, FuncDecl) { +AST_NODE_IMPL(Declaration, FuncDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // FuncDecl := SharedModifiers? 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? S.Suite + // FuncDecl := Modifiers 'fn' E.PathExpr '(' VarDecl[true]* ')' RequiresDecl? ('->' + // E.TypeExpr)? (S.Suite | ';' | '=' ('default' | 'delete')) - NOT_IMPLEMENTED; + // one rule to follow is we cant have keyword arguments after positional arguments + bool has_keyword = false; + + NodeT node = make_node(true); + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->modifiers.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for function")); + } + } + } else { + while (node->modifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_FUNCTION); + iter.advance(); // skip 'fn' + + ParseResult name = expr_parser.parse(); + RETURN_IF_ERROR(name); + + if (name.value()->type == PathExpr::PathType::Dot) { + return std::unexpected(PARSE_ERROR(CURRENT_TOK, "invalid function name")); + } + + node->name = name.value(); + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_OPEN_PAREN); + iter.advance(); // skip '(' + + while (CURRENT_TOKEN_IS(token::IDENTIFIER) || CURRENT_TOKEN_IS(token::KEYWORD_CONST)) { + token::Token starting = CURRENT_TOK; + + ParseResult param = parse(true); + RETURN_IF_ERROR(param); + + if (param.value()->value != nullptr) { + if (has_keyword) { + return std::unexpected( + PARSE_ERROR(starting, "positional argument after default argument")); + } + + has_keyword = true; + } + + node->params.emplace_back(param.value()); + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_COMMA)) { + iter.advance(); // skip ',' + } + } + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_CLOSE_PAREN); + iter.advance(); // skip ')' + + if (CURRENT_TOKEN_IS(token::KEYWORD_REQUIRES)) { + ParseResult generics = parse(); + RETURN_IF_ERROR(generics); + + node->generics = generics.value(); + } + + if (CURRENT_TOKEN_IS(token::OPERATOR_ARROW)) { + iter.advance(); // skip '->' + + ParseResult returns = expr_parser.parse(); + RETURN_IF_ERROR(returns); + + node->returns = returns.value(); + } + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_SEMICOLON)) { + iter.advance(); // skip ';' + } else if (CURRENT_TOKEN_IS(token::OPERATOR_ASSIGN)) { + iter.advance(); // skip '=' + + while (node->qualifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip qualifier + } + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_SEMICOLON); + iter.advance(); // skip ';' + } else if (CURRENT_TOKEN_IS(token::PUNCTUATION_OPEN_BRACE)) { + ParseResult body = state_parser.parse(); + RETURN_IF_ERROR(body); + + node->body = body.value(); + } else { + return std::unexpected(PARSE_ERROR(CURRENT_TOK, "expected function body")); + } + + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, FuncDecl) { json.section("FuncDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, FuncDecl) { + std::vector params; + + for (const auto ¶m : node.params) { + params.push_back(get_node_json(param)); + } + + json.section("FuncDecl") + .add("name", get_node_json(node.name)) + .add("params", params) + .add("generics", get_node_json(node.generics)) + .add("returns", get_node_json(node.returns)) + .add("body", get_node_json(node.body)) + .add("modifiers", node.modifiers.to_json()) + .add("qualifiers", node.qualifiers.to_json()); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, VarDecl) { +AST_NODE_IMPL(Declaration, VarDecl, bool force_type, bool force_value) { IS_NOT_EMPTY; // VarDecl := S.NamedVarSpecifier ('=' E)? ~ also pass in a bool to force type need - NOT_IMPLEMENTED; + ParseResult var = state_parser.parse(force_type); + RETURN_IF_ERROR(var); + + if (CURRENT_TOKEN_IS(token::OPERATOR_ASSIGN)) { + iter.advance(); // skip '=' + + ParseResult<> value = expr_parser.parse(); + RETURN_IF_ERROR(value); + + NodeT node = make_node(var.value(), value.value()); + return node; + } + + if (force_value) { + return std::unexpected(PARSE_ERROR(CURRENT_TOK, "expected value for variable")); + } + + NodeT node = make_node(var.value()); + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, VarDecl) { json.section("VarDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, VarDecl) { + json.section("VarDecl") + .add("var", get_node_json(node.var)) + .add("value", get_node_json(node.value)); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, FFIDecl) { +AST_NODE_IMPL(Declaration, FFIDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // FFIDecl := VisDecl? 'ffi' L.StringLiteral D + // FFIDecl := Modifiers 'ffi' L.StringLiteral D NOT_IMPLEMENTED; } @@ -476,20 +817,75 @@ AST_NODE_IMPL_VISITOR(Jsonify, FFIDecl) { json.section("FFIDecl"); } // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, LetDecl) { +AST_NODE_IMPL(Declaration, LetDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // LetDecl := VisDecl? 'let' SharedModifiers VarDecl* ';' + // LetDecl := Modifiers 'let' Modifiers VarDecl* ';' - NOT_IMPLEMENTED; + NodeT node = make_node(true); + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + if (!node->vis.find_add(tok.current().get())) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid modifier for let")); + } + } + } else { + while (node->vis.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_LET); + iter.advance(); // skip 'let' + + while (node->modifiers.find_add(CURRENT_TOK)) { + iter.advance(); // skip modifier + } + + while + CURRENT_TOKEN_IS(token::IDENTIFIER) { + ParseResult var = parse(); + RETURN_IF_ERROR(var); + + // if no value is provided type is required + if ((var.value()->value == nullptr) && (var.value()->var->type == nullptr)) { + return std::unexpected( + PARSE_ERROR(var.value()->var->path->name, "expected a type or value for let")); + } + + node->vars.emplace_back(var.value()); + + if (CURRENT_TOKEN_IS(token::PUNCTUATION_COMMA)) { + iter.advance(); // skip ',' + } + } + + IS_EXCEPTED_TOKEN(token::PUNCTUATION_SEMICOLON); + iter.advance(); // skip ';' + + return node; } -AST_NODE_IMPL_VISITOR(Jsonify, LetDecl) { json.section("LetDecl"); } +AST_NODE_IMPL_VISITOR(Jsonify, LetDecl) { + std::vector vars; + + for (const auto &var : node.vars) { + vars.push_back(get_node_json(var)); + } + + json.section("LetDecl") + .add("vars", vars) + .add("vis", node.vis.to_json()) + .add("modifiers", node.modifiers.to_json()); +} // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Declaration, OpDecl) { +/* TODO: MERGE WITH FUNCTION DECL */ +AST_NODE_IMPL(Declaration, OpDecl, const std::shared_ptr &modifiers) { IS_NOT_EMPTY; - // OpDecl := SharedModifiers? 'op' T FuncDecl[no_SharedModifiers=true] + // OpDecl := Modifiers 'op' T FuncDecl[no_SharedModifiers=true] NOT_IMPLEMENTED; } @@ -498,15 +894,95 @@ AST_NODE_IMPL_VISITOR(Jsonify, OpDecl) { json.section("OpDecl"); } // ---------------------------------------------------------------------------------------------- // +AST_NODE_IMPL(Declaration, ModuleDecl, const std::shared_ptr &modifiers) { + IS_NOT_EMPTY; + // ModuleDecl := 'inline'? 'module' E.PathExpr[scopeOnly=true] S.Suite + + if (modifiers != nullptr) { + for (auto &tok : *modifiers) { + return std::unexpected( + PARSE_ERROR(tok.current().get(), "invalid specifier for module")); + } + } + + bool inline_module = false; + + if (CURRENT_TOKEN_IS(token::KEYWORD_INLINE)) { + inline_module = true; + iter.advance(); // skip 'inline' + } + + IS_EXCEPTED_TOKEN(token::KEYWORD_MODULE); + iter.advance(); // skip 'module' + + ParseResult name = expr_parser.parse(); + RETURN_IF_ERROR(name); + + ParseResult body = state_parser.parse(); + RETURN_IF_ERROR(body); + + NodeT node = make_node(name.value(), body.value(), inline_module); + return node; +} + +AST_NODE_IMPL_VISITOR(Jsonify, ModuleDecl) { + json.section("ModuleDecl") + .add("name", get_node_json(node.name)) + .add("body", get_node_json(node.body)) + .add("inline_module", node.inline_module ? "true" : "false"); +} + +// ---------------------------------------------------------------------------------------------- // + AST_BASE_IMPL(Declaration, parse) { IS_NOT_EMPTY; - token::Token tok = CURRENT_TOK; /// get the current token from the iterator + token::Token tok = CURRENT_TOK; /// get the current token from the iterator + std::shared_ptr modifiers = nullptr; /// create a pointer to the modifiers + + /* TODO: make this not happen if bool is passed */ + while (Modifiers::is_modifier(tok)) { + if (modifiers == nullptr || modifiers->empty()) { + modifiers = std::make_shared(); + } + + modifiers->push_back(tok); /// add the modifier to the list + iter.advance(); /// advance the iterator + + tok = CURRENT_TOK; /// get the next token + } switch (tok.token_kind()) { + case token::KEYWORD_CONST: + return parse(); + case token::KEYWORD_CLASS: + return parse(modifiers); + case token::KEYWORD_ENUM: + if (modifiers != nullptr) { + return std::unexpected(PARSE_ERROR(tok, "invalid modifier for enum")); + } + + return parse(modifiers); + case token::KEYWORD_INTERFACE: + return parse(modifiers); + case token::KEYWORD_LET: + return parse(modifiers); + case token::KEYWORD_FFI: + return parse(modifiers); + case token::KEYWORD_FUNCTION: + return parse(modifiers); + case token::KEYWORD_OPERATOR: + return parse(modifiers); + case token::KEYWORD_TYPE: + return parse(modifiers); + // case token::KEYWORD_UNION: + // return parse(modifiers); + // TODO: evaluate if unions should be statements or declarations case token::KEYWORD_STRUCT: - return parse(); + return parse(modifiers); + case token::KEYWORD_MODULE: + return parse(modifiers); default: return state_parser.parse(); } -} \ No newline at end of file +} diff --git a/source/parser/ast/source/nodes/Exprs.cc b/source/parser/ast/source/nodes/Exprs.cc index 53e311e..c3a6947 100644 --- a/source/parser/ast/source/nodes/Exprs.cc +++ b/source/parser/ast/source/nodes/Exprs.cc @@ -84,8 +84,7 @@ /// [ ] * LambdaExpr * LE -> 'fn' TODO /// /// /// /// /* generics */ /// -/// [ ] * GenericInvokeExpr * GI -> '<' GAE? ( ',' GAE )* '>' /// -/// [ ] * GenericArgumentExpr * GAE -> E | ID '=' E /// +/// [ ] * GenericInvokeExpr * GI -> '<' TY? ( ',' TY )* '>' /// /// [ ] * GenericInvokePathExpr * PGE -> PE GI /// /// /// /// /// @@ -120,6 +119,7 @@ #include "parser/ast/include/config/AST_config.def" #include "parser/ast/include/config/AST_generate.hh" +#include "parser/ast/include/config/AST_modifiers.hh" #include "parser/ast/include/config/case_types.def" #include "parser/ast/include/core/AST_nodes.hh" #include "parser/ast/include/nodes/AST_Expressions.hh" @@ -484,7 +484,7 @@ AST_NODE_IMPL(Expression, IdentExpr) { return make_node(tok, is_reserved_primitive); } -AST_NODE_IMPL_VISITOR(Jsonify, IdentExpr) { json.section("IdentExpr").add("name", node.name); } +AST_NODE_IMPL_VISITOR(Jsonify, IdentExpr) { json.section("IdentExpr", node.name); } // ---------------------------------------------------------------------------------------------- // @@ -604,14 +604,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, ArgumentListExpr) { args.push_back(get_node_json(arg)); } - json.section("ArgumentListExpr").add("args", args); -} - -// ---------------------------------------------------------------------------------------------- // - -AST_NODE_IMPL(Expression, GenericArgumentExpr) { - IS_NOT_EMPTY; - NOT_IMPLEMENTED; + json.section("ArgumentListExpr", args); } // ---------------------------------------------------------------------------------------------- // @@ -628,7 +621,7 @@ AST_NODE_IMPL(Expression, GenericInvokeExpr) { return make_node(nullptr); } - ParseResult first = parse(); + ParseResult first = parse(); RETURN_IF_ERROR(first); NodeT generics = make_node(first.value()); @@ -637,7 +630,7 @@ AST_NODE_IMPL(Expression, GenericInvokeExpr) { CURRENT_TOKEN_IS(token::PUNCTUATION_COMMA) { iter.advance(); // skip ',' - ParseResult arg = parse(); + ParseResult arg = parse(); RETURN_IF_ERROR(arg); generics->args.push_back(arg.value()); @@ -649,6 +642,16 @@ AST_NODE_IMPL(Expression, GenericInvokeExpr) { return generics; } +AST_NODE_IMPL_VISITOR(Jsonify, GenericInvokeExpr) { + std::vector args; + + for (const auto &arg : node.args) { + args.push_back(get_node_json(arg)); + } + + json.section("GenericInvokeExpr", args); +} + // ---------------------------------------------------------------------------------------------- // AST_NODE_IMPL(Expression, GenericInvokePathExpr) { @@ -748,7 +751,7 @@ AST_NODE_IMPL(Expression, PathExpr, ParseResult<> simple_path) { // := IdentExpr | ScopePathExpr | DotPathExpr IS_NULL_RESULT(simple_path) { - simple_path = parse(); + simple_path = parse_primary(); RETURN_IF_ERROR(simple_path); } @@ -780,10 +783,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, PathExpr) { // ---------------------------------------------------------------------------------------------- // -AST_NODE_IMPL(Expression, - FunctionCallExpr, - ParseResult<> lhs, - ParseResult<> gens /* FIXME: unused */) { +AST_NODE_IMPL(Expression, FunctionCallExpr, ParseResult<> lhs) { IS_NOT_EMPTY; /* @@ -794,7 +794,6 @@ AST_NODE_IMPL(Expression, } */ - // if lhs is not empty, then we have a path expression ParseResult path; IS_NULL_RESULT(lhs) { @@ -816,7 +815,8 @@ AST_NODE_IMPL(Expression, AST_NODE_IMPL_VISITOR(Jsonify, FunctionCallExpr) { json.section("FunctionCallExpr") .add("path", get_node_json(node.path)) - .add("args", get_node_json(node.args)); + .add("args", get_node_json(node.args)) + .add("generics", get_node_json(node.generic)); } // ---------------------------------------------------------------------------------------------- // @@ -868,7 +868,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, ArrayLiteralExpr) { values.push_back(get_node_json(value)); } - json.section("ArrayLiteralExpr").add("values", values); + json.section("ArrayLiteralExpr", values); } // ---------------------------------------------------------------------------------------------- // @@ -929,7 +929,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, TupleLiteralExpr) { values.push_back(get_node_json(value)); } - json.section("TupleLiteralExpr").add("values", values); + json.section("TupleLiteralExpr", values); } // ---------------------------------------------------------------------------------------------- // @@ -987,7 +987,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, SetLiteralExpr) { values.push_back(get_node_json(value)); } - json.section("SetLiteralExpr").add("values", values); + json.section("SetLiteralExpr", values); } // ---------------------------------------------------------------------------------------------- // @@ -1075,7 +1075,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, MapLiteralExpr) { values.push_back(get_node_json(value)); } - json.section("MapLiteralExpr").add("values", values); + json.section("MapLiteralExpr", values); } // ---------------------------------------------------------------------------------------------- // @@ -1241,7 +1241,7 @@ AST_NODE_IMPL(Expression, ParenthesizedExpr, ParseResult<> expr) { } AST_NODE_IMPL_VISITOR(Jsonify, ParenthesizedExpr) { - json.section("ParenthesizedExpr").add("value", get_node_json(node.value)); + json.section("ParenthesizedExpr", get_node_json(node.value)); } // ---------------------------------------------------------------------------------------------- // @@ -1308,7 +1308,8 @@ AST_NODE_IMPL_VISITOR(Jsonify, InstOfExpr) { // ---------------------------------------------------------------------------------------------- // /* DEPRECATED: a Type is deduced from context and at this stage is considered a Expression */ -AST_NODE_IMPL(Expression, Type) { // TODO +AST_NODE_IMPL(Expression, Type) { // TODO - REMAKE using the new Modifiers and stricter rules, such + // as no types can contain a binary expression // if E(2) does not exist, check if its a & | * token, since if it is, // then return a unary expression since its a pointer or reference type @@ -1320,13 +1321,8 @@ AST_NODE_IMPL(Expression, Type) { // TODO // FunctionQualifier IS_NOT_EMPTY; - std::vector type_prefixes; - - // TODO: all fucntion specifiers can be applied to lambda types - - auto is_type_prefix = [&](const token::Token &tok) { - return is_type_qualifier(tok) || is_ffi_specifier(tok); - }; + Modifiers fn_specifiers(Modifiers::ExpectedModifier::FuncSpec); + NodeT node = make_node(true); if (CURRENT_TOKEN_IS(token::KEYWORD_FUNCTION)) { iter.advance(); // skip 'fn' @@ -1374,24 +1370,91 @@ AST_NODE_IMPL(Expression, Type) { // TODO return make_node(lambda); } - if (is_type_prefix(CURRENT_TOK)) { - type_prefixes.push_back(CURRENT_TOK); - iter.advance(); + while (node->specifiers.find_add(CURRENT_TOK)) { + iter.advance(); // TODO: Handle 'ffi' ('class' | 'interface' | 'struct' | 'enum' | 'union' + // | 'type') + } + + ParseResult<> EXPR = parse_primary(); + RETURN_IF_ERROR(EXPR); + + bool continue_loop = true; + + while (continue_loop) { + const token::Token &tok = CURRENT_TOK; + + switch (tok.token_kind()) { + // case token::PUNCTUATION_OPEN_ANGLE: /// what to do if its ident '<' parms + // /// '>' '(' args ')' its now either a + // /// function call w a generic or its a + // /// binary expression may god help me + // NOT_IMPLEMENTED; + // SOLUTION: 2 pass compiler + case token::PUNCTUATION_OPEN_PAREN: + EXPR = parse(EXPR); + RETURN_IF_ERROR(EXPR); + break; - while (is_type_prefix(CURRENT_TOK)) { - type_prefixes.push_back(CURRENT_TOK); - iter.advance(); + case token::PUNCTUATION_OPEN_BRACKET: + EXPR = parse(EXPR); + RETURN_IF_ERROR(EXPR); + break; + + case token::OPERATOR_SCOPE: + EXPR = parse(EXPR); + RETURN_IF_ERROR(EXPR); + break; + + case token::KEYWORD_HAS: + case token::KEYWORD_DERIVES: + return std::unexpected( + PARSE_ERROR(tok, "expected a type, but found a 'has' or 'derives' keyword")); + + case token::PUNCTUATION_QUESTION_MARK: + case token::KEYWORD_IF: + EXPR = parse(EXPR); + RETURN_IF_ERROR(EXPR); + break; + + case token::KEYWORD_AS: + return std::unexpected( + PARSE_ERROR(tok, "expected a type, but found a 'as' keyword")); + case token::PUNCTUATION_OPEN_ANGLE: // generic lol + { + ParseResult generic = parse(); + RETURN_IF_ERROR(generic); + + node->generics = generic.value(); + continue_loop = false; + break; + } + + default: + if (is_excepted(tok, IS_UNARY_OPERATOR)) { + EXPR = parse(EXPR); + RETURN_IF_ERROR(EXPR); + } else if (tok == token::PUNCTUATION_OPEN_PAREN) { + iter.advance(); // skip '(' + EXPR = parse(EXPR); /// im not sure why this works, but + /// based on small tests, it seems + /// to work fine i'll find out soon + /// enough if it doesn't + RETURN_IF_ERROR(EXPR); + } else { + continue_loop = false; + } } } - ParseResult<> type = parse(); - RETURN_IF_ERROR(type); - - return make_node(type.value()); + node->value = EXPR.value(); + return node; } AST_NODE_IMPL_VISITOR(Jsonify, Type) { - json.section("Type").add("value", get_node_json(node.value)).add("type", (int)node.type); + json.section("Type") + .add("value", get_node_json(node.value)) + .add("generics", get_node_json(node.generics)) + .add("specifiers", node.specifiers.to_json()); } // ---------------------------------------------------------------------------------------------- // diff --git a/source/parser/ast/source/nodes/States.cc b/source/parser/ast/source/nodes/States.cc index 3c4cf86..34b0751 100644 --- a/source/parser/ast/source/nodes/States.cc +++ b/source/parser/ast/source/nodes/States.cc @@ -227,7 +227,7 @@ AST_BASE_IMPL(Statement, parse) { // NOLINT(readability-function-cognitive-comp /// if(iter.remaining_n() == 0) { return std::unexpected(...); } token::Token tok = CURRENT_TOK; /// get the current token from the iterator - modifiers = get_modifiers(iter); /// get the modifiers for the statement + // modifiers = get_modifiers(iter); /// get the modifiers for the statement switch (tok.token_kind()) { // TODO: case token::KEYWORD_IMPORT @@ -300,6 +300,10 @@ AST_NODE_IMPL(Statement, NamedVarSpecifier, bool force_type) { RETURN_IF_ERROR(path); if (force_type) { + if (path.value()->name.value() == "self") { + return make_node(path.value()); + } + IS_EXCEPTED_TOKEN(token::PUNCTUATION_COLON); } @@ -361,7 +365,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, NamedVarSpecifierList) { vars.push_back(get_node_json(var)); } - json.section("NamedVarSpecifierList").add("vars", vars); + json.section("NamedVarSpecifierList", vars); } // ---------------------------------------------------------------------------------------------- // @@ -872,7 +876,7 @@ AST_NODE_IMPL(Statement, YieldState) { } AST_NODE_IMPL_VISITOR(Jsonify, YieldState) { - json.section("YieldState").add("expr", get_node_json(node.value)); + json.section("YieldState", get_node_json(node.value)); } // ---------------------------------------------------------------------------------------------- // @@ -893,7 +897,7 @@ AST_NODE_IMPL(Statement, DeleteState) { } AST_NODE_IMPL_VISITOR(Jsonify, DeleteState) { - json.section("DeleteState").add("expr", get_node_json(node.value)); + json.section("DeleteState", get_node_json(node.value)); } // ---------------------------------------------------------------------------------------------- // @@ -950,7 +954,7 @@ AST_NODE_IMPL(Statement, ReturnState) { } AST_NODE_IMPL_VISITOR(Jsonify, ReturnState) { - json.section("ReturnState").add("value", get_node_json(node.value)); + json.section("ReturnState", get_node_json(node.value)); } // ---------------------------------------------------------------------------------------------- // @@ -970,7 +974,7 @@ AST_NODE_IMPL(Statement, BreakState) { } AST_NODE_IMPL_VISITOR(Jsonify, BreakState) { - json.section("BreakState").add("marker", node.marker); + json.section("BreakState", node.marker); } // ---------------------------------------------------------------------------------------------- // @@ -990,7 +994,7 @@ AST_NODE_IMPL(Statement, ContinueState) { } AST_NODE_IMPL_VISITOR(Jsonify, ContinueState) { - json.section("ContinueState").add("marker", node.marker); + json.section("ContinueState", node.marker); } // ---------------------------------------------------------------------------------------------- // @@ -1008,7 +1012,7 @@ AST_NODE_IMPL(Statement, ExprState) { } AST_NODE_IMPL_VISITOR(Jsonify, ExprState) { - json.section("ExprState").add("expr", get_node_json(node.value)); + json.section("ExprState", get_node_json(node.value)); } // ---------------------------------------------------------------------------------------------- // @@ -1028,10 +1032,13 @@ AST_NODE_IMPL(Statement, SuiteState) { if CURRENT_TOKEN_IS (token::PUNCTUATION_COLON) { iter.advance(); // skip ':' - ParseResult<> stmt = parse(); - RETURN_IF_ERROR(stmt); + Declaration decl_parser(iter); + + ParseResult<> decl = decl_parser.parse(); + RETURN_IF_ERROR(decl); + - NodeT block = make_node(NodeV<>{stmt.value()}); + NodeT block = make_node(NodeV<>{decl.value()}); return make_node(block); } @@ -1042,7 +1049,7 @@ AST_NODE_IMPL(Statement, SuiteState) { } AST_NODE_IMPL_VISITOR(Jsonify, SuiteState) { - json.section("SuiteState").add("body", get_node_json(node.body)); + json.section("SuiteState", get_node_json(node.body)); } // ---------------------------------------------------------------------------------------------- // @@ -1053,6 +1060,7 @@ AST_NODE_IMPL(Statement, BlockState) { NodeV<> body; token::Token starting_tok; + Declaration decl_parser(iter); IS_EXCEPTED_TOKEN(token::PUNCTUATION_OPEN_BRACE); starting_tok = CURRENT_TOK; @@ -1061,10 +1069,10 @@ AST_NODE_IMPL(Statement, BlockState) { while (CURRENT_TOKEN_IS_NOT( token::PUNCTUATION_CLOSE_BRACE)) { // TODO: implement this kind of bounds checks for all // the pair token parsers '(', '[', '{'. - ParseResult<> stmt = parse(); - RETURN_IF_ERROR(stmt); + ParseResult<> decl = decl_parser.parse(); + RETURN_IF_ERROR(decl); - body.push_back(stmt.value()); + body.push_back(decl.value()); } if (iter.remaining_n() == 0) { @@ -1083,7 +1091,7 @@ AST_NODE_IMPL_VISITOR(Jsonify, BlockState) { body_json.push_back(get_node_json(node)); } - json.section("BlockState").add("body", body_json); + json.section("BlockState", body_json); } // ---------------------------------------------------------------------------------------------- // @@ -1217,7 +1225,7 @@ AST_NODE_IMPL(Statement, PanicState) { } AST_NODE_IMPL_VISITOR(Jsonify, PanicState) { - json.section("PanicState").add("expr", get_node_json(node.expr)); + json.section("PanicState",get_node_json(node.expr)); } // ---------------------------------------------------------------------------------------------- // @@ -1237,7 +1245,7 @@ AST_NODE_IMPL(Statement, FinallyState) { } AST_NODE_IMPL_VISITOR(Jsonify, FinallyState) { - json.section("FinallyState").add("body", get_node_json(node.body)); + json.section("FinallyState", get_node_json(node.body)); } // ---------------------------------------------------------------------------------------------- //