Allow unnamed parameters in function prototype
This commit is contained in:
parent
9749b13253
commit
aa25c31bcf
@ -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";
|
||||
|
@ -26,6 +26,7 @@ enum class ErrorType {
|
||||
ExpectedRCurlyBracket,
|
||||
ExpectedSemicolon,
|
||||
DependentDeclaration,
|
||||
NameOmitted, // int main(int, int) { ... }
|
||||
|
||||
// Flow control
|
||||
BreakNotWithinLoop,
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user