Parse varargs

This commit is contained in:
Sofia 2026-04-11 22:18:02 +03:00
parent 3f61e3749e
commit 8646d5c0d0
4 changed files with 27 additions and 2 deletions

View File

@ -91,6 +91,11 @@ namespace AST {
out << " " << *param.first;
}
}
if (this->m_is_vararg) {
if (counter > 0)
out << ", ";
out << "...";
}
out << ") -> ";
out << this->m_return_ty->formatted();

View File

@ -176,6 +176,7 @@ namespace AST {
private:
std::unique_ptr<types::Type> m_return_ty;
std::vector<std::pair<std::optional<std::string>, std::unique_ptr<types::Type>>> m_params;
bool m_is_vararg;
std::string m_name;
std::optional<std::vector<std::unique_ptr<Statement>>> m_statements;
public:
@ -183,11 +184,13 @@ namespace AST {
token::Metadata meta,
std::unique_ptr<types::Type> return_ty,
std::vector<std::pair<std::optional<std::string>, std::unique_ptr<types::Type>>> params,
bool is_vararg,
std::string name,
std::optional<std::vector<std::unique_ptr<Statement>>> statements)
: TopLevelStatement{ meta }
, m_return_ty{ std::move(return_ty) }
, m_params{ std::move(params) }
, m_is_vararg{ is_vararg }
, m_name{ name }
, m_statements{ std::move(statements) } {
}

View File

@ -275,10 +275,20 @@ namespace parsing {
inner.expect(token::Type::Symbol, "(");
std::vector<std::pair<std::optional<std::string>, std::unique_ptr<types::Type>>> params;
bool is_vararg = false;
while (inner.peek().content != ")") {
if (params.size() > 0) {
inner.expect(token::Type::Symbol, ",");
}
if (inner.peek().content == ".") {
inner.next();
inner.expect(token::Type::Symbol, ".");
inner.expect(token::Type::Symbol, ".");
is_vararg = true;
break;
}
auto param_ty = parse_type(inner).unwrap();
std::optional<std::string> param_name{};
if (inner.peek().type == token::Type::Ident) {
@ -310,7 +320,14 @@ namespace parsing {
stream.m_position = inner.m_position;
auto fun = new AST::Function{ before_meta + stream.metadata(), std::move(type), std::move(params), name_token.content, std::move(statements) };
auto fun = new AST::Function{
before_meta + stream.metadata(),
std::move(type),
std::move(params),
is_vararg,
name_token.content,
std::move(statements)
};
return std::unique_ptr<AST::TopLevelStatement>{ fun };
}
catch (std::runtime_error& error) {

2
test.c
View File

@ -1,4 +1,4 @@
void printf(char*, int);
void printf(char*, ...);
int fibonacci(int n) {
if (n < 2)