From 11a7f6a9dab17429e317653e734ed4155f861c76 Mon Sep 17 00:00:00 2001 From: bog Date: Thu, 21 Sep 2023 22:26:13 +0200 Subject: [PATCH] ADD: int arithmetic. --- examples/int.fk | 25 +++++++++ libstd/commons.hpp | 1 + libstd/fun.cpp | 116 ++++++++++++++++++++++++++++++++++++++--- libstd/fun.hpp | 11 +++- libstd/lib.cpp | 6 +++ src/Module.hpp | 2 +- src/NativeFunction.cpp | 5 +- src/NativeFunction.hpp | 4 +- src/Program.cpp | 4 +- src/VM.cpp | 12 +++-- 10 files changed, 169 insertions(+), 17 deletions(-) create mode 100644 examples/int.fk diff --git a/examples/int.fk b/examples/int.fk new file mode 100644 index 0000000..4b05764 --- /dev/null +++ b/examples/int.fk @@ -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))) \ No newline at end of file diff --git a/libstd/commons.hpp b/libstd/commons.hpp index 6664b2a..ff957b5 100644 --- a/libstd/commons.hpp +++ b/libstd/commons.hpp @@ -1,6 +1,7 @@ #ifndef fkstd_COMMONS_HPP #define fkstd_COMMONS_HPP +#include #include "../src/Module.hpp" #include "../src/Constant.hpp" diff --git a/libstd/fun.cpp b/libstd/fun.cpp index cf5e135..8401339 100644 --- a/libstd/fun.cpp +++ b/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(LOG_ERROR, ss.str()); + loc.error(LOG_ERROR, ss.str()); } - return std::make_shared(TYPE_BOOL, true, oracle->loc()); + return std::make_shared(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(TYPE_INT, 0, loc); } + + STDRET add_int(Loc loc, STDARGS args) + { + int result = 0; + + for (auto arg: args) + { + result += std::get(arg->value()); + } + + return std::make_shared(TYPE_INT, result, loc); + } + + STDRET sub_int(Loc loc, STDARGS args) + { + if (args.empty()) + { + return std::make_shared(TYPE_INT, 0, loc); + } + + if (args.size() == 1) + { + return std::make_shared(TYPE_INT, + -std::get(args[0]->value()), + loc); + } + + int result = std::get(args[0]->value()); + + for (size_t i=1; i(args[i]->value()); + } + + return std::make_shared(TYPE_INT, result, loc); + } + + STDRET mul_int(Loc loc, STDARGS args) + { + int result = 1; + + for (auto arg: args) + { + result *= std::get(arg->value()); + } + + return std::make_shared(TYPE_INT, result, loc); + } + + STDRET div_int(Loc loc, STDARGS args) + { + if (args.empty()) + { + return std::make_shared(TYPE_INT, 1, loc); + } + + if (args.size() == 1) + { + return std::make_shared(TYPE_INT, + 1/std::get(args[0]->value()), + loc); + } + + int result = std::get(args[0]->value()); + + for (size_t i=1; i(args[i]->value()); + } + + return std::make_shared(TYPE_INT, result, loc); + } + + STDRET mod_int(Loc loc, STDARGS args) + { + if (args.empty()) + { + return std::make_shared(TYPE_INT, 1, loc); + } + + int result = std::get(args[0]->value()); + + for (size_t i=1; i(args[i]->value()); + } + + return std::make_shared(TYPE_INT, result, loc); + } + + STDRET pow_int(Loc loc, STDARGS args) + { + if (args.empty()) + { + return std::make_shared(TYPE_INT, 1, loc); + } + + int result = std::get(args[0]->value()); + + for (size_t i=1; i(args[i]->value())); + } + + return std::make_shared(TYPE_INT, result, loc); + } } diff --git a/libstd/fun.hpp b/libstd/fun.hpp index dbd9846..642d776 100644 --- a/libstd/fun.hpp +++ b/libstd/fun.hpp @@ -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 diff --git a/libstd/lib.cpp b/libstd/lib.cpp index 645275d..6ad98af 100644 --- a/libstd/lib.cpp +++ b/libstd/lib.cpp @@ -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); diff --git a/src/Module.hpp b/src/Module.hpp index 13bf919..63f5907 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -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 m_lexer = std::make_shared(m_loc); std::shared_ptr m_parser = std::make_shared(*m_lexer); std::shared_ptr m_sym = std::make_shared(); diff --git a/src/NativeFunction.cpp b/src/NativeFunction.cpp index f9d118f..c1e23f3 100644 --- a/src/NativeFunction.cpp +++ b/src/NativeFunction.cpp @@ -12,8 +12,9 @@ namespace fk } std::shared_ptr - NativeFunction::call(std::vector> args) + NativeFunction::call(Loc const& loc, + std::vector> args) { - return m_native(args); + return m_native(loc, args); } } diff --git a/src/NativeFunction.hpp b/src/NativeFunction.hpp index f9e0db9..0a0cc5b 100644 --- a/src/NativeFunction.hpp +++ b/src/NativeFunction.hpp @@ -7,7 +7,7 @@ namespace fk { using native_t = std::function - (std::vector>)>; + (Loc, std::vector>)>; class NativeFunction { @@ -16,7 +16,7 @@ namespace fk virtual ~NativeFunction(); std::shared_ptr - call(std::vector> args); + call(Loc const& loc, std::vector> args); private: native_t m_native; diff --git a/src/Program.cpp b/src/Program.cpp index 31b2f9d..d8b5c5b 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -32,7 +32,9 @@ namespace fk { for (size_t i=0; iequals(*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; } diff --git a/src/VM.cpp b/src/VM.cpp index e65d4f2..113d653 100644 --- a/src/VM.cpp +++ b/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(frame().program - ->get_const(pop())->value()); + if (instr.param > 0) + { + loc = args.front()->loc(); + } + + auto ref = std::get(ref_val->value()); auto fun = std::get> (load_global(ref)); - push(frame().program->add(fun->call(args))); + push(frame().program->add(fun->call(loc, args))); m_pc++; } break;