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::ExpectedRCurlyBracket: return "Expected '}'";
|
||||||
case ErrorType::ExpectedSemicolon: return "Expected ';'";
|
case ErrorType::ExpectedSemicolon: return "Expected ';'";
|
||||||
case ErrorType::DependentDeclaration: return "A dependant statement may not be a declaration";
|
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
|
// Flow control
|
||||||
case ErrorType::BreakNotWithinLoop: return "Break statement not within loop";
|
case ErrorType::BreakNotWithinLoop: return "Break statement not within loop";
|
||||||
|
@ -26,6 +26,7 @@ enum class ErrorType {
|
|||||||
ExpectedRCurlyBracket,
|
ExpectedRCurlyBracket,
|
||||||
ExpectedSemicolon,
|
ExpectedSemicolon,
|
||||||
DependentDeclaration,
|
DependentDeclaration,
|
||||||
|
NameOmitted, // int main(int, int) { ... }
|
||||||
|
|
||||||
// Flow control
|
// Flow control
|
||||||
BreakNotWithinLoop,
|
BreakNotWithinLoop,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
@ -88,7 +89,7 @@ ParseReturn parse_par_identifier(vector<Token> tokens);
|
|||||||
* Type1 Identifier1, Type2 Identifier2
|
* Type1 Identifier1, Type2 Identifier2
|
||||||
* and returns it as a node with Declaration as children
|
* 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
|
* 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;
|
int i=1;
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
char* cur = argv[i];
|
char* cur = argv[i];
|
||||||
@ -70,7 +70,7 @@ int main(int argc, char* argv[]) {
|
|||||||
bool dump_mem = false;
|
bool dump_mem = false;
|
||||||
bool help = 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) {
|
if (help) {
|
||||||
show_help(argv[0]);
|
show_help(argv[0]);
|
||||||
|
@ -424,7 +424,9 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
|
|
||||||
//* Args
|
//* 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
|
// RPar
|
||||||
if (args_ret.tokens.size() < 1 || args_ret.tokens.back().type != TokenType::RParenthese)
|
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
|
//* LCurly
|
||||||
if (tokens.size() < 1 || tokens.back().type != TokenType::LCurlyBracket)
|
if (tokens.size() < 1 || tokens.back().type != TokenType::LCurlyBracket)
|
||||||
throw SyntaxError(ErrorType::ExpectedLCurlyBracket, identifier.pos, {});
|
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;
|
vector<Node> nodes;
|
||||||
CodePosition pos = tokens.back().pos;
|
CodePosition pos = tokens.back().pos;
|
||||||
|
optional<CodePosition> unnamed;
|
||||||
|
|
||||||
while (tokens.size() != 0 && tokens.back().type != TokenType::RParenthese) {
|
while (tokens.size() != 0 && tokens.back().type != TokenType::RParenthese) {
|
||||||
if (tokens.back().type != TokenType::Identifier)
|
if (tokens.back().type != TokenType::Identifier)
|
||||||
@ -629,13 +635,28 @@ ParseReturn parse_args(vector<Token> tokens) {
|
|||||||
|
|
||||||
// TODO: if type is void, return
|
// TODO: if type is void, return
|
||||||
|
|
||||||
|
Token identifier;
|
||||||
|
try {
|
||||||
ParseReturn ret = parse_par_identifier(tokens);
|
ParseReturn ret = parse_par_identifier(tokens);
|
||||||
tokens = ret.tokens;
|
tokens = ret.tokens;
|
||||||
|
|
||||||
if (!holds_alternative<Token>(ret.node))
|
if (!holds_alternative<Token>(ret.node))
|
||||||
throw ParseException(); // The parsing is incorrect
|
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 = {
|
InnerNode node = {
|
||||||
.type=NodeType::Declaration,
|
.type=NodeType::Declaration,
|
||||||
@ -651,15 +672,16 @@ ParseReturn parse_args(vector<Token> tokens) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerNode node = {
|
InnerNode inner_node = {
|
||||||
.type=NodeType::FunctionArgs,
|
.type=NodeType::FunctionArgs,
|
||||||
.children=nodes,
|
.children=nodes,
|
||||||
.pos=pos
|
.pos=pos
|
||||||
};
|
};
|
||||||
return {
|
ParseReturn retval = {
|
||||||
.node=node,
|
.node=inner_node,
|
||||||
.tokens=tokens
|
.tokens=tokens
|
||||||
};
|
};
|
||||||
|
return {retval, unnamed};
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseReturn parse_comp(vector<Token> tokens) {
|
ParseReturn parse_comp(vector<Token> tokens) {
|
||||||
|
Loading…
Reference in New Issue
Block a user