[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;
auto type_checker = jlx::type_checker(rt->statements.begin(), rt->statements.end());
type_checker.include_stdlib();
try {
type_checker.check();
} 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) {
auto start = *current;
if (current == last) {
if (previous != nullptr) {
return previous;
@ -409,6 +407,9 @@ namespace jlx {
fail_invalid_eof();
}
auto start = *current;
switch(current->type) {
case Identifier:
if (previous != nullptr) {
@ -445,19 +446,47 @@ namespace jlx {
case Punctuation:
{
if (current->content == "(") {
identifier_expression* identifier = 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 != ")") {
fail_invalid_token(*current);
if (identifier != nullptr) {
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 == ";") {
if (previous == nullptr) {
fail_invalid_token(*current);
@ -476,14 +505,12 @@ namespace jlx {
}
fail_invalid_token(*current);
break;
case Keyword:
default:
if (previous != nullptr) {
return previous;
}
fail_invalid_token(*current);
break;
default:
fail_invalid_token(*current);
}
}

View file

@ -440,6 +440,7 @@ namespace jlx {
init_type = decl->initial_expression->evaluated_type;
}
auto type = decl->type;
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()) {
throw std::runtime_error("Cannot infer variable declaration type");
}
@ -567,5 +575,43 @@ namespace jlx {
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"
}
});
}
};
}