77
88namespace frontend {
99 static std::unordered_set<std::string> loadedFiles;
10- static context::Options optionsValue;
1110
12- Parser::Parser (const std::vector<token::Token> &tokens, const context::Options options_) {
13- optionsValue = options_;
14- size_t index = 0 ;
15- program = Program{build (tokens, index)};
11+ Parser::Parser (const std::vector<token::Token> &tokens,
12+ const context::Options options) : options(options), tokens(tokens), index(0 ) {
13+ }
14+
15+ Program Parser::parse () {
16+ return Program{build ()};
1617 }
1718
1819 template <typename T>
19- void Parser::assertToken (const std::vector<token::Token> &tokens, size_t &index ) {
20+ void Parser::assertToken () {
2021 if (const token::Token ¤tToken = tokens[index]; !std::holds_alternative<T>(currentToken.tokenType )) {
21- optionsValue .logger .error (currentToken.location , " syntax error: expected " , token::toString<T>(), " , got " ,
22- currentToken.toString ());
22+ options .logger .error (currentToken.location , " syntax error: expected " , token::toString<T>(), " , got " ,
23+ currentToken.toString ());
2324 }
2425 }
2526
2627 template <typename T>
27- void Parser::assertAndConsume (const std::vector<token::Token> &tokens, size_t &index ) {
28- assertToken<T>(tokens, index );
28+ void Parser::assertAndConsume () {
29+ assertToken<T>();
2930 ++index;
3031 }
3132
32- IdentifierAstNode Parser::consumeIdentifier (const std::vector<token::Token> &tokens, size_t &index ) {
33- assertToken<token::Identifier>(tokens, index );
33+ IdentifierAstNode Parser::consumeIdentifier () {
34+ assertToken<token::Identifier>();
3435 auto [value] = std::get<token::Identifier>(tokens[index].tokenType );
3536 const Location location = tokens[index].location ;
3637 ++index;
3738 return IdentifierAstNode{value, location};
3839 }
3940
4041 interpreter::type::PrimitiveType
41- Parser::consumePrimitiveTypeName (const std::vector<token::Token> &tokens, size_t &index ) {
42- assertToken<token::Identifier>(tokens, index );
42+ Parser::consumePrimitiveTypeName () {
43+ assertToken<token::Identifier>();
4344 auto [value] = std::get<token::Identifier>(tokens[index].tokenType );
4445 Location location = tokens[index].location ;
4546 ++index;
47+ // TODO: Perform this check through interpreter::type package.
4648 if (value == " Float" ) {
4749 return interpreter::type::PrimitiveType{interpreter::type::PrimitiveType::Type::Float};
4850 }
@@ -55,12 +57,12 @@ namespace frontend {
5557 return interpreter::type::PrimitiveType{interpreter::type::PrimitiveType::Type::Custom, std::move (value)};
5658 }
5759
58- interpreter::type::Type Parser::parseType (const std::vector<token::Token> &tokens, size_t &index ) {
59- interpreter::type::PrimitiveType typ = consumePrimitiveTypeName (tokens, index );
60+ interpreter::type::Type Parser::parseType () {
61+ interpreter::type::PrimitiveType typ = consumePrimitiveTypeName ();
6062 std::vector types{typ};
6163 while (std::holds_alternative<token::Arrow>(tokens[index].tokenType )) {
62- assertAndConsume<token::Arrow>(tokens, index );
63- types.push_back (consumePrimitiveTypeName (tokens, index ));
64+ assertAndConsume<token::Arrow>();
65+ types.push_back (consumePrimitiveTypeName ());
6466 }
6567 if (types.size () == 1 ) {
6668 return typ;
@@ -76,96 +78,97 @@ namespace frontend {
7678 return currentType;
7779 }
7880
79- Expression Parser::parseExpression (const std::vector<token::Token> &tokens, size_t &index ) {
80- const auto &tok = tokens[index];
81- const Location location = tok .location ;
81+ Expression Parser::parseExpression () {
82+ const auto &token = tokens[index];
83+ const Location location = token .location ;
8284 return std::visit ([&]<typename T0 >(T0 &&) {
8385 using T = std::decay_t <T0 >;
8486 if (std::is_same_v<T, token::Identifier>) {
8587 ++index;
86- const auto value = std::get<token::Identifier>(tok .tokenType ).value ;
88+ const auto value = std::get<token::Identifier>(token .tokenType ).value ;
8789 return Expression (IdentifierAstNode{value, location});
8890 }
8991 if (std::is_same_v<T, token::String>) {
9092 ++index;
91- const auto value = unescapeString (std::get<token::String>(tok .tokenType ).value );
93+ const auto value = unescapeString (std::get<token::String>(token .tokenType ).value );
9294 return Expression (StringAstNode{value, location});
9395 }
9496 if (std::is_same_v<T, token::Float>) {
9597 ++index;
96- const auto value = std::get<token::Float>(tok .tokenType ).value ;
98+ const auto value = std::get<token::Float>(token .tokenType ).value ;
9799 return Expression (FloatAstNode{value, location});
98100 }
99101 if (std::is_same_v<T, token::BackwardSlash>) {
100- return Expression (parseLambdaExpression (tokens, index ));
102+ return Expression (parseLambdaExpression ());
101103 }
102104 if (std::is_same_v<T, token::OpenParenthesis>) {
103- return Expression (parseFunctionApplication (tokens, index ));
105+ return Expression (parseFunctionApplication ());
104106 }
105- optionsValue .logger .error (location, " syntax error: unexpected token " , tok .toString ());
106- }, tok .tokenType );
107+ options .logger .error (location, " syntax error: unexpected token " , token .toString ());
108+ }, token .tokenType );
107109 }
108110
109- LambdaExpression Parser::parseLambdaExpression (const std::vector<token::Token> &tokens, size_t &index ) {
111+ LambdaExpression Parser::parseLambdaExpression () {
110112 Location location = tokens[index].location ;
111- assertAndConsume<token::BackwardSlash>(tokens, index );
112- IdentifierAstNode argument = consumeIdentifier (tokens, index );
113- assertAndConsume<token::Colon>(tokens, index );
114- interpreter::type::Type argumentType = parseType (tokens, index );
115- assertAndConsume<token::Dot>(tokens, index );
116- Expression expression = parseExpression (tokens, index );
113+ assertAndConsume<token::BackwardSlash>();
114+ IdentifierAstNode argument = consumeIdentifier ();
115+ assertAndConsume<token::Colon>();
116+ interpreter::type::Type argumentType = parseType ();
117+ assertAndConsume<token::Dot>();
118+ Expression expression = parseExpression ();
117119 return LambdaExpression{
118120 argument, argumentType, std::make_unique<Expression>(std::move (expression)), location
119121 };
120122 }
121123
122- FunctionApplication Parser::parseFunctionApplication (const std::vector<token::Token> &tokens, size_t &index ) {
124+ FunctionApplication Parser::parseFunctionApplication () {
123125 const Location location = tokens[index].location ;
124- assertAndConsume<token::OpenParenthesis>(tokens, index );
125- const IdentifierAstNode functionName = consumeIdentifier (tokens, index );
126+ assertAndConsume<token::OpenParenthesis>();
127+ const IdentifierAstNode functionName = consumeIdentifier ();
126128 std::vector<std::unique_ptr<Expression> > arguments;
127129 while (!std::holds_alternative<token::CloseParenthesis>(tokens[index].tokenType )) {
128- arguments.push_back (std::make_unique<Expression>(std::move (parseExpression (tokens, index ))));
130+ arguments.push_back (std::make_unique<Expression>(std::move (parseExpression ())));
129131 }
130- assertAndConsume<token::CloseParenthesis>(tokens, index );
132+ assertAndConsume<token::CloseParenthesis>();
131133 return FunctionApplication{functionName, std::move (arguments), location};
132134 }
133135
134- DefinitionAstNode Parser::parseDefinitionAstNode (const std::vector<token::Token> &tokens, size_t &index ) {
136+ DefinitionAstNode Parser::parseDefinitionAstNode () {
135137 Location location = tokens[index].location ;
136- IdentifierAstNode definitionName = consumeIdentifier (tokens, index );
137- assertAndConsume<token::Colon>(tokens, index );
138- interpreter::type::Type definitionType = parseType (tokens, index );
139- assertAndConsume<token::Equal>(tokens, index );
140- Expression expression = parseExpression (tokens, index );
138+ IdentifierAstNode definitionName = consumeIdentifier ();
139+ assertAndConsume<token::Colon>();
140+ interpreter::type::Type definitionType = parseType ();
141+ assertAndConsume<token::Equal>();
142+ Expression expression = parseExpression ();
141143 return DefinitionAstNode{definitionName, definitionType, std::move (expression), location};
142144 }
143145
144- static std::string getAbsolutePath (const std::string &path ) {
145- return std::filesystem::absolute (path ).string ();
146+ static std::string getAbsolutePath (const std::string &filepath ) {
147+ return std::filesystem::absolute (filepath ).string ();
146148 }
147149
148- static void processUseFile (std::vector<AstNode> &nodes, const std::string &filepath) {
150+ static void processUseFile (std::vector<AstNode> &astNodes, const std::string &filepath,
151+ const context::Options &options) {
149152 const std::string absolutePath = getAbsolutePath (filepath);
150153 if (loadedFiles.contains (absolutePath)) {
151154 // Circular Dependency or Duplicate Load
152155 return ;
153156 }
154157 loadedFiles.insert (absolutePath);
155- auto lexerValue = Lexer::fromFile (filepath, optionsValue );
158+ auto lexerValue = Lexer::fromFile (filepath, options );
156159 const auto tokens = lexerValue.lex ();
157- if (optionsValue .debug ) {
160+ if (options .debug ) {
158161 for (const auto &token: tokens) {
159- optionsValue .logger .debug (token);
162+ options .logger .debug (token);
160163 }
161164 }
162- for (Parser parser (tokens, optionsValue) ; auto &astNode: parser. program . astNodes ) {
163- nodes .emplace_back (std::move (astNode));
165+ for (auto [astastNodes] = Parser (tokens, options). parse () ; auto &astNode: astastNodes ) {
166+ astNodes .emplace_back (std::move (astNode));
164167 }
165168 }
166169
167- std::vector<AstNode> Parser::build (const std::vector<token::Token> &tokens, size_t &index ) {
168- std::vector<AstNode> nodes ;
170+ std::vector<AstNode> Parser::build () {
171+ std::vector<AstNode> astNodes ;
169172 while (!std::holds_alternative<token::Eof>(tokens[index].tokenType )) {
170173 const token::Token &token = tokens[index];
171174 std::visit ([&]<typename T0 >(T0 &&) {
@@ -174,24 +177,24 @@ namespace frontend {
174177 if (const auto identifierValue = std::get<token::Identifier>(tokens[index].tokenType ).value ;
175178 identifierValue == " use" ) {
176179 ++index; // consume "use"
177- assertToken<token::String>(tokens, index );
180+ assertToken<token::String>();
178181 const std::string filepath = unescapeString (
179182 std::get<token::String>(tokens[index].tokenType ).value );
180183 ++index; // consume <filepath>
181- processUseFile (nodes , filepath);
184+ processUseFile (astNodes , filepath, options );
182185 } else {
183- nodes .push_back (AstNode{std::move (parseDefinitionAstNode (tokens, index ))});
186+ astNodes .push_back (AstNode{std::move (parseDefinitionAstNode ())});
184187 }
185188 } else if constexpr (std::is_same_v<T, token::String> ||
186189 std::is_same_v<T, token::Float> ||
187190 std::is_same_v<T, token::BackwardSlash> ||
188191 std::is_same_v<T, token::OpenParenthesis>) {
189- nodes .push_back (AstNode{std::move (parseExpression (tokens, index ))});
192+ astNodes .push_back (AstNode{std::move (parseExpression ())});
190193 } else {
191- optionsValue .logger .error (token.location , " syntax error: unexpected token " , token.toString ());
194+ options .logger .error (token.location , " syntax error: unexpected token " , token.toString ());
192195 }
193196 }, token.tokenType );
194197 }
195- return nodes ;
198+ return astNodes ;
196199 }
197200}
0 commit comments