ADD: truncat function and fix some bugs related to the closure mechanism.

main
bog 2023-09-25 21:28:57 +02:00
parent 9a8f4096ea
commit d973241ae2
18 changed files with 134 additions and 19 deletions

1
examples/cast.fk Normal file
View File

@ -0,0 +1 @@
(assert= 8 (trunc 8.71))

View File

@ -14,3 +14,32 @@
(assert= 6 (a))
(assert= 7 (a))
(assert= 34 (b))
($ (c) 42)
($ (d)
(+ (c) 1))
(assert= 43 (d))
($ hello 34)
($ (i)
($ (j)
($ (k)
(println hello))))
(((i)))
($ @m './mod2')
($ (u)
($ (v)
($ (w)
(assert= 42 m::var)
(assert= 14 (m::fun 7))
259 )))
(assert= 42 ((-> () m::var)))
(assert= 259 (((u))))

View File

@ -2,16 +2,13 @@
#define fkstd_COMMONS_HPP
#include <cmath>
#include "../src/commons.hpp"
#include "../src/Module.hpp"
#include "../src/Constant.hpp"
#include "../src/SymTable.hpp"
using namespace fk;
#define STDARGS std::vector<std::shared_ptr<Constant>>
#define STDRET std::shared_ptr<Constant>
#define STDSYM std::shared_ptr<SymTable>
FK_ERROR(assert_error);
#endif

View File

@ -278,6 +278,13 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_FLOAT, result, loc);
}
STDRET trunc(Loc loc, Module&, STDARGS args)
{
float val = std::get<float>(args[0]->value());
int res = val;
return std::make_shared<Constant>(TYPE_INT, res, loc);
}
STDRET lt(Loc loc, Module&, STDARGS args)
{
NUM_BINOP(<);

View File

@ -20,6 +20,7 @@ namespace fkstd
STDRET div_float(Loc loc, Module& mod, STDARGS args);
STDRET mod_float(Loc loc, Module& mod, STDARGS args);
STDRET pow_float(Loc loc, Module& mod, STDARGS args);
STDRET trunc(Loc loc, Module& mod, STDARGS args);
STDRET lt(Loc loc, Module& mod, STDARGS args);
STDRET le(Loc loc, Module& mod, STDARGS args);

View File

@ -20,6 +20,8 @@ extern "C" void lib(Module& mod)
mod.register_function("%.", fkstd::mod_float);
mod.register_function("^.", fkstd::pow_float);
mod.register_function("trunc", fkstd::trunc);
mod.register_function("<", fkstd::lt);
mod.register_function("<=", fkstd::le);
mod.register_function(">", fkstd::gt);

View File

@ -63,10 +63,14 @@ fakir_hpp = [
'src/types.hpp',
]
pkg = import('pkgconfig')
fakir_lib = shared_library('fakir',
sources: fakir_cpp,
install: true)
pkg.generate(fakir_lib, subdirs: ['fakir'])
install_headers(fakir_hpp, subdir: 'fakir')
fakir_dep = declare_dependency(

View File

@ -74,11 +74,9 @@ namespace fk
} break;
case NODE_VARDECL: {
m_addr++;
std::string ident = node->child(0)->repr();
auto rhs = node->child(1);
next_addr();
push_decl(ident);
compile_prog(rhs, prog);
pop_decl();
@ -86,11 +84,11 @@ namespace fk
auto entry = sym()->declare_local(ident,
m_addr,
node->loc())
.set_is_array(rhs->type() == NODE_ARRAY)
.set_node(rhs);
prog->add(OP_STORE_LOCAL, m_addr);
} break;
case NODE_ARRAY: {
@ -114,9 +112,7 @@ namespace fk
prog->load_const(std::make_shared<Constant>(TYPE_STRING,
var->repr(),
node->loc()));
compile_prog(mod, prog);
prog->add(OP_LOAD_MOD);
} break;
@ -271,7 +267,17 @@ namespace fk
if (!entry)
{
auto entry = m_sym->find_global(node->repr());
auto entries = m_sym->find_all(node->repr());
std::optional<SymEntry> entry;
for (SymEntry const& e: entries)
{
if (e.scope() <= m_sym->scope()
&& (!entry || e.scope() < entry->scope()))
{
entry = e;
}
}
if (entry)
{
@ -293,10 +299,12 @@ namespace fk
if (!entry->is_global())
{
prog->add(OP_LOAD_LOCAL, entry->addr());
break;
}
else
{
prog->add(OP_LOAD_GLOBAL, entry->addr());
break;
}
} break;
@ -348,4 +356,9 @@ namespace fk
m_decl_stack.pop_back();
}
addr_t Compiler::next_addr()
{
m_addr++;
return m_addr;
}
}

View File

@ -44,6 +44,8 @@ namespace fk
void push_decl(std::string const& ident);
void pop_decl();
addr_t next_addr();
private:
Module& m_mod;
addr_t m_addr = 0;

