ADD: int arithmetic.
parent
12cc10720e
commit
11a7f6a9da
|
@ -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)))
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef fkstd_COMMONS_HPP
|
||||
#define fkstd_COMMONS_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include "../src/Module.hpp"
|
||||
#include "../src/Constant.hpp"
|
||||
|
||||
|
|
116
libstd/fun.cpp
116
libstd/fun.cpp
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
12
src/VM.cpp
12
src/VM.cpp
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue