浏览代码

Added fp operations, fixed a bug of the parser

master
Ludovic 'Archivist' Lagouardette 4 年前
父节点
当前提交
c00303a1ba
共有 2 个文件被更改,包括 120 次插入4 次删除
  1. +117
    -3
      include/rigid_paradise/lispy/lispy.hpp
  2. +3
    -1
      src/csv-sheet/csv-parse.cpp

+ 117
- 3
include/rigid_paradise/lispy/lispy.hpp 查看文件

@ -42,6 +42,7 @@ namespace lispy {
std::unordered_map<std::string, int> atoms;
int last_atom = 0;
bool error_crash = false;
bool print_parse_results = false;
std::unordered_map<int, std::shared_ptr<function>> function_table;
std::unordered_map<int, lvalue> variable_table;
@ -423,7 +424,7 @@ namespace lispy {
auto matching = find_matching(data, idx);
auto res = parse(std::basic_string_view<token>{data.begin()+idx+1, matching-idx-1}, ctx);
ret->append(res.second);
skip = matching - idx + 1;
skip = matching - idx;
++sz;
} else if constexpr (std::is_same_v<T, cons_end>) {
std::cerr << typeid(T).name() << " mismatched parenthesis" << std::endl;
@ -530,6 +531,13 @@ namespace lispy {
{
auto n = lex(data, ctx);
auto p = parse(std::basic_string_view<token>(n.data(), n.size()), ctx);
if(ctx.print_parse_results)
{
print_types_visitor(std::cerr, p.second, ctx);
std::cerr << std::endl;
print_visitor(std::cerr, p.second, ctx);
std::cerr << std::endl;
}
return eval(p.second, ctx);
}
}
@ -540,7 +548,7 @@ namespace lispy_math {
int64_t ret = 0;
if(!arguments)
{
std::cerr << "no argument provided, integer expected" << std::endl;
std::cerr << "no argument provided, number expected" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
@ -554,7 +562,36 @@ namespace lispy_math {
} else if constexpr (std::is_same_v<T, double>) {
ret = arg;
} else {
std::cerr << "bad argument provided, integer expected" << std::endl;
std::cerr << "bad argument provided, number expected" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
}
}, arguments->self);
arguments = arguments->other;
return ret;
}
double next_as_floating(std::shared_ptr<lispy::cons>& arguments, lispy::context& ctx) {
double ret = 0;
if(!arguments)
{
std::cerr << "no argument provided, number expected" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
return ret;
}
std::visit([&](auto arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int64_t>) {
ret = arg;
} else if constexpr (std::is_same_v<T, double>) {
ret = arg;
} else {
std::cerr << "bad argument provided, number expected" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
@ -647,6 +684,74 @@ namespace lispy_math {
return a%b;
}};
};
namespace float_functions {
class plus : lispy::function {virtual lispy::lvalue operator() (const std::shared_ptr<lispy::cons> arguments, lispy::context& ctx) {
auto p = arguments;
double a = next_as_floating(p, ctx);
double b = next_as_floating(p, ctx);
if(p)
{
std::cerr << "expected arity of 2 but more arguments provided" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
}
return a+b;
}};
class minus : lispy::function {virtual lispy::lvalue operator() (const std::shared_ptr<lispy::cons> arguments, lispy::context& ctx) {
auto p = arguments;
double a = next_as_floating(p, ctx);
if(!p) {
return -a;
}
double b = next_as_floating(p, ctx);
if(p)
{
std::cerr << "expected arity of 1 or 2 but more arguments provided" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
}
return a-b;
}};
class product : lispy::function {virtual lispy::lvalue operator() (const std::shared_ptr<lispy::cons> arguments, lispy::context& ctx) {
auto p = arguments;
double a = next_as_floating(p, ctx);
double b = next_as_floating(p, ctx);
if(p)
{
std::cerr << "expected arity of 2 but more arguments provided" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
}
return a*b;
}};
class divide : lispy::function {virtual lispy::lvalue operator() (const std::shared_ptr<lispy::cons> arguments, lispy::context& ctx) {
auto p = arguments;
double a = next_as_floating(p, ctx);
double b = next_as_floating(p, ctx);
if(p)
{
std::cerr << "expected arity of 2 but more arguments provided" << std::endl;
if(ctx.error_crash)
{
std::exit(-1);
}
}
return a/b;
}};
};
inline void add_integer_functions(lispy::context& ctx) {
using func_ptr = std::shared_ptr<lispy::function>;
@ -657,4 +762,13 @@ namespace lispy_math {
ctx.function_table[ctx.get_atom("/")] = func_ptr{(lispy::function*)new integer_functions::divide()};
ctx.function_table[ctx.get_atom("%")] = func_ptr{(lispy::function*)new integer_functions::remainder()};
}
inline void add_floatingp_functions(lispy::context& ctx) {
using func_ptr = std::shared_ptr<lispy::function>;
ctx.function_table[ctx.get_atom("+.")] = func_ptr{(lispy::function*)new float_functions::plus()};
ctx.function_table[ctx.get_atom("-.")] = func_ptr{(lispy::function*)new float_functions::minus()};
ctx.function_table[ctx.get_atom("*.")] = func_ptr{(lispy::function*)new float_functions::product()};
ctx.function_table[ctx.get_atom("/.")] = func_ptr{(lispy::function*)new float_functions::divide()};
}
}

+ 3
- 1
src/csv-sheet/csv-parse.cpp 查看文件

@ -3,8 +3,10 @@
int main() {
lispy::context ctx;
ctx.print_parse_results = true;
lispy_math::add_integer_functions(ctx);
lispy::lvalue v = lispy::eval("cat $AA12 @A12:C23 (+ 3 (* 5 6) ) \"data \\ ひらがな \n\ttabulated\" \"\" \"test 2 \\x65\"", ctx);
lispy_math::add_floatingp_functions(ctx);
lispy::lvalue v = lispy::eval("cat $AA12 @A12:C23 (/. (+ 3 (* 5 6)) 10) \"data \\ ひらがな \n\ttabulated\" \"\" \"test 2 \\x65\"", ctx);
lispy::print_types_visitor(std::cout, v, ctx);
std::cout << std::endl;

正在加载...
取消
保存