diff --git a/docs/syntax_concept_01.md b/docs/syntax_concept_01.md index 03983b7..be5a583 100644 --- a/docs/syntax_concept_01.md +++ b/docs/syntax_concept_01.md @@ -16,7 +16,7 @@ fn main() -> i64 { } ``` -## Key Aspects: +## Key Aspects 1. **Function `main`**: The main function returns a value of type `i64`, indicating a clear return type definition. 2. **Variable `index`**: Initialized with the value `0`. The type `i64` suggests an integer variable with a large range. @@ -25,9 +25,10 @@ fn main() -> i64 { 5. **Loop**: A simple `while` loop that runs until `index` reaches the value `11`, updating the array `ar` with calculated values. 6. **Return Value**: The function ends with a return value of `0`, which typically indicates successful execution. -## Notes: +## Notes This code is intended as a first draft. Some improvements are possible: + - The constant `b` is not used and could either be removed or utilized. - The array `ar` is introduced to demonstrate storage of values calculated within the loop. - The syntax for string types (`string`) might need to be adjusted depending on the target language, as not all languages support this notation. @@ -37,7 +38,7 @@ This code is intended as a first draft. Some improvements are possible: The following EBNF definition represents the structure of the code. The starting rule is `translation_unit`, and it is designed to be LL(1) compatible: ``` -translation_unit ::= function +translation_unit ::= (function)* function ::= "fn" identifier "(" ")" "->" type "{" statements "}" statements ::= (statement)* statement ::= variable_declaration | constant_declaration | loop | return_statement diff --git a/include/TranslationUnitNode.h b/include/TranslationUnitNode.h index 3b1e351..1d81ffb 100644 --- a/include/TranslationUnitNode.h +++ b/include/TranslationUnitNode.h @@ -3,18 +3,16 @@ #include #include "AstNode.h" -#include "FunctionNode.h" - -class FunctionNode; +#include class TranslationUnitNode : public AstNode, public std::enable_shared_from_this { public: ~TranslationUnitNode() = default; - TranslationUnitNode(const AstPtr& fnode); + TranslationUnitNode(const std::vector& nodes); void accept(const std::shared_ptr& v) override; private: - AstPtr _fnode; + std::vector _nodes; }; #endif // TRANSLATIONUNITNODE_H diff --git a/src/Parser.cpp b/src/Parser.cpp index cab7366..57cdb88 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -16,6 +16,7 @@ #include "TranslationUnitNode.h" #include "TypeNode.h" #include "VariableDeclarationNode.h" +#include "FunctionNode.h" auto missing(TokenKind kind) -> Error { return err("Missing " + detail::to_string(kind)); @@ -56,19 +57,30 @@ auto Parser::accept(TokenKind tk) -> bool { } return false; } - +// translation_unit := (function)* auto Parser::parse_translation_unit() -> ParserResult { _context.push({.context = "tranlsation unit", .rule = RuleType::TRANSLATION_UNIT}); ParserResult node = parse_function(); - if (node) { - return {std::make_shared(node.result())}; + if (!node.ok()) { + return node.error_value(); + } + std::vector nodes; + while (is_produced(node)) { + nodes.push_back(node.result()); + node = parse_function(); + if (!node.ok()) { + return node.error_value(); + } + if (!node.result()) { + break; + } } - return node.error_value(); + return {std::make_shared(nodes)}; } // function ::= "fn" identifier "(" ")" "->" type "{" statements "}" auto Parser::parse_function() -> ParserResult { if (!accept(TokenKind::FN)) { - return missing(TokenKind::FN); + return Epsilon; } if (!accept(TokenKind::IDENTIFIER)) { return missing(TokenKind::IDENTIFIER); diff --git a/src/TranslationUnitNode.cpp b/src/TranslationUnitNode.cpp index c0491b1..0fe36f1 100644 --- a/src/TranslationUnitNode.cpp +++ b/src/TranslationUnitNode.cpp @@ -1,15 +1,16 @@ #include "AstNode.h" -#include "FunctionNode.h" #include "Visitor.h" #include "TranslationUnitNode.h" -TranslationUnitNode::TranslationUnitNode(const AstPtr& fnode) : _fnode(fnode) { +TranslationUnitNode::TranslationUnitNode(const std::vector& nodes) : _nodes(nodes) { // Constructor implementation } void TranslationUnitNode::accept(const std::shared_ptr& v) { v->begin(shared_from_this()); auto v_next = v->visit(shared_from_this()); - _fnode->accept(v_next); + for (auto& node : _nodes) { + node->accept(v_next); + } v->end(shared_from_this()); }