ADD: int arithmetic.

main
bog 2023-09-21 22:26:13 +02:00
parent 12cc10720e
commit 11a7f6a9da
10 changed files with 169 additions and 17 deletions

25
examples/int.fk Normal file
View File

@ -0,0 +1,25 @@
(assert= 3 (+ 3))
(assert= 6 (+ 1 2 3))
(assert= 0 (+))
(assert= -3 (- 3))
(assert= 4 (- 7 3))
(assert= -4 (- 1 2 3))
(assert= 0 (-))
(assert= 1 (*))
(assert= 2 (* 2))
(assert= 14 (* 2 7))
(assert= 1 (/))
(assert= 0 (/ 5))
(assert= 2 (/ 5 2))
(assert= 6 (/ 18 3))
(assert= 1 (%))
(assert= 3 (% 7 4))
(assert= 1 (^))
(assert= 128 (^ 2 7))
(assert= 8 (* 2 (+ 1 3)))

View File

@ -1,6 +1,7 @@
#ifndef fkstd_COMMONS_HPP
#define fkstd_COMMONS_HPP
#include <cmath>
#include "../src/Module.hpp"
#include "../src/Constant.hpp"

View File

@ -2,7 +2,7 @@
namespace fkstd
{
STDRET assert_eq(STDARGS args)
STDRET assert_eq(Loc loc, STDARGS args)
{
auto oracle = args[0];
auto expr = args[1];
@ -16,13 +16,13 @@ namespace fkstd
<< expr->string()
<< "'";
oracle->loc().error<assert_error>(LOG_ERROR, ss.str());
loc.error<assert_error>(LOG_ERROR, ss.str());
}
return std::make_shared<Constant>(TYPE_BOOL, true, oracle->loc());
return std::make_shared<Constant>(TYPE_BOOL, true, loc);
}
STDRET println(STDARGS args)
STDRET println(Loc loc, STDARGS args)
{
std::string sep;
@ -32,8 +32,6 @@ namespace fkstd
sep = " ";
}
Loc loc {"???"};
if (args.size() > 0)
{
loc = args.front()->loc();
@ -43,4 +41,110 @@ namespace fkstd
return std::make_shared<Constant>(TYPE_INT, 0, loc);
}
STDRET add_int(Loc loc, STDARGS args)
{
int result = 0;
for (auto arg: args)
{
result += std::get<int>(arg->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET sub_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 0, loc);
}
if (args.size() == 1)
{
return std::make_shared<Constant>(TYPE_INT,
-std::get<int>(args[0]->value()),
loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result -= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET mul_int(Loc loc, STDARGS args)
{
int result = 1;
for (auto arg: args)
{
result *= std::get<int>(arg->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET div_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
if (args.size() == 1)
{
return std::make_shared<Constant>(TYPE_INT,
1/std::get<int>(args[0]->value()),
loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result /= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET mod_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result %= std::get<int>(args[i]->value());
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
STDRET pow_int(Loc loc, STDARGS args)
{
if (args.empty())
{
return std::make_shared<Constant>(TYPE_INT, 1, loc);
}
int result = std::get<int>(args[0]->value());
for (size_t i=1; i<args.size(); i++)
{
result = std::pow(result, std::get<int>(args[i]->value()));
}
return std::make_shared<Constant>(TYPE_INT, result, loc);
}
}

View File

@ -4,8 +4,15 @@
namespace fkstd
{
STDRET assert_eq(STDARGS args);
STDRET println(STDARGS args);
STDRET assert_eq(Loc loc, STDARGS args);
STDRET println(Loc loc, STDARGS args);
STDRET add_int(Loc loc, STDARGS args);
STDRET sub_int(Loc loc, STDARGS args);
STDRET mul_int(Loc loc, STDARGS args);
STDRET div_int(Loc loc, STDARGS args);
STDRET mod_int(Loc loc, STDARGS args);
STDRET pow_int(Loc loc, STDARGS args);
}
#endif

View File

@ -6,6 +6,12 @@ extern "C" void lib(Module& mod)
{
mod.register_function("assert=", fkstd::assert_eq);
mod.register_function("println", fkstd::println);
mod.register_function("+", fkstd::add_int);
mod.register_function("-", fkstd::sub_int);
mod.register_function("*", fkstd::mul_int);
mod.register_function("/", fkstd::div_int);
mod.register_function("%", fkstd::mod_int);
mod.register_function("^", fkstd::pow_int);
mod.register_macro("assert-static-fail", fkstd::assert_static_fail);
mod.register_macro(":", fkstd::block);

View File

@ -29,7 +29,7 @@ namespace fk
private:
std::filesystem::path m_source_path;
std::string m_source;
Loc m_loc {m_source_path};
Loc m_loc {m_source_path, 1};
std::shared_ptr<Lexer> m_lexer = std::make_shared<Lexer>(m_loc);
std::shared_ptr<Parser> m_parser = std::make_shared<Parser>(*m_lexer);
std::shared_ptr<SymTable> m_sym = std::make_shared<SymTable>();

View File

@ -12,8 +12,9 @@ namespace fk
}
std::shared_ptr<Constant>
NativeFunction::call(std::vector<std::shared_ptr<Constant>> args)
NativeFunction::call(Loc const& loc,
std::vector<std::shared_ptr<Constant>> args)
{
return m_native(args);
return m_native(loc, args);
}
}

View File

@ -7,7 +7,7 @@
namespace fk
{
using native_t = std::function
<std::shared_ptr<Constant>(std::vector<std::shared_ptr<Constant>>)>;
<std::shared_ptr<Constant>(Loc, std::vector<std::shared_ptr<Constant>>)>;
class NativeFunction
{
@ -16,7 +16,7 @@ namespace fk
virtual ~NativeFunction();
std::shared_ptr<Constant>
call(std::vector<std::shared_ptr<Constant>> args);
call(Loc const& loc, std::vector<std::shared_ptr<Constant>> args);
private:
native_t m_native;

View File

@ -32,7 +32,9 @@ namespace fk
{
for (size_t i=0; i<m_consts.size(); i++)
{
if (m_consts[i]->equals(*constant))
if (m_consts[i]->equals(*constant)
&& m_consts[i]->loc().line() == constant->loc().line()
&& m_consts[i]->loc().path() == constant->loc().path())
{
return i;
}

View File

@ -101,13 +101,19 @@ namespace fk
args.insert(std::begin(args),
frame().program->get_const(addr));
}
auto ref_val = frame().program->get_const(pop());
Loc loc = ref_val->loc();
auto ref = std::get<size_t>(frame().program
->get_const(pop())->value());
if (instr.param > 0)
{
loc = args.front()->loc();
}
auto ref = std::get<size_t>(ref_val->value());
auto fun = std::get<std::shared_ptr<NativeFunction>>
(load_global(ref));
push(frame().program->add(fun->call(args)));
push(frame().program->add(fun->call(loc, args)));
m_pc++;
} break;