View File

@ -30,6 +30,7 @@ namespace fk
case TYPE_STRING: return std::get<std::string>(m_value);
case TYPE_REF: return std::to_string(std::get<size_t>(m_value));
case TYPE_PROGRAM: return "<program>";
case TYPE_CUSTOM: return "<custom>";
case TYPE_ARRAY: return std::get<std::shared_ptr<Array>>
(m_value)->string();

View File

@ -15,6 +15,7 @@ namespace fk
using constant_t = std::variant<int,
float,
bool,
void*,
std::string,
size_t,
std::shared_ptr<Program>,

View File

@ -17,10 +17,15 @@ namespace fk
std::shared_ptr<Module> Module::get_mod(std::string const& name)
{
assert(m_native_modules.find(name) != std::end(m_native_modules));
assert(has_mod(name));
return m_native_modules[name];
}
bool Module::has_mod(std::string const& name)
{
return m_native_modules.find(name) != std::end(m_native_modules);
}
void Module::build()
{
import_std();

View File

@ -24,6 +24,7 @@ namespace fk
std::shared_ptr<VM> vm() const { return m_vm; }
std::shared_ptr<Module> get_mod(std::string const& name);
bool has_mod(std::string const& name);
void build();

View File

@ -126,6 +126,22 @@ namespace fk
return idx;
}
std::vector<SymEntry> SymTable::find_all(std::string const& name)
{
std::vector<SymEntry> res;
for (auto e: m_entries)
{
if (e.name() == name)
{
res.push_back(e);
}
}
return res;
}
void SymTable::set(std::string const& name, addr_t addr)
{
if (auto idx = find_idx(name);

View File

@ -30,6 +30,8 @@ namespace fk
std::optional<SymEntry> find_global(std::string const& name);
std::optional<size_t> find_idx_global(std::string const& name);
std::vector<SymEntry> find_all(std::string const& name);
void set(std::string const& name, addr_t addr);
std::string string() const;

View File

@ -116,7 +116,24 @@ namespace fk
std::filesystem::path path =
std::get<std::string>(path_val->value());
auto mod = m_mod.get_mod(path);
auto alt_path = std::filesystem::path("/")
/ "usr" / "lib" / ("lib"
+ path.filename().string()
+ ".so" );
std::shared_ptr<Module> mod;
if (m_mod.has_mod(path))
{
mod = m_mod.get_mod(path);
}
else if (std::filesystem::exists(alt_path))
{
mod = std::make_shared<Module>(alt_path);
mod->import_std();
mod->import_library(alt_path);
}
addr_t addr = store_global(mod);
auto res = std::make_shared<Constant>(TYPE_REF, addr,
@ -129,6 +146,7 @@ namespace fk
case OP_LOAD_MOD: {
addr_t mod_addr = pop();
auto mod_val = frame().program->get_const(mod_addr);
size_t mod_ref =
std::get<size_t>(mod_val->value());
@ -203,8 +221,8 @@ namespace fk
{
auto val = frame().lambda->get_env(instr.param);
addr_t addr = frame().program->add(val);
push(addr);
m_pc++;
break;
}
@ -249,12 +267,20 @@ namespace fk
addr_t addr = store_global(lambda);
auto ref = std::make_shared<Constant>(TYPE_REF, addr, p->loc());
if (m_frames.size() > 1)
/*if (m_frames.size() >= 1)
{
for (auto e: m_frames.back().locals)
{
lambda->add_env(e.first, e.second);
}
}*/
for (auto const& f: m_frames)
{
for (auto e: f.locals)
{
lambda->add_env(e.first, e.second);
}
}
push(frame().program->add(ref));
@ -494,11 +520,14 @@ namespace fk
std::vector<std::shared_ptr<Constant>> args,
size_t ref,
Loc const& loc)
{
if (&parent != this)
{
for (auto entry: parent.m_globals)
{
store_global(entry.first, entry.second);
}
}
auto self = std::make_shared<Constant>(TYPE_REF,
static_cast<size_t>(ref),

View File

@ -26,4 +26,8 @@ using addr_t = size_t;
NAME (std::string const& what) : std::runtime_error(what ) {} \
}
#define STDARGS std::vector<std::shared_ptr<Constant>>
#define STDRET std::shared_ptr<Constant>
#define STDSYM std::shared_ptr<SymTable>
#endif

View File

@ -5,7 +5,7 @@
#define TYPES(G) G(TYPE_INT), G(TYPE_FLOAT), G(TYPE_BOOL), G(TYPE_STRING), \
G(TYPE_REF), G(TYPE_PROGRAM), G(TYPE_ARRAY), G(TYPE_NIL), \
G(TYPE_FUNCTION)
G(TYPE_FUNCTION), G(TYPE_CUSTOM)
namespace fk
{