Skip to content

Commit

Permalink
[stdlib] added basic stdlib.psy
Browse files Browse the repository at this point in the history
  • Loading branch information
harrand committed May 25, 2024
1 parent 9da7d06 commit f479938
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 58 deletions.
76 changes: 69 additions & 7 deletions cpp/src/build.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/TargetParser/Host.h"

#ifdef _WIN32
#include <windows.h>
#endif

build::info* cur_build_info = nullptr;

void set_linkage_type(std::int64_t link_type_value)
Expand Down Expand Up @@ -43,13 +47,47 @@ void add_link_library(const char* link_library)
cur_build_info->link_libraries.push_back(link_library);
}

void use_stdlib(std::uint8_t use)
{
cur_build_info->using_stdlib = use;
}

void install_functions(llvm::ExecutionEngine& exe)
{
exe.addGlobalMapping("set_linkage_type", reinterpret_cast<std::uintptr_t>(&set_linkage_type));
exe.addGlobalMapping("set_build_type", reinterpret_cast<std::uintptr_t>(&set_build_type));
exe.addGlobalMapping("set_output_name", reinterpret_cast<std::uintptr_t>(&set_output_name));
exe.addGlobalMapping("add_source", reinterpret_cast<std::uintptr_t>(&add_source));
exe.addGlobalMapping("add_link_library", reinterpret_cast<std::uintptr_t>(&add_link_library));
exe.addGlobalMapping("use_stdlib", reinterpret_cast<std::uintptr_t>(&use_stdlib));
}

const char* get_output_extension(build::linkage_type link)
{
const char* extension = "";
switch(link)
{
case build::linkage_type::executable:
#ifdef _WIN32
extension = ".exe";
#elif defined(__linux__)
extension = ".out";
#else
static_assert("unknown platform");
#endif
break;
case build::linkage_type::library:
#ifdef _WIN32
extension = ".lib";
#elif defined(__linux__)
extension = ".a";
#else
static_assert("unknown platform");
#endif
break;
default: break;
}
return extension;
}

namespace build
Expand Down Expand Up @@ -114,13 +152,19 @@ namespace build
metaprogram_handle->dropAllReferences();
code::cleanup();
}
#ifdef _WIN32
ret.link_name += ".exe";
#elif defined(__linux__)
ret.link_name += ".out";
#else
static_assert("unknown platform");
#endif
ret.link_name += get_output_extension(ret.link);
if(ret.using_stdlib)
{
std::string psyc_path;
#ifdef _WIN32
psyc_path.resize(MAX_PATH);
GetModuleFileNameA(nullptr, psyc_path.data(), psyc_path.size());
#endif
std::filesystem::path psyc_dir = std::filesystem::path{psyc_path}.parent_path();
std::filesystem::path stdlib_path = psyc_dir / "stdlib.psy";
diag::assert_that(std::filesystem::exists(stdlib_path), error_code::buildmeta, "could not find stdlib implementation. expected to find: \"{}\"", stdlib_path.string());
ret.extra_input_files.push_back(stdlib_path);
}
return ret;
}

Expand Down Expand Up @@ -276,6 +320,24 @@ namespace build
.is_extern = true
}
});
ret.root.children.push_back(ast::node
{
.payload = ast::function_definition
{
.func_name = "use_stdlib",
.params =
{
ast::variable_declaration
{
.var_name = "use",
.type_name = "bool",
.initialiser = ast::expression{.expr = ast::bool_literal{.val = true}}
},
},
.ret_type = "u0",
.is_extern = true
}
});


// same with some globals.
Expand Down
1 change: 1 addition & 0 deletions cpp/src/build.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace build
linkage_type link = linkage_type::none;
config_type config = config_type::debug;
std::string link_name = "a";
bool using_stdlib = true;
std::vector<std::filesystem::path> extra_input_files = {};
std::vector<std::filesystem::path> link_libraries = {};
std::string target_triple;
Expand Down
4 changes: 2 additions & 2 deletions cpp/src/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ namespace linkage
}
for(std::filesystem::path link_library : binfo.link_libraries)
{
cmd += std::format(" {}", link_library.string());
cmd += std::format(" \"{}\"", link_library.string());
}

auto lt = divine_linker_type(binfo.compiler_args.linker_name);
Expand Down Expand Up @@ -209,7 +209,7 @@ namespace linkage

for(std::filesystem::path link_library : binfo.link_libraries)
{
cmd += std::format(" {}", link_library.string());
cmd += std::format(" \"{}\"", link_library.string());
}

int ret = std::system(cmd.c_str());
Expand Down
52 changes: 3 additions & 49 deletions samples/scratchpad.psy
Original file line number Diff line number Diff line change
@@ -1,64 +1,18 @@
puts :: (str : i8& const) -> u0 := extern;
main :: () -> i64
{
puts("hello world!");
puts("hello world! ;)");
greeting : string;
defer greeting.cleanup();

greeting.resize(5);
greeting.print();
puts(greeting.str);
greeting.set("hey!");
greeting.print();
puts(greeting.str);

print();
return 0;
}

strlen :: (str : i8& const) -> i64 := extern;
strcpy :: (dst : i8& const, src : i8& const) -> i8& const := extern;
string :: struct
{
str : i8& := null;
resize :: (sz : i64) -> u0
{
if this.str != null
{
// free it first.
__builtin_free(this.str);
}
this.str = __builtin_malloc(sz);
i : i64;
for i = 0, (i != sz), i = (i + 1)
{
this.str[i] = '\0';
}
}
cleanup :: () -> u0
{
if this.str != null
{
__builtin_free(this.str);
}
this.str = null;
}
size :: () -> i64
{
if this.str == null
{
return 0;
}
return strlen(this.str);
}
set :: (literal : i8& const) -> u0
{
strcpy(this.str, literal);
}
print :: () -> u0
{
puts(this.str);
}
}

print :: () -> u0
{
puts("free-function print!");
Expand Down
47 changes: 47 additions & 0 deletions stdlib/stdlib.psy
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
puts :: (str : i8& const) -> u0 := extern;
strlen :: (str : i8& const) -> i64 := extern;
strcpy :: (dst : i8& const, src : i8& const) -> i8& const := extern;

string :: struct
{
str : i8& := null;
resize :: (sz : i64) -> u0
{
if this.str != null
{
// free it first.
__builtin_free(this.str);
}
this.str = __builtin_malloc(sz);
i : i64;
for i = 0, (i != sz), i = (i + 1)
{
this.str[i] = '\0';
}
}
cleanup :: () -> u0
{
if this.str != null
{
__builtin_free(this.str);
}
this.str = null;
}
size :: () -> i64
{
if this.str == null
{
return 0;
}
return strlen(this.str);
}
set :: (literal : i8& const) -> u0
{
strcpy(this.str, literal);
}

//print :: () -> u0
//{
// puts(this.str);
//}
}

0 comments on commit f479938

Please sign in to comment.