Allow unnamed parameters in function prototype

This commit is contained in:
augustin64 2024-01-04 21:55:17 +01:00
parent 9749b13253
commit aa25c31bcf
5 changed files with 39 additions and 14 deletions

View File

@ -27,6 +27,7 @@ string UserError::get_message(void) const {
case ErrorType::ExpectedRCurlyBracket: return "Expected '}'";
case ErrorType::ExpectedSemicolon: return "Expected ';'";
case ErrorType::DependentDeclaration: return "A dependant statement may not be a declaration";
case ErrorType::NameOmitted: return "Omitting parameter name in a function definition";
// Flow control
case ErrorType::BreakNotWithinLoop: return "Break statement not within loop";

View File

@ -26,6 +26,7 @@ enum class ErrorType {
ExpectedRCurlyBracket,
ExpectedSemicolon,
DependentDeclaration,
NameOmitted, // int main(int, int) { ... }
// Flow control
BreakNotWithinLoop,

View File

@ -3,6 +3,7 @@
#include <vector>
#include <variant>
#include <optional>
#include <stdexcept>
#include "tokenize.h"
#include "errors.h"
@ -88,7 +89,7 @@ ParseReturn parse_par_identifier(vector<Token> tokens);
* Type1 Identifier1, Type2 Identifier2
* and returns it as a node with Declaration as children
*/
ParseReturn parse_args(vector<Token> tokens);
tuple<ParseReturn, optional<CodePosition>> parse_args(vector<Token> tokens);
/**
* Prints a tree for debugging it

View File

@ -18,7 +18,7 @@ void show_help(char* prog_name) {
}
void parse_args(int argc, char* argv[], bool &print_tokens, bool &print_ast, bool &dump_type_mem, bool &dump_mem, bool &help) {
void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &print_ast, bool &dump_type_mem, bool &dump_mem, bool &help) {
int i=1;
while (i < argc) {
char* cur = argv[i];
@ -70,7 +70,7 @@ int main(int argc, char* argv[]) {
bool dump_mem = false;
bool help = false;
parse_args(argc, argv, print_tokens, print_ast, dump_type_mem, dump_mem, help);
parse_main_arguments(argc, argv, print_tokens, print_ast, dump_type_mem, dump_mem, help);
if (help) {
show_help(argv[0]);

View File

@ -424,7 +424,9 @@ ParseReturn parse_statement(vector<Token> tokens) {
tokens.pop_back();
//* Args
ParseReturn args_ret = parse_args(tokens);
tuple<ParseReturn, optional<CodePosition>> args_ret_t = parse_args(tokens);
ParseReturn args_ret = get<0>(args_ret_t);
optional<CodePosition> unnamed = get<1>(args_ret_t); // Contient, s'il existe la position du type du premier argument n'ayant pas de nom
// RPar
if (args_ret.tokens.size() < 1 || args_ret.tokens.back().type != TokenType::RParenthese)
@ -451,6 +453,9 @@ ParseReturn parse_statement(vector<Token> tokens) {
};
}
if (bool(unnamed))
throw SyntaxError(ErrorType::NameOmitted, unnamed.value(), {});
//* LCurly
if (tokens.size() < 1 || tokens.back().type != TokenType::LCurlyBracket)
throw SyntaxError(ErrorType::ExpectedLCurlyBracket, identifier.pos, {});
@ -616,9 +621,10 @@ ParseReturn parse_args_values(vector<Token> tokens) {
};
}
ParseReturn parse_args(vector<Token> tokens) {
tuple<ParseReturn, optional<CodePosition>> parse_args(vector<Token> tokens) {
vector<Node> nodes;
CodePosition pos = tokens.back().pos;
optional<CodePosition> unnamed;
while (tokens.size() != 0 && tokens.back().type != TokenType::RParenthese) {
if (tokens.back().type != TokenType::Identifier)
@ -629,13 +635,28 @@ ParseReturn parse_args(vector<Token> tokens) {
// TODO: if type is void, return
Token identifier;
try {
ParseReturn ret = parse_par_identifier(tokens);
tokens = ret.tokens;
if (!holds_alternative<Token>(ret.node))
throw ParseException(); // The parsing is incorrect
Token identifier = get<Token>(ret.node);
identifier = get<Token>(ret.node);
} catch (const ParseException &pex) {
if (tokens.back().type == TokenType::Comma || tokens.back().type == TokenType::RParenthese) {
identifier = {
.type=TokenType::Identifier,
.data="",
.pos=null_pos
};
if (!unnamed)
unnamed = type.pos;
} else {
throw ParseException();
}
}
InnerNode node = {
.type=NodeType::Declaration,
@ -651,15 +672,16 @@ ParseReturn parse_args(vector<Token> tokens) {
}
}
InnerNode node = {
InnerNode inner_node = {
.type=NodeType::FunctionArgs,
.children=nodes,
.pos=pos
};
return {
.node=node,
ParseReturn retval = {
.node=inner_node,
.tokens=tokens
};
return {retval, unnamed};
}
ParseReturn parse_comp(vector<Token> tokens) {