[libjlx] Parse function calls
[libjlx] Add basic stdlib functions to type_checker
This commit is contained in:
parent
693487a62a
commit
26e1f3a173
3 changed files with 87 additions and 13 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue