diff --git a/furc/include/furc/ast/declaration.hpp b/furc/include/furc/ast/declaration.hpp index 12d45f2..895b00c 100644 --- a/furc/include/furc/ast/declaration.hpp +++ b/furc/include/furc/ast/declaration.hpp @@ -4,6 +4,7 @@ #include "furc/ast/node.hpp" #include "furc/ast/statement.hpp" +#include #include #include @@ -79,10 +80,11 @@ public: * * @param location Node location. * @param name Name of the function. + * @param type Return type of the function. */ template - function_declaration_node(struct location location, T&& name) - : declaration_node(location), p_name(std::forward(name)) {} + function_declaration_node(struct location location, T&& name, std::optional&& returnType) + : declaration_node(location), p_name(std::forward(name)), p_returnType(std::move(returnType)) {} public: /** * @brief Returns this node's declaration type. @@ -97,6 +99,13 @@ public: * @return Name of the function. */ std::string name() const { return p_name; } + + /** + * @brief Returns function's return type. + * + * @return Function's return type. + */ + const std::optional& return_type() const { return p_returnType; } public: void accept(visitor& visitor) const override; @@ -108,6 +117,11 @@ protected: * @brief Name of the function. */ std::string p_name; + + /** + * @brief Return type of the function. + */ + std::optional p_returnType; }; /** @@ -120,11 +134,12 @@ public: * * @param location Node location. * @param name Name of the function. + * @param type Return type of the function. * @param body Body of the function. */ template - function_definition_node(struct location location, T&& name, body&& body) - : function_declaration_node(location, std::forward(name)), m_body(std::move(body)) {} + function_definition_node(struct location location, T&& name, std::optional&& type, body&& body) + : function_declaration_node(location, std::forward(name), std::move(type)), m_body(std::move(body)) {} public: /** * @brief Returns this node's declaration type. diff --git a/furc/src/front/parser.cpp b/furc/src/front/parser.cpp index a2c18b2..0411c8d 100644 --- a/furc/src/front/parser.cpp +++ b/furc/src/front/parser.cpp @@ -69,6 +69,14 @@ ast::declaration_node_r parser::parse_declaration() { tok = eat_token(token_t::RParen); if (tok.has_error()) return ast::declaration_node_r(ast::error{ tok.error().location }); + std::optional returnType; + if (peek_token().has_value() && peek_token()->type == token_t::SlimArrow) { + auto tok = next_token(); + auto type = parse_type(); + if (type.has_error()) return ast::declaration_node_r(ast::error{ tok->location }); + returnType = *type; + } + const auto& peek = peek_token(); if (peek.has_error()) return ast::declaration_node_r(ast::error{ peek.error().location }); switch (peek->type) { @@ -77,11 +85,14 @@ ast::declaration_node_r parser::parse_declaration() { if (body.has_error()) return ast::declaration_node_r(ast::error{ body.error().location }); return m_arena->allocate_shared(first->location, name->value.string, + std::move(returnType), std::move(body.value())); } case token_t::Semicolon: { m_peekBuffer.clear(); - return m_arena->allocate_shared(first->location, name->value.string); + return m_arena->allocate_shared(first->location, + name->value.string, + std::move(returnType)); } default: return ast::declaration_node_r(ast::error{ tok->location }); } diff --git a/furc/src/main.cpp b/furc/src/main.cpp index 9aef4da..42c678d 100644 --- a/furc/src/main.cpp +++ b/furc/src/main.cpp @@ -13,7 +13,7 @@ int main(void) { try { std::string programStr = R"( - func main() { + func main() -> int32 { x = 0; y = 10; z = 1;