From 3333842cd5cf58619ddfb1671023d23716574e54 Mon Sep 17 00:00:00 2001 From: Harrand Date: Wed, 15 May 2024 20:21:31 +0100 Subject: [PATCH] [cpp] added builtins --- cpp/CMakeLists.txt | 2 ++ cpp/src/ast.hpp | 1 + cpp/src/builtin.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++ cpp/src/builtin.hpp | 17 ++++++++++++ cpp/src/semal.cpp | 16 ++++++----- cpp/src/semal.hpp | 2 +- cpp/src/type.cpp | 1 + samples/scratchpad.psy | 1 + 8 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 cpp/src/builtin.cpp create mode 100644 cpp/src/builtin.hpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4775b75..0f1f30a 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -34,6 +34,8 @@ add_executable(psyc src/psyc_main.cpp src/ast.cpp src/ast.hpp + src/builtin.cpp + src/builtin.hpp src/config.hpp src/diag.hpp src/error.hpp diff --git a/cpp/src/ast.hpp b/cpp/src/ast.hpp index 8f20554..d5b77d3 100644 --- a/cpp/src/ast.hpp +++ b/cpp/src/ast.hpp @@ -155,6 +155,7 @@ struct ast std::vector params = {}; std::string ret_type; bool is_extern = false; + bool is_builtin = false; constexpr std::string to_string() const { std::string params_str = "("; diff --git a/cpp/src/builtin.cpp b/cpp/src/builtin.cpp new file mode 100644 index 0000000..83da56b --- /dev/null +++ b/cpp/src/builtin.cpp @@ -0,0 +1,61 @@ +#include "builtin.hpp" +#include + +std::array builtin_names +{ + "malloc", + "free" +}; + +std::array builtin_functions +{ + semal::function_t + { + .return_ty = type::from_primitive(primitive_type::i8).pointer_to(), + .name = "malloc", + .params = + { + semal::local_variable_t + { + .ty = type::from_primitive(primitive_type::u64), + .name = "size_bytes", + .ctx = {}, + } + }, + .ctx = {}, + .is_method = false + }, + semal::function_t + { + .return_ty = type::from_primitive(primitive_type::u0), + .name = "free", + .params = + { + semal::local_variable_t + { + .ty = type::from_primitive(primitive_type::i8).pointer_to(), + .name = "ptr", + .ctx = {}, + } + }, + .ctx = {}, + .is_method = false + }, +}; + +builtin try_find_builtin(std::string_view funcname) +{ + for(int i = 0; i < (int)builtin::_count; i++) + { + if(std::format("__builtin_{}", builtin_names[i]) == funcname) + { + return (builtin)i; + } + } + return builtin::_undefined; +} + +semal::function_t& get_builtin_function(builtin b) +{ + return builtin_functions[(int)b]; +} \ No newline at end of file diff --git a/cpp/src/builtin.hpp b/cpp/src/builtin.hpp new file mode 100644 index 0000000..0d7203b --- /dev/null +++ b/cpp/src/builtin.hpp @@ -0,0 +1,17 @@ +#ifndef PSYC_BUILTIN_HPP +#define PSYC_BUILTIN_HPP +#include "ast.hpp" +#include "semal.hpp" + +enum class builtin +{ + malloc, + free, + _count, + _undefined, +}; + +// return builtin::_undefined if funcname doesnt correspond to a builtin. +builtin try_find_builtin(std::string_view funcname); +semal::function_t& get_builtin_function(builtin b); +#endif // PSYC_BUILTIN_HPP \ No newline at end of file diff --git a/cpp/src/semal.cpp b/cpp/src/semal.cpp index 64f87ca..5cbc83a 100644 --- a/cpp/src/semal.cpp +++ b/cpp/src/semal.cpp @@ -1,5 +1,6 @@ #include "semal.hpp" #include "type.hpp" +#include "builtin.hpp" #include "util.hpp" namespace semal @@ -156,6 +157,11 @@ namespace semal return &funcdata; } } + builtin maybe_builtin = try_find_builtin(name); + if(maybe_builtin != builtin::_undefined) + { + return &get_builtin_function(maybe_builtin); + } return nullptr; } @@ -231,13 +237,14 @@ namespace semal return nullptr; } - output analyse_predecl(const ast& tree) + output analyse_predecl(ast tree) { output ret; auto semal_assert = [&tree](ast::path_t path, bool expr, const char* fmt, auto... ts) { context{&tree, path}.semal_assert(expr, fmt, ts...); }; + for(std::size_t i = 0; i < tree.root.children.size(); i++) { const ast::node& node = tree.root.children[i]; @@ -569,12 +576,7 @@ namespace semal type function_call(const data& d, const ast::function_call& payload) { const function_t* maybe_function = d.state.try_find_function(payload.function_name.c_str()); - if(maybe_function == nullptr) - { - d.assert_that(payload.function_name.starts_with("__builtin_"), std::format("call to undeclared function \"{}\"", payload.function_name)); - diag::note("detected call to builtin function \"{}\"", payload.function_name); - return type::undefined(); - } + d.assert_that(maybe_function != nullptr, std::format("call to undeclared function \"{}\"", payload.function_name)); return maybe_function->return_ty; } diff --git a/cpp/src/semal.hpp b/cpp/src/semal.hpp index f100a04..27b0589 100644 --- a/cpp/src/semal.hpp +++ b/cpp/src/semal.hpp @@ -85,7 +85,7 @@ namespace semal type get_type_from_payload(const ast::node::payload_t& payload, const ast& tree, const ast::path_t& path) const; }; - output analyse_predecl(const ast& tree); + output analyse_predecl(ast tree); output analyse_full(const ast& tree, output predecl = {}); struct state diff --git a/cpp/src/type.cpp b/cpp/src/type.cpp index 9f1c8cb..cff0576 100644 --- a/cpp/src/type.cpp +++ b/cpp/src/type.cpp @@ -199,6 +199,7 @@ type type::dereference() const type type::pointer_to(type_qualifier quals) const { + diag::assert_that(!this->is_undefined(), error_code::type, "attempt to get pointer to type."); return { .ty = util::box{*this}, diff --git a/samples/scratchpad.psy b/samples/scratchpad.psy index dc7b6b1..5bb926c 100644 --- a/samples/scratchpad.psy +++ b/samples/scratchpad.psy @@ -7,6 +7,7 @@ mydata :: struct { member : i64 := 5; } +__builtin_malloc(123); putchar :: (ch : i8) -> u0 := extern; dub :: (val : i64) -> i64