Compare commits
No commits in common. "e12ff9694332fbc1d6a48042f4f99e85cfb351f0" and "47b44d3439c28d97ad895f7be5a3c9a1ac629f91" have entirely different histories.
e12ff96943
...
47b44d3439
|
@ -24,5 +24,4 @@ BLOCK ::= opar colon EXPR* cpar
|
|||
ARRAY ::= osquare EXPR* csquare
|
||||
IMPORT ::= opar import string cpar
|
||||
SHORT_IMPORT ::= opar decl import ident string cpar
|
||||
SHORTER_IMPORT ::= opar decl import ident cpar
|
||||
NS ::= ident ns ident
|
||||
|
|
26
lib/cast.hpp
26
lib/cast.hpp
|
@ -1,26 +0,0 @@
|
|||
#include "commons.hpp"
|
||||
|
||||
extern "C" void lib_cast(grino::Loader& loader)
|
||||
{
|
||||
grino::Loc loc {"core/casts"};
|
||||
|
||||
loader.add_native("stoi", [loc](auto args){
|
||||
std::string value = args[0]->as_string();
|
||||
return grino::Value::make_int(loc, std::stoi(value));
|
||||
});
|
||||
|
||||
loader.add_native("itos", [loc](auto args){
|
||||
int value = args[0]->as_int();
|
||||
return grino::Value::make_string(loc, std::to_string(value));
|
||||
});
|
||||
|
||||
loader.add_native("stof", [loc](auto args){
|
||||
std::string value = args[0]->as_string();
|
||||
return grino::Value::make_int(loc, std::stof(value));
|
||||
});
|
||||
|
||||
loader.add_native("ftos", [loc](auto args){
|
||||
float value = args[0]->as_float();
|
||||
return grino::Value::make_string(loc, std::to_string(value));
|
||||
});
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#include "../src/Loader.hpp"
|
||||
#include "../src/Logger.hpp"
|
||||
#include "../src/Value.hpp"
|
||||
#include "../src/opcodes.hpp"
|
||||
#include "../src/Module.hpp"
|
129
lib/core.cpp
129
lib/core.cpp
|
@ -1,11 +1,8 @@
|
|||
#include "../src/Loader.hpp"
|
||||
#include "src/Logger.hpp"
|
||||
#include "src/Prototype.hpp"
|
||||
#include "src/Value.hpp"
|
||||
#include "src/opcodes.hpp"
|
||||
#include "../src/Module.hpp"
|
||||
#include "cast.hpp"
|
||||
#include "src/types.hpp"
|
||||
|
||||
GRINO_ERROR(assertion_error);
|
||||
|
||||
|
@ -44,11 +41,7 @@ extern "C" void lib_collection(grino::Loader& loader)
|
|||
};
|
||||
|
||||
return f(args[0], idxs);
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_NIL, grino::HINT_ANY},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL, grino::HINT_ANY},
|
||||
}));
|
||||
});
|
||||
|
||||
loader.add_native("empty?", [&loader](auto args){
|
||||
auto val = args[0];
|
||||
|
@ -146,21 +139,11 @@ extern "C" void lib_flow_control(grino::Loader& loader)
|
|||
compiler.compile(else_node, prog, sym);
|
||||
|
||||
prog.set_param(br, prog.size());
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_NONE},
|
||||
}}));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" void lib_int(grino::Loader& loader)
|
||||
{
|
||||
auto var_proto =
|
||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_INT},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT},
|
||||
});
|
||||
|
||||
loader.add_native("+", [](auto args){
|
||||
int result = 0;
|
||||
|
||||
|
@ -177,7 +160,7 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("*", [](auto args){
|
||||
int result = 1;
|
||||
|
@ -195,7 +178,7 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("-", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -222,7 +205,7 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("/", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -249,7 +232,7 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("%", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -276,7 +259,7 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("^", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -303,17 +286,11 @@ extern "C" void lib_int(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_int(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" void lib_float(grino::Loader& loader)
|
||||
{
|
||||
auto var_proto =
|
||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM, grino::TYPE_FLOAT},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_INT},
|
||||
});
|
||||
|
||||
loader.add_native("+.", [](auto args){
|
||||
float result = 0;
|
||||
|
||||
|
@ -330,7 +307,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("*.", [](auto args){
|
||||
float result = 1;
|
||||
|
@ -348,7 +325,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("-.", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -375,7 +352,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("/.", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -402,7 +379,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("%.", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -429,7 +406,7 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("^.", [](auto args){
|
||||
grino::Loc loc {"???", 0};
|
||||
|
@ -456,18 +433,11 @@ extern "C" void lib_float(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_float(loc, result);
|
||||
}, var_proto);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" void lib_cmp(grino::Loader& loader)
|
||||
{
|
||||
auto var_proto =
|
||||
std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot>{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_INT},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_BOOL},
|
||||
});
|
||||
|
||||
loader.add_native("<", [](auto args){
|
||||
if (args[0]->type() == grino::TYPE_INT)
|
||||
{
|
||||
|
@ -485,7 +455,7 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
|||
}
|
||||
|
||||
assert(0);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("<=", [](auto args){
|
||||
if (args[0]->type() == grino::TYPE_INT)
|
||||
|
@ -504,7 +474,7 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
|||
}
|
||||
|
||||
assert(0);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native(">", [](auto args){
|
||||
if (args[0]->type() == grino::TYPE_INT)
|
||||
|
@ -523,7 +493,7 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
|||
}
|
||||
|
||||
assert(0);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native(">=", [](auto args){
|
||||
if (args[0]->type() == grino::TYPE_INT)
|
||||
|
@ -542,33 +512,21 @@ extern "C" void lib_cmp(grino::Loader& loader)
|
|||
}
|
||||
|
||||
assert(0);
|
||||
}, var_proto);
|
||||
});
|
||||
|
||||
loader.add_native("ne?", [](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
|
||||
return grino::Value::make_bool(args[0]->loc(), !lhs->equals(*rhs));
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_ANY},
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_BOOL}
|
||||
}}));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" void lib_bool(grino::Loader& loader)
|
||||
{
|
||||
loader.add_native("not", [](auto args){
|
||||
return grino::Value::make_bool(args[0]->loc(), !args[0]->as_bool());
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_BOOL},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_BOOL}
|
||||
}}));
|
||||
});
|
||||
|
||||
loader.add_static("and", [](auto& compiler, auto node,
|
||||
auto& program,
|
||||
|
@ -598,14 +556,7 @@ extern "C" void lib_bool(grino::Loader& loader)
|
|||
program.push_instr(grino::OPCODE_LOAD_CONST, addr);
|
||||
|
||||
program.set_param(to_end, program.size());
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM,
|
||||
grino::TYPE_BOOL,
|
||||
grino::HINT_NONE},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_BOOL,
|
||||
grino::HINT_NONE},
|
||||
}}));
|
||||
});
|
||||
|
||||
loader.add_static("or", [](auto& compiler, auto node,
|
||||
auto& program, auto& sym){
|
||||
|
@ -635,14 +586,7 @@ extern "C" void lib_bool(grino::Loader& loader)
|
|||
program.push_instr(grino::OPCODE_LOAD_CONST, addr);
|
||||
|
||||
program.set_param(to_end, program.size());
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_VARIADIC_PARAM,
|
||||
grino::TYPE_BOOL,
|
||||
grino::HINT_NONE},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_BOOL,
|
||||
grino::HINT_NONE},
|
||||
}}));
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" void lib_assert(grino::Loader& loader)
|
||||
|
@ -661,10 +605,7 @@ extern "C" void lib_assert(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_bool(args.front()->loc(), true);
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM, grino::TYPE_BOOL},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN, grino::TYPE_NIL}
|
||||
}}));
|
||||
});
|
||||
|
||||
loader.add_native("assert=", [](auto args){
|
||||
auto lhs = args.front();
|
||||
|
@ -730,7 +671,6 @@ extern "C" void lib(grino::Loader& loader)
|
|||
lib_collection(loader);
|
||||
lib_array(loader);
|
||||
lib_string(loader);
|
||||
lib_cast(loader);
|
||||
|
||||
loader.add_native("dump", [](auto args){
|
||||
std::string sep;
|
||||
|
@ -763,17 +703,7 @@ extern "C" void lib(grino::Loader& loader)
|
|||
}
|
||||
|
||||
program.push_value(grino::Value::make_nil(node->loc()));
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_ANY},
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_NONE}
|
||||
}}));
|
||||
});
|
||||
|
||||
loader.add_native("eq?", [](auto args){
|
||||
auto lhs = args.front();
|
||||
|
@ -789,14 +719,5 @@ extern "C" void lib(grino::Loader& loader)
|
|||
}
|
||||
|
||||
return grino::Value::make_bool(args.front()->loc(), true);
|
||||
}, std::make_shared<grino::Prototype>(std::vector<grino::TypeSlot> {{
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_ANY},
|
||||
grino::TypeSlot {grino::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME},
|
||||
grino::TypeSlot {grino::HINT_CAT_RETURN,
|
||||
grino::TYPE_BOOL}
|
||||
}}));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
#include "src/Loader.hpp"
|
||||
#include "src/Module.hpp"
|
||||
|
||||
extern "C" void lib_io(grino::Loader& loader)
|
||||
{
|
||||
auto mod = loader.add_module("io");
|
||||
|
||||
mod->loader()->add_native("print", [](auto args){
|
||||
for (auto arg: args)
|
||||
{
|
||||
std::cout << arg->string();
|
||||
}
|
||||
return grino::Value::make_nil(grino::Loc {"io"});
|
||||
});
|
||||
|
||||
mod->loader()->add_native("println", [](auto args){
|
||||
for (auto arg: args)
|
||||
{
|
||||
std::cout << arg->string();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return grino::Value::make_nil(grino::Loc {"io"});
|
||||
});
|
||||
|
||||
mod->loader()->add_native("read", [](auto args){
|
||||
std::string value;
|
||||
std::cin >> value;
|
||||
|
||||
return grino::Value::make_string(grino::Loc {"io"}, value);
|
||||
});
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
#include "src/Loader.hpp"
|
||||
#include "src/Module.hpp"
|
||||
|
||||
extern "C" void lib_rand(grino::Loader& loader)
|
||||
{
|
||||
grino::Loc loc {"core/rand"};
|
||||
auto mod = loader.add_module("rand");
|
||||
|
||||
mod->loader()->add_native("randf", [loc](auto args){
|
||||
std::mt19937 r;
|
||||
|
||||
r.seed(std::chrono::steady_clock::now().time_since_epoch().count());
|
||||
|
||||
std::uniform_real_distribution<float> urd(0.0f, 1.0f);
|
||||
|
||||
return grino::Value::make_float(loc, urd(r));
|
||||
});
|
||||
|
||||
mod->loader()->add_native("range", [loc](auto args){
|
||||
std::mt19937 r;
|
||||
|
||||
r.seed(std::chrono::steady_clock::now().time_since_epoch().count());
|
||||
int from = args[0]->as_int();
|
||||
int to = args[1]->as_int();
|
||||
|
||||
std::uniform_int_distribution<int> dist(from, to);
|
||||
|
||||
return grino::Value::make_int(loc, dist(r));
|
||||
});
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
#include "src/Loader.hpp"
|
||||
|
||||
#include "io.hpp"
|
||||
#include "rand.hpp"
|
||||
|
||||
extern "C" void lib(grino::Loader& loader)
|
||||
{
|
||||
lib_io(loader);
|
||||
lib_rand(loader);
|
||||
}
|
15
meson.build
15
meson.build
|
@ -35,8 +35,6 @@ grino_src = shared_library('grino',
|
|||
'src/Loader.cpp',
|
||||
'src/Addr.cpp',
|
||||
'src/Module.cpp',
|
||||
'src/StaticPass.cpp',
|
||||
'src/Prototype.cpp',
|
||||
],
|
||||
install: true)
|
||||
pkg = import('pkgconfig')
|
||||
|
@ -64,8 +62,6 @@ install_headers(
|
|||
'src/Loader.hpp',
|
||||
'src/Addr.hpp',
|
||||
'src/Module.hpp',
|
||||
'src/StaticPass.hpp',
|
||||
'src/Prototype.hpp',
|
||||
], subdir: 'grino'
|
||||
)
|
||||
|
||||
|
@ -81,16 +77,6 @@ shared_library('grino_core',
|
|||
install: true,
|
||||
install_dir: grino_libdir)
|
||||
|
||||
shared_library('grino_std',
|
||||
sources: [
|
||||
'lib/std/std.cpp'
|
||||
],
|
||||
dependencies: [
|
||||
grino_dep
|
||||
],
|
||||
install: true,
|
||||
install_dir: grino_libdir)
|
||||
|
||||
executable('grino',
|
||||
sources: [
|
||||
'src/main.cpp'
|
||||
|
@ -105,7 +91,6 @@ executable('grino-tests',
|
|||
'tests/main.cpp',
|
||||
'tests/Lexer.cpp',
|
||||
'tests/Parser.cpp',
|
||||
'tests/StaticPass.cpp',
|
||||
],
|
||||
dependencies: [
|
||||
grino_dep,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "Program.hpp"
|
||||
#include "Module.hpp"
|
||||
#include "SymTable.hpp"
|
||||
#include "opcodes.hpp"
|
||||
#include "src/opcodes.hpp"
|
||||
#include "StaticFunction.hpp"
|
||||
|
||||
namespace grino
|
||||
|
@ -246,11 +246,6 @@ namespace grino
|
|||
}
|
||||
}
|
||||
|
||||
bool Compiler::has_static_func(std::string name) const
|
||||
{
|
||||
return m_statics.find(name) != std::end(m_statics);
|
||||
}
|
||||
|
||||
void Compiler::add_static_func(std::string const& name,
|
||||
std::shared_ptr<StaticFunction> fun)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "commons.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "mutils.hpp"
|
||||
#include "src/mutils.hpp"
|
||||
#include "Addr.hpp"
|
||||
|
||||
namespace grino
|
||||
|
@ -27,14 +27,6 @@ namespace grino
|
|||
Program& program,
|
||||
SymTable& sym);
|
||||
|
||||
std::shared_ptr<StaticFunction>
|
||||
static_func(std::string name) const {
|
||||
return m_statics.at(name);
|
||||
}
|
||||
|
||||
|
||||
bool has_static_func(std::string name) const;
|
||||
|
||||
void add_static_func(std::string const& name,
|
||||
std::shared_ptr<StaticFunction> fun);
|
||||
|
||||
|
|
|
@ -51,8 +51,4 @@ namespace grino
|
|||
m_env[addr] = value;
|
||||
}
|
||||
|
||||
void Function::set_prototype(std::shared_ptr<Prototype> prototype)
|
||||
{
|
||||
m_prototype = prototype;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define grino_FUNCTION_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "Prototype.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
@ -20,7 +19,6 @@ namespace grino
|
|||
explicit Function(std::shared_ptr<Program> prog, size_t base_addr);
|
||||
virtual ~Function();
|
||||
|
||||
std::shared_ptr<Prototype> prototype() const { return m_prototype; }
|
||||
size_t base_addr() const { return m_base_addr; }
|
||||
|
||||
bool is_native() const;
|
||||
|
@ -31,14 +29,11 @@ namespace grino
|
|||
std::shared_ptr<Value> env(size_t addr) const;
|
||||
void set_env(size_t addr, std::shared_ptr<Value> value);
|
||||
|
||||
void set_prototype(std::shared_ptr<Prototype> prototype);
|
||||
|
||||
private:
|
||||
native_t m_native;
|
||||
std::shared_ptr<Program> m_prog;
|
||||
std::unordered_map<size_t, std::shared_ptr<Value>> m_env;
|
||||
size_t m_base_addr = 0;
|
||||
std::shared_ptr<Prototype> m_prototype;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "Lexer.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "src/Node.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Loader.hpp"
|
||||
#include "Function.hpp"
|
||||
#include "src/config.in.hpp"
|
||||
#include <dlfcn.h>
|
||||
#include "Lexer.hpp"
|
||||
#include "Parser.hpp"
|
||||
|
@ -43,11 +44,6 @@ namespace grino
|
|||
return deps;
|
||||
}
|
||||
|
||||
void Loader::add_lib(std::filesystem::path path)
|
||||
{
|
||||
m_libs.push_back(path);
|
||||
}
|
||||
|
||||
void Loader::load_libraries()
|
||||
{
|
||||
for (auto entry: std::filesystem::directory_iterator(GRINO_LIBDIR))
|
||||
|
@ -58,15 +54,6 @@ namespace grino
|
|||
load_library(entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto path: m_libs)
|
||||
{
|
||||
if (path.has_extension()
|
||||
&& path.extension() == ".so")
|
||||
{
|
||||
load_library(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Loader::load_library(std::filesystem::path path)
|
||||
|
@ -74,7 +61,6 @@ namespace grino
|
|||
void* handle = dlopen(path.string().c_str(), RTLD_NOW);
|
||||
typedef void(*libfun)(Loader&);
|
||||
libfun f = (libfun) dlsym(handle, "lib");
|
||||
assert(f);
|
||||
|
||||
f(*this);
|
||||
}
|
||||
|
@ -102,23 +88,8 @@ namespace grino
|
|||
m_sym_table.declare_object(loc, name, addr, 0);
|
||||
}
|
||||
|
||||
void Loader::add_native(std::string const& name,
|
||||
native_t native,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
void Loader::add_static(std::string const& name, static_fun_t fun)
|
||||
{
|
||||
size_t addr = m_vm.heap_size();
|
||||
grino::Loc loc {"natives/" + name, 0};
|
||||
auto val = grino::Value::make_native_function(loc, native);
|
||||
val->as_function()->set_prototype(prototype);
|
||||
m_vm.set_heap(addr, val);
|
||||
m_sym_table.declare_function(loc, name, addr, 0, prototype);
|
||||
}
|
||||
|
||||
void Loader::add_static(std::string const& name,
|
||||
static_fun_t fun,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
{
|
||||
auto fn = std::make_shared<StaticFunction>(fun, prototype);
|
||||
m_compiler.add_static_func(name, fn);
|
||||
m_compiler.add_static_func(name, std::make_shared<StaticFunction>(fun));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,27 +20,17 @@ namespace grino
|
|||
std::vector<std::filesystem::path>
|
||||
dependencies(std::shared_ptr<Node> node);
|
||||
|
||||
void add_lib(std::filesystem::path path);
|
||||
|
||||
void load_libraries();
|
||||
void load_library(std::filesystem::path path);
|
||||
|
||||
std::shared_ptr<Module> add_module(std::string const& name);
|
||||
void add_native(std::string const& name, native_t native);
|
||||
|
||||
void add_native(std::string const& name,
|
||||
native_t native,
|
||||
std::shared_ptr<Prototype> prototype);
|
||||
|
||||
void add_static(std::string const& name,
|
||||
static_fun_t fun,
|
||||
std::shared_ptr<Prototype> prototype);
|
||||
void add_static(std::string const& name, static_fun_t fun);
|
||||
|
||||
private:
|
||||
VM& m_vm;
|
||||
Compiler& m_compiler;
|
||||
SymTable& m_sym_table;
|
||||
std::vector<std::filesystem::path> m_libs;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace grino
|
|||
class Loc
|
||||
{
|
||||
public:
|
||||
explicit Loc(std::filesystem::path path, int line=0);
|
||||
explicit Loc(std::filesystem::path path, int line);
|
||||
virtual ~Loc();
|
||||
|
||||
std::filesystem::path path() const { return m_path; }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define grino_LOGGER_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "mutils.hpp"
|
||||
#include "src/mutils.hpp"
|
||||
#include "Loc.hpp"
|
||||
|
||||
#define LOG_TYPE(G) \
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "Lexer.hpp"
|
||||
#include "Parser.hpp"
|
||||
#include "Compiler.hpp"
|
||||
#include "StaticPass.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
@ -45,9 +44,6 @@ namespace grino
|
|||
m_loader = std::make_shared<Loader>(*m_vm, *m_compiler, *m_sym_table);
|
||||
m_loader->load_libraries();
|
||||
|
||||
StaticPass static_pass {m_logger, *m_compiler, *m_sym_table};
|
||||
static_pass.check(ast);
|
||||
|
||||
m_compiler->compile(ast, *m_program, *m_sym_table);
|
||||
|
||||
m_vm->run();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "Parser.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "mutils.hpp"
|
||||
#include "src/Node.hpp"
|
||||
#include "src/mutils.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
@ -118,6 +118,7 @@ namespace grino
|
|||
|
||||
std::shared_ptr<Node> Parser::parse_expr()
|
||||
{
|
||||
|
||||
if (type_is({NODE_IDENT, NODE_NS}))
|
||||
{
|
||||
return parse_ns();
|
||||
|
@ -334,17 +335,7 @@ namespace grino
|
|||
consume(NODE_DECL);
|
||||
consume(NODE_IMPORT);
|
||||
auto ident = consume(NODE_IDENT);
|
||||
std::shared_ptr<Node> val;
|
||||
|
||||
if (type_is(NODE_STRING))
|
||||
{
|
||||
val = consume(NODE_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = make_node(NODE_STRING, "'" + ident->repr() + "'");
|
||||
}
|
||||
|
||||
auto val = consume(NODE_STRING);
|
||||
consume(NODE_CPAR);
|
||||
|
||||
auto node = make_node(NODE_VARDECL);
|
||||
|
@ -356,4 +347,5 @@ namespace grino
|
|||
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "commons.hpp"
|
||||
#include "Lexer.hpp"
|
||||
#include "mutils.hpp"
|
||||
#include "src/mutils.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "Program.hpp"
|
||||
#include "opcodes.hpp"
|
||||
#include "src/opcodes.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
#include "Prototype.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
/*explicit*/ Prototype::Prototype(std::vector<TypeSlot> const& types)
|
||||
: m_types { types }
|
||||
{
|
||||
}
|
||||
|
||||
/*explicit*/ Prototype::Prototype(std::vector<TypeType> const& params,
|
||||
TypeType ret)
|
||||
{
|
||||
for (auto ty: params)
|
||||
{
|
||||
m_types.push_back(TypeSlot {
|
||||
HINT_CAT_PARAM,
|
||||
ty,
|
||||
HINT_NONE
|
||||
});
|
||||
}
|
||||
|
||||
m_types.push_back(TypeSlot {
|
||||
HINT_CAT_RETURN,
|
||||
ret,
|
||||
HINT_NONE
|
||||
});
|
||||
}
|
||||
|
||||
/*virtual*/ Prototype::~Prototype()
|
||||
{
|
||||
}
|
||||
|
||||
TypeType Prototype::type(size_t index) const
|
||||
{
|
||||
assert(index < size());
|
||||
return m_types[index].type;
|
||||
}
|
||||
|
||||
HintType Prototype::hint(size_t index) const
|
||||
{
|
||||
assert(index < size());
|
||||
return m_types[index].hint;
|
||||
}
|
||||
|
||||
HintCatType Prototype::category(size_t index) const
|
||||
{
|
||||
assert(index < size());
|
||||
return m_types[index].category;
|
||||
}
|
||||
|
||||
std::vector<TypeSlot> Prototype::filter(HintCatType category) const
|
||||
{
|
||||
std::vector<TypeSlot> result;
|
||||
|
||||
for (size_t i=0; i<size(); i++)
|
||||
{
|
||||
if (m_types[i].category == category)
|
||||
{
|
||||
result.push_back(m_types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
#ifndef grino_PROTOTYPE_HPP
|
||||
#define grino_PROTOTYPE_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
#define HINTS(G) \
|
||||
G(HINT_NONE), \
|
||||
G(HINT_ANY), \
|
||||
G(HINT_SAME),
|
||||
|
||||
#define HINTS_CATEGORY(G) \
|
||||
G(HINT_CAT_PARAM), \
|
||||
G(HINT_CAT_VARIADIC_PARAM), \
|
||||
G(HINT_CAT_RETURN)
|
||||
|
||||
namespace grino
|
||||
{
|
||||
GRINO_ENUM(Hint, HINTS);
|
||||
GRINO_ENUM(HintCat, HINTS_CATEGORY);
|
||||
|
||||
struct TypeSlot {
|
||||
HintCatType category;
|
||||
TypeType type;
|
||||
HintType hint = HINT_NONE;
|
||||
};
|
||||
|
||||
class Prototype
|
||||
{
|
||||
public:
|
||||
explicit Prototype(std::vector<TypeSlot> const& types);
|
||||
explicit Prototype(std::vector<TypeType> const& params, TypeType ret);
|
||||
virtual ~Prototype();
|
||||
|
||||
size_t size() const { return m_types.size(); }
|
||||
|
||||
TypeType type(size_t index) const;
|
||||
HintType hint(size_t index) const;
|
||||
HintCatType category(size_t index) const;
|
||||
|
||||
std::vector<TypeSlot> filter(HintCatType category) const;
|
||||
|
||||
private:
|
||||
std::vector<TypeSlot> m_types;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,10 +3,8 @@
|
|||
|
||||
namespace grino
|
||||
{
|
||||
/*explicit*/ StaticFunction::StaticFunction(static_fun_t fun,
|
||||
std::shared_ptr<Prototype> proto)
|
||||
/*explicit*/ StaticFunction::StaticFunction(static_fun_t fun)
|
||||
: m_fun { fun }
|
||||
, m_prototype { proto }
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "Node.hpp"
|
||||
#include "Program.hpp"
|
||||
#include "SymTable.hpp"
|
||||
#include "Prototype.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
@ -19,16 +18,13 @@ namespace grino
|
|||
class StaticFunction
|
||||
{
|
||||
public:
|
||||
explicit StaticFunction(static_fun_t fun, std::shared_ptr<Prototype> proto);
|
||||
explicit StaticFunction(static_fun_t fun);
|
||||
virtual ~StaticFunction();
|
||||
|
||||
std::shared_ptr<Prototype> prototype() const { return m_prototype; }
|
||||
|
||||
void call(Compiler& compiler, node_t node, prog_t prog, sym_t sym);
|
||||
|
||||
private:
|
||||
static_fun_t m_fun;
|
||||
std::shared_ptr<Prototype> m_prototype;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
#include "StaticPass.hpp"
|
||||
#include "src/Prototype.hpp"
|
||||
#include "StaticFunction.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
/*explicit*/ StaticPass::StaticPass(Logger& logger,
|
||||
Compiler& compiler,
|
||||
SymTable& sym)
|
||||
: m_logger { logger }
|
||||
, m_compiler { compiler }
|
||||
, m_sym { sym }
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/ StaticPass::~StaticPass()
|
||||
{
|
||||
}
|
||||
|
||||
TypeType StaticPass::check(std::shared_ptr<Node> node)
|
||||
{
|
||||
switch (node->type())
|
||||
{
|
||||
case NODE_ARRAY:
|
||||
case NODE_BLOCK: {
|
||||
for (size_t i=0; i<node->size(); i++)
|
||||
{
|
||||
check(node->child(i).lock());
|
||||
}
|
||||
|
||||
return TYPE_NIL;
|
||||
} break;
|
||||
|
||||
case NODE_MODULE: {
|
||||
for (size_t i=0; i<node->size(); i++)
|
||||
{
|
||||
check(node->child(i).lock());
|
||||
}
|
||||
|
||||
return TYPE_MODULE;
|
||||
} break;
|
||||
|
||||
case NODE_INT: {
|
||||
return TYPE_INT;
|
||||
} break;
|
||||
|
||||
case NODE_FLOAT: {
|
||||
return TYPE_FLOAT;
|
||||
} break;
|
||||
|
||||
case NODE_BOOL: {
|
||||
return TYPE_BOOL;
|
||||
} break;
|
||||
|
||||
case NODE_STRING: {
|
||||
return TYPE_STRING;
|
||||
} break;
|
||||
|
||||
case NODE_IDENT: {
|
||||
std::string ident = node->repr();
|
||||
return m_types[ident];
|
||||
} break;
|
||||
|
||||
case NODE_LAMBDA: {
|
||||
return TYPE_FUNCTION;
|
||||
} break;
|
||||
|
||||
case NODE_IMPORT: {
|
||||
return TYPE_MODULE;
|
||||
} break;
|
||||
|
||||
case NODE_VARDECL: {
|
||||
std::string ident = node->child(0).lock()->repr();
|
||||
auto res = check(node->child(1).lock());
|
||||
m_types[ident] = res;
|
||||
return res;
|
||||
} break;
|
||||
|
||||
case NODE_FUNCALL: {
|
||||
std::string ident = node->child(0).lock()->repr();
|
||||
std::shared_ptr<Prototype> proto;
|
||||
auto entry = m_sym.find_no_scope(ident);
|
||||
|
||||
if (entry && entry->prototype)
|
||||
{
|
||||
proto = entry->prototype;
|
||||
}
|
||||
else if (m_compiler.has_static_func(ident))
|
||||
{
|
||||
proto = m_compiler.static_func(ident)->prototype();
|
||||
}
|
||||
|
||||
if (proto)
|
||||
{
|
||||
auto params = proto->filter(HINT_CAT_PARAM);
|
||||
auto rets = proto->filter(HINT_CAT_RETURN);
|
||||
|
||||
auto var_params = proto->filter(HINT_CAT_VARIADIC_PARAM);
|
||||
|
||||
if (!var_params.empty())
|
||||
{
|
||||
TypeType ty = var_params.back().type;
|
||||
|
||||
for (size_t i=1; i<node->size(); i++)
|
||||
{
|
||||
auto param_ty = check(node->child(i).lock());
|
||||
|
||||
if (param_ty != ty
|
||||
&& var_params.back().hint != HINT_ANY)
|
||||
{
|
||||
error(ty, param_ty, node->loc());
|
||||
}
|
||||
}
|
||||
|
||||
return rets[0].type;
|
||||
}
|
||||
|
||||
if (params.size() != node->size() - 1)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "arity mismatch, expected '"
|
||||
<< params.size()
|
||||
<< "' got '"
|
||||
<< (node->size() - 1)
|
||||
<< "'";
|
||||
std::cout << node->string() << std::endl;
|
||||
m_logger
|
||||
.log<static_error>(LOG_ERROR, node->loc(), ss.str());
|
||||
}
|
||||
|
||||
std::vector<TypeType> ty;
|
||||
|
||||
for (size_t i=1; i<node->size(); i++)
|
||||
{
|
||||
TypeType param_ty = check(node->child(i).lock());
|
||||
ty.push_back(param_ty);
|
||||
|
||||
if (proto->hint(i - 1) == HINT_ANY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool same_err = (i > 1 && proto->hint(i - 1) == HINT_SAME)
|
||||
&& ty.back() != ty.at(ty.size() - 2);
|
||||
|
||||
bool normal_err = proto->hint(i - 1) == HINT_NONE
|
||||
&& param_ty != proto->type(i - 1);
|
||||
|
||||
if (same_err || normal_err)
|
||||
{
|
||||
error(proto->type(i - 1), param_ty, node->loc());
|
||||
}
|
||||
}
|
||||
|
||||
assert(rets.size() > 0);
|
||||
return rets[0].type;
|
||||
}
|
||||
|
||||
return TYPE_NIL;
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::cerr << "cannot check node "
|
||||
<< NodeTypeStr[node->type()] << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
void StaticPass::error(TypeType lhs, TypeType rhs, Loc const& loc)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "type mismatch, expected '"
|
||||
<< GRINO_TRIM(TypeTypeStr[lhs], "TYPE_")
|
||||
<< "', got '"
|
||||
<< GRINO_TRIM(TypeTypeStr[rhs], "TYPE_")
|
||||
<< "'";
|
||||
|
||||
m_logger
|
||||
.log<static_error>(LOG_ERROR, loc, ss.str());
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef grino_STATICPASS_HPP
|
||||
#define grino_STATICPASS_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "SymTable.hpp"
|
||||
#include "Compiler.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
GRINO_ERROR(static_error);
|
||||
|
||||
class StaticPass
|
||||
{
|
||||
public:
|
||||
explicit StaticPass(Logger& logger, Compiler& compiler, SymTable& sym);
|
||||
virtual ~StaticPass();
|
||||
|
||||
TypeType check(std::shared_ptr<Node> node);
|
||||
|
||||
private:
|
||||
Logger& m_logger;
|
||||
Compiler& m_compiler;
|
||||
SymTable& m_sym;
|
||||
std::unordered_map<std::string, TypeType> m_types;
|
||||
|
||||
void error(TypeType lhs, TypeType rhs, Loc const& loc);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -27,6 +27,7 @@ namespace grino
|
|||
entry.name = name;
|
||||
entry.is_object = false;
|
||||
entry.scope = scope;
|
||||
|
||||
m_entries.push_back(entry);
|
||||
}
|
||||
|
||||
|
@ -39,16 +40,6 @@ namespace grino
|
|||
m_entries.back().is_object = true;
|
||||
}
|
||||
|
||||
void SymTable::declare_function(Loc const& loc,
|
||||
std::string const& name,
|
||||
size_t addr,
|
||||
size_t scope,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
{
|
||||
declare_object(loc, name, addr, scope);
|
||||
m_entries.back().prototype = prototype;
|
||||
}
|
||||
|
||||
std::optional<SymEntry> SymTable::find(std::string const& name, size_t scope)
|
||||
{
|
||||
std::optional<SymEntry> entry;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "commons.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "types.hpp"
|
||||
#include "Prototype.hpp"
|
||||
|
||||
namespace grino
|
||||
{
|
||||
|
@ -13,7 +11,6 @@ namespace grino
|
|||
bool is_object; /* object are on the heap instead of the stack */
|
||||
size_t addr; /* address on the heap if object, local address otherwise */
|
||||
size_t scope;
|
||||
std::shared_ptr<Prototype> prototype; /* only used by functions */
|
||||
};
|
||||
|
||||
GRINO_ERROR(symbolic_error);
|
||||
|
@ -30,9 +27,6 @@ namespace grino
|
|||
void declare_object(Loc const& loc, std::string const& name, size_t addr,
|
||||
size_t scope);
|
||||
|
||||
void declare_function(Loc const& loc, std::string const& name, size_t addr,
|
||||
size_t scope, std::shared_ptr<Prototype> prototype);
|
||||
|
||||
std::optional<SymEntry> find(std::string const& name, size_t scope);
|
||||
std::optional<SymEntry> find_no_scope(std::string const& name);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "VM.hpp"
|
||||
#include "Value.hpp"
|
||||
#include "src/Value.hpp"
|
||||
#include "Module.hpp"
|
||||
#include "opcodes.hpp"
|
||||
#include "src/opcodes.hpp"
|
||||
#include <optional>
|
||||
|
||||
namespace grino
|
||||
|
@ -212,6 +212,7 @@ namespace grino
|
|||
{
|
||||
if (fun)
|
||||
{
|
||||
std::cout << "store INIT" << std::endl;
|
||||
fun->set_env(itr->first,
|
||||
Value::make_copy(itr->second->loc(),
|
||||
itr->second));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "Value.hpp"
|
||||
#include "Program.hpp"
|
||||
#include "types.hpp"
|
||||
#include "src/types.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
namespace grino
|
||||
|
@ -37,28 +37,23 @@ namespace grino
|
|||
}
|
||||
|
||||
/*static*/
|
||||
std::shared_ptr<Value>
|
||||
Value::make_native_function(Loc const& loc,
|
||||
native_t val,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
std::shared_ptr<Value> Value::make_native_function(Loc const& loc,
|
||||
native_t val)
|
||||
{
|
||||
auto value = std::make_shared<Value>(loc);
|
||||
value->m_type = TYPE_FUNCTION;
|
||||
value->m_function_val = std::make_shared<Function>(val);
|
||||
value->m_function_val->set_prototype(prototype);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*static*/ std::shared_ptr<Value>
|
||||
Value::make_function(Loc const& loc,
|
||||
std::shared_ptr<Program> val,
|
||||
size_t base_addr,
|
||||
std::shared_ptr<Prototype> prototype)
|
||||
size_t base_addr)
|
||||
{
|
||||
auto value = std::make_shared<Value>(loc);
|
||||
value->m_type = TYPE_FUNCTION;
|
||||
value->m_function_val = std::make_shared<Function>(val, base_addr);
|
||||
value->m_function_val->set_prototype(prototype);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -135,16 +130,6 @@ namespace grino
|
|||
return value;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
std::shared_ptr<Value> Value::make_user_data(Loc const& loc,
|
||||
void* val)
|
||||
{
|
||||
auto value = std::make_shared<Value>(loc);
|
||||
value->m_type = TYPE_PROGRAM;
|
||||
value->m_user_data_val = val;
|
||||
return value;
|
||||
}
|
||||
|
||||
std::shared_ptr<Program> Value::as_program() const
|
||||
{
|
||||
return m_program_val;
|
||||
|
@ -167,7 +152,6 @@ namespace grino
|
|||
case TYPE_FUNCTION: return "<function>";
|
||||
case TYPE_REF: return "&" + std::to_string(*m_ref_val);
|
||||
case TYPE_PROGRAM: return "<program>";
|
||||
case TYPE_USER_DATA: return "<user data>";
|
||||
case TYPE_MODULE: return "<module " + m_module_val->name() + ">";
|
||||
case TYPE_ARRAY: {
|
||||
std::stringstream ss;
|
||||
|
@ -204,7 +188,6 @@ namespace grino
|
|||
case TYPE_REF: return *m_ref_val == *other.m_ref_val;
|
||||
case TYPE_PROGRAM: return false;
|
||||
case TYPE_MODULE: return false;
|
||||
case TYPE_USER_DATA: return m_user_data_val == other.m_user_data_val;
|
||||
|
||||
default:
|
||||
std::cerr << "cannot compare equality with value "
|
||||
|
|
|
@ -20,17 +20,11 @@ namespace grino
|
|||
static std::shared_ptr<Value> make_bool(Loc const& loc, bool val);
|
||||
static std::shared_ptr<Value> make_int(Loc const& loc, int val);
|
||||
static std::shared_ptr<Value> make_float(Loc const& loc, float val);
|
||||
|
||||
static std::shared_ptr<Value>
|
||||
make_native_function(Loc const& loc,
|
||||
native_t val,
|
||||
std::shared_ptr<Prototype> prototype=nullptr);
|
||||
|
||||
static std::shared_ptr<Value>
|
||||
make_function(Loc const& loc,
|
||||
std::shared_ptr<Program> val,
|
||||
size_t base_addr,
|
||||
std::shared_ptr<Prototype> prototype=nullptr);
|
||||
static std::shared_ptr<Value> make_native_function(Loc const& loc,
|
||||
native_t val);
|
||||
static std::shared_ptr<Value> make_function(Loc const& loc,
|
||||
std::shared_ptr<Program> val,
|
||||
size_t base_addr);
|
||||
|
||||
static std::shared_ptr<Value> make_ref(Loc const& loc,
|
||||
size_t val);
|
||||
|
@ -50,9 +44,6 @@ namespace grino
|
|||
static std::shared_ptr<Value> make_module(Loc const& loc,
|
||||
std::shared_ptr<Module> val);
|
||||
|
||||
static std::shared_ptr<Value> make_user_data(Loc const& loc,
|
||||
void* val);
|
||||
|
||||
explicit Value(Loc const& loc);
|
||||
virtual ~Value() = default;
|
||||
|
||||
|
@ -68,7 +59,6 @@ namespace grino
|
|||
val_array_t const& as_array() const { return *m_array_val; }
|
||||
std::string const& as_string() const { return *m_string_val; }
|
||||
std::shared_ptr<Module> as_module() const;
|
||||
void* as_user_data() const { return m_user_data_val; }
|
||||
|
||||
std::string string() const;
|
||||
bool equals(Value const& other) const;
|
||||
|
@ -85,7 +75,6 @@ namespace grino
|
|||
std::optional<val_array_t> m_array_val;
|
||||
std::optional<std::string> m_string_val;
|
||||
std::shared_ptr<Module> m_module_val;
|
||||
void* m_user_data_val = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
111
src/main.cpp
111
src/main.cpp
|
@ -8,14 +8,12 @@
|
|||
#include "Program.hpp"
|
||||
#include "VM.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "SymTable.hpp"
|
||||
#include "src/SymTable.hpp"
|
||||
#include "Loader.hpp"
|
||||
#include "Addr.hpp"
|
||||
#include "StaticPass.hpp"
|
||||
|
||||
void run(char* const source_name,
|
||||
std::vector<std::filesystem::path> const& libs,
|
||||
bool debug_mode)
|
||||
|
||||
void run(char* const source_name, bool debug_mode)
|
||||
{
|
||||
std::string source;
|
||||
{
|
||||
|
@ -53,16 +51,12 @@ void run(char* const source_name,
|
|||
grino::Compiler compiler {logger, addr};
|
||||
|
||||
grino::Loader loader {vm, compiler, sym_table};
|
||||
|
||||
for (auto p: libs)
|
||||
{
|
||||
loader.add_lib(p);
|
||||
}
|
||||
|
||||
loader.load_libraries();
|
||||
|
||||
grino::StaticPass static_pass {logger, compiler, sym_table};
|
||||
static_pass.check(ast);
|
||||
for (auto dep: loader.dependencies(ast))
|
||||
{
|
||||
// TODO: import them
|
||||
}
|
||||
|
||||
compiler.compile(ast, program, sym_table);
|
||||
|
||||
|
@ -84,80 +78,55 @@ void run(char* const source_name,
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
bool debug_mode = false;
|
||||
std::vector<std::filesystem::path> libs;
|
||||
|
||||
while (true)
|
||||
static struct option options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int option_index = 0;
|
||||
|
||||
int c = getopt_long(argc, argv, "hvd", options, &option_index);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
static struct option options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{"lib", no_argument, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
case 'h': {
|
||||
std::cout << "Usage: grino [OPTION]... source" << std::endl;
|
||||
std::cout << "OPTIONS:" << std::endl;
|
||||
std::cout << "\t" << "-d, --debug, "
|
||||
<< "activate debug mode" << std::endl;
|
||||
|
||||
int option_index = 0;
|
||||
std::cout << "\t" << "-h, --help, "
|
||||
<< "show this message" << std::endl;
|
||||
std::cout << "\t" << "-v, --version, "
|
||||
<< "show grino version" << std::endl;
|
||||
exit(0);
|
||||
} break;
|
||||
|
||||
int c = getopt_long(argc, argv, "hvdl:", options, &option_index);
|
||||
case 'v': {
|
||||
std::cout << "grino version: " << GRINO_VERSION << std::endl;
|
||||
std::cout << "License: " << "GPLv3 or later (see LICENSE)"<< std::endl;
|
||||
exit(0);
|
||||
} break;
|
||||
|
||||
if (c == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'h': {
|
||||
std::cout << "Usage: grino [OPTION]... source" << std::endl;
|
||||
std::cout << "OPTIONS:" << std::endl;
|
||||
std::cout << "\t" << "-d, --debug, "
|
||||
<< "activate debug mode" << std::endl;
|
||||
|
||||
std::cout << "\t" << "-h, --help, "
|
||||
<< "show this message" << std::endl;
|
||||
std::cout << "\t" << "-v, --version, "
|
||||
<< "show grino version" << std::endl;
|
||||
exit(0);
|
||||
} break;
|
||||
|
||||
case 'v': {
|
||||
std::cout << "grino version: " << GRINO_VERSION << std::endl;
|
||||
std::cout << "License: " << "GPLv3 or later (see LICENSE)"<< std::endl;
|
||||
exit(0);
|
||||
} break;
|
||||
|
||||
case 'd': {
|
||||
debug_mode = true;
|
||||
} break;
|
||||
|
||||
case 'l': {
|
||||
auto path = std::filesystem::path("/usr/lib")
|
||||
/ std::filesystem::path("lib" + std::string(optarg) + ".so");
|
||||
|
||||
if (std::filesystem::is_regular_file(path))
|
||||
{
|
||||
libs.push_back(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "W: cannot find lib " << path << std::endl;
|
||||
}
|
||||
} break;
|
||||
|
||||
}
|
||||
case 'd': {
|
||||
debug_mode = true;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
if (debug_mode)
|
||||
{
|
||||
run(argv[optind], libs, debug_mode);
|
||||
run(argv[optind], debug_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
run(argv[optind], libs, debug_mode);
|
||||
run(argv[optind], debug_mode);
|
||||
}
|
||||
catch(std::exception const& err)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define grino_OPCODES_HPP
|
||||
|
||||
#include "commons.hpp"
|
||||
#include "mutils.hpp"
|
||||
#include "src/mutils.hpp"
|
||||
|
||||
#define OPCODES(G) \
|
||||
G(OPCODE_LOAD_CONST), \
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
G(TYPE_FLOAT), \
|
||||
G(TYPE_ARRAY), \
|
||||
G(TYPE_STRING), \
|
||||
G(TYPE_MODULE), \
|
||||
G(TYPE_USER_DATA)
|
||||
G(TYPE_MODULE)
|
||||
|
||||
|
||||
namespace grino
|
||||
|
|
|
@ -116,10 +116,4 @@ TEST_CASE_METHOD(ParserTest, "Parser_import")
|
|||
|
||||
test_parse("MODULE(VARDECL(IDENT[bim],IMPORT(STRING['hello'])))",
|
||||
"($ @bim 'hello')");
|
||||
|
||||
test_parse("MODULE(VARDECL(IDENT[bim],IMPORT(STRING['bim'])))",
|
||||
"($ @ bim )");
|
||||
|
||||
test_parse("MODULE(VARDECL(IDENT[hello_world],IMPORT(STRING['hello_world'])))",
|
||||
" ( $ @ hello_world )");
|
||||
}
|
||||
|
|
|
@ -1,379 +0,0 @@
|
|||
#include <catch2/catch.hpp>
|
||||
#include <memory>
|
||||
#include "../src/StaticPass.hpp"
|
||||
#include "../src/Logger.hpp"
|
||||
#include "../src/Lexer.hpp"
|
||||
#include "../src/Parser.hpp"
|
||||
#include "src/Prototype.hpp"
|
||||
#include "src/SymTable.hpp"
|
||||
#include "src/Loader.hpp"
|
||||
#include "src/types.hpp"
|
||||
|
||||
class StaticPassTest
|
||||
{
|
||||
public:
|
||||
explicit StaticPassTest() {}
|
||||
virtual ~StaticPassTest() {}
|
||||
|
||||
void test_ok(std::string const& source,
|
||||
std::function<void(grino::Loader&)> init)
|
||||
{
|
||||
grino::Logger logger;
|
||||
grino::Lexer lexer {logger, "tests/parser"};
|
||||
grino::Parser parser {logger, lexer};
|
||||
grino::SymTable sym {logger};
|
||||
grino::Addr addr;
|
||||
grino::Compiler compiler {logger, addr};
|
||||
grino::StaticPass pass {logger, compiler, sym};
|
||||
grino::Program prog;
|
||||
grino::VM vm {logger, prog};
|
||||
grino::Loader loader {vm, compiler, sym};
|
||||
|
||||
init(loader);
|
||||
|
||||
auto root = parser.parse(source);
|
||||
|
||||
INFO("source: " << source);
|
||||
REQUIRE_NOTHROW(pass.check(root));
|
||||
}
|
||||
|
||||
void test_ko(std::string const& source,
|
||||
std::function<void(grino::Loader&)> init)
|
||||
{
|
||||
grino::Logger logger;
|
||||
grino::Lexer lexer {logger, "tests/parser"};
|
||||
grino::Parser parser {logger, lexer};
|
||||
grino::SymTable sym {logger};
|
||||
grino::Addr addr;
|
||||
grino::Compiler compiler {logger, addr};
|
||||
grino::StaticPass pass {logger, compiler, sym};
|
||||
grino::Program prog;
|
||||
grino::VM vm {logger, prog};
|
||||
grino::Loader loader {vm, compiler, sym};
|
||||
|
||||
init(loader);
|
||||
|
||||
auto root = parser.parse(source);
|
||||
|
||||
INFO("source: " << source);
|
||||
REQUIRE_THROWS_AS(pass.check(root), grino::static_error);
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(StaticPassTest, "StaticPass_normal")
|
||||
{
|
||||
grino::TypeSlot ty_int_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_int_ret {
|
||||
grino::HintCatType::HINT_CAT_RETURN,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
auto slots = std::vector<grino::TypeSlot> {ty_int_param,
|
||||
ty_int_param,
|
||||
ty_int_ret};
|
||||
|
||||
auto proto = std::make_shared<grino::Prototype>(slots);
|
||||
|
||||
test_ok("(+ 45 1)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ 45.2 1)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ (+ 45.2 1) 3)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(StaticPassTest, "StaticPass_hint_any")
|
||||
{
|
||||
grino::TypeSlot ty_int_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_any_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_INT,
|
||||
grino::HINT_ANY
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_int_ret {
|
||||
grino::HintCatType::HINT_CAT_RETURN,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
auto slots = std::vector<grino::TypeSlot> {ty_int_param,
|
||||
ty_any_param,
|
||||
ty_int_ret};
|
||||
|
||||
auto proto = std::make_shared<grino::Prototype>(slots);
|
||||
|
||||
test_ok("(+ 45 1)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ 45.2 1)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45 1.3)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ (+ 2 1) 3)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ (+ 2 1) 3.2)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ 7.14 (+ 2 1))", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(StaticPassTest, "StaticPass_hint_same")
|
||||
{
|
||||
grino::TypeSlot ty_any_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_ANY
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_same_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_int_ret {
|
||||
grino::HintCatType::HINT_CAT_RETURN,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
auto slots = std::vector<grino::TypeSlot> {ty_any_param,
|
||||
ty_same_param,
|
||||
ty_int_ret};
|
||||
|
||||
auto proto = std::make_shared<grino::Prototype>(slots);
|
||||
|
||||
test_ok("(+ 45 1)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45.2 1.3)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
|
||||
test_ok("(+ false true)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ false 3.2)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ 3.7 9)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(StaticPassTest, "StaticPass_int_variadic")
|
||||
{
|
||||
grino::TypeSlot ty_same_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_var_param {
|
||||
grino::HintCatType::HINT_CAT_VARIADIC_PARAM,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_int_ret {
|
||||
grino::HintCatType::HINT_CAT_RETURN,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
auto slots = std::vector<grino::TypeSlot> {
|
||||
ty_same_param,
|
||||
ty_var_param,
|
||||
ty_int_ret
|
||||
};
|
||||
|
||||
auto proto = std::make_shared<grino::Prototype>(slots);
|
||||
|
||||
test_ok("(+ 45 1 3 2 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ko("(+ 45 3.12 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(StaticPassTest, "StaticPass_any_variadic")
|
||||
{
|
||||
grino::TypeSlot ty_same_param {
|
||||
grino::HintCatType::HINT_CAT_PARAM,
|
||||
grino::TYPE_NIL,
|
||||
grino::HINT_SAME
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_var_param {
|
||||
grino::HintCatType::HINT_CAT_VARIADIC_PARAM,
|
||||
grino::TYPE_INT,
|
||||
grino::HINT_ANY
|
||||
};
|
||||
|
||||
grino::TypeSlot ty_int_ret {
|
||||
grino::HintCatType::HINT_CAT_RETURN,
|
||||
grino::TYPE_INT
|
||||
};
|
||||
|
||||
auto slots = std::vector<grino::TypeSlot> {
|
||||
ty_same_param,
|
||||
ty_var_param,
|
||||
ty_int_ret
|
||||
};
|
||||
|
||||
auto proto = std::make_shared<grino::Prototype>(slots);
|
||||
|
||||
test_ok("(+ 45 1 3 2 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45 3.12 1 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
|
||||
test_ok("(+ 45 3.12 true 'salut' 7)", [&proto](auto& loader){
|
||||
grino::Loc loc {"tests/static_pass"};
|
||||
loader.add_native("+", [loader, loc](auto args){
|
||||
auto lhs = args[0];
|
||||
auto rhs = args[1];
|
||||
return grino::Value::make_int(loc, lhs->as_int() + rhs->as_int());
|
||||
}, proto);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue