[libjlx] Parse function calls

[libjlx] Add basic stdlib functions to type_checker
This commit is contained in:
John Stefanelli 2025-05-30 10:54:35 +02:00
parent 693487a62a
commit 26e1f3a173
Signed by: jstefanelli
GPG key ID: 60EDE2437640D2AA
3 changed files with 87 additions and 13 deletions

View file

@ -64,6 +64,7 @@ int main(int argc, char** argv) {
std::cout << "Parsed " << rt->statements.size() << " statements" << std::endl; std::cout << "Parsed " << rt->statements.size() << " statements" << std::endl;
auto type_checker = jlx::type_checker(rt->statements.begin(), rt->statements.end()); auto type_checker = jlx::type_checker(rt->statements.begin(), rt->statements.end());
type_checker.include_stdlib();
try { try {
type_checker.check(); type_checker.check();
} catch (jlx::type_error& err) { } catch (jlx::type_error& err) {

View file

@ -399,8 +399,6 @@ namespace jlx {
} }
std::unique_ptr<expression> parse_expression(std::unique_ptr<expression> previous = nullptr) { std::unique_ptr<expression> parse_expression(std::unique_ptr<expression> previous = nullptr) {
auto start = *current;
if (current == last) { if (current == last) {
if (previous != nullptr) { if (previous != nullptr) {
return previous; return previous;
@ -409,6 +407,9 @@ namespace jlx {
fail_invalid_eof(); fail_invalid_eof();
} }
auto start = *current;
switch(current->type) { switch(current->type) {
case Identifier: case Identifier:
if (previous != nullptr) { if (previous != nullptr) {
@ -445,19 +446,47 @@ namespace jlx {
case Punctuation: case Punctuation:
{ {
if (current->content == "(") { if (current->content == "(") {
identifier_expression* identifier = nullptr;
if (previous != nullptr) { if (previous != nullptr) {
return previous; auto* id = dynamic_cast<identifier_expression*>(previous.get());
if (id == nullptr) {
return previous;
}
identifier = id;
} }
auto ex = parse_expression(); next();
if (current->type != Punctuation || current->content != ")") { if (identifier != nullptr) {
fail_invalid_token(*current); std::vector<std::unique_ptr<expression>> args;
bool first = true;
while (current->type != Punctuation || current->content != ")") {
if (!first) {
if (current->type != Punctuation || current->content != ",") {
fail_invalid_token(*current);
}
next();
}
first = false;
args.emplace_back(parse_expression());
}
next(false);
return std::make_unique<function_call>(identifier->t, identifier->name, std::move(args));
} else {
auto ex = parse_expression();
if (current->type != Punctuation || current->content != ")") {
fail_invalid_token(*current);
}
next(false);
return parse_expression(std::move(ex));
} }
next(false);
return ex;
} else if (current->content == ";") { } else if (current->content == ";") {
if (previous == nullptr) { if (previous == nullptr) {
fail_invalid_token(*current); fail_invalid_token(*current);
@ -476,14 +505,12 @@ namespace jlx {
} }
fail_invalid_token(*current); fail_invalid_token(*current);
break; break;
case Keyword: default:
if (previous != nullptr) { if (previous != nullptr) {
return previous; return previous;
} }
fail_invalid_token(*current); fail_invalid_token(*current);
break; break;
default:
fail_invalid_token(*current);
} }
} }

View file

@ -440,6 +440,7 @@ namespace jlx {
init_type = decl->initial_expression->evaluated_type; init_type = decl->initial_expression->evaluated_type;
} }
auto type = decl->type; auto type = decl->type;
if (init_type.has_value()) { if (init_type.has_value()) {
@ -450,6 +451,13 @@ namespace jlx {
} }
} }
if (type == "comptime_int") {
type = "i64";
} else if (type == "comptime_float") {
type = "f64";
}
if (!type.has_value()) { if (!type.has_value()) {
throw std::runtime_error("Cannot infer variable declaration type"); throw std::runtime_error("Cannot infer variable declaration type");
} }
@ -567,5 +575,43 @@ namespace jlx {
throw std::runtime_error("Missing function"); throw std::runtime_error("Missing function");
} }
type_checker_scope& get_global_scope() {
return scopes.front();
}
void include_stdlib() {
auto& glob = get_global_scope();
constexpr std::array<std::string_view, 11> stringable_types = {
"i8",
"i16",
"i32",
"i64",
"u8",
"u16",
"u32",
"u64",
"f32",
"f64",
"boolean"
};
for (const auto& type : stringable_types) {
glob.functions.insert_or_assign(std::format("{}_to_string", type), runtime_function{
"string",
{
type
}
});
}
glob.functions.insert_or_assign("print", runtime_function{
"void",
{
"string"
}
});
}
}; };
} }