More usage cleansups

This commit is contained in:
Jason Turner 2009-07-18 23:34:08 +00:00
parent 4d4c26bf73
commit 82bd46bb1a
6 changed files with 113 additions and 61 deletions

View File

@ -489,7 +489,7 @@ namespace chaiscript
template<typename T> template<typename T>
void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name) void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name)
{ {
s.add(type_<T>(), name); s.add(user_type<T>(), name);
add_basic_constructors<T>(s, name); add_basic_constructors<T>(s, name);
add_oper_assign<T>(s); add_oper_assign<T>(s);
add_oper_assign_pod<T>(s); add_oper_assign_pod<T>(s);
@ -590,10 +590,10 @@ namespace chaiscript
/** /**
* return true if the Boxed_Value matches the registered type by name * return true if the Boxed_Value matches the registered type by name
*/ */
static bool is_type(const Dispatch_Engine &e, const std::string &type_name, Boxed_Value r) static bool is_type(const Dispatch_Engine &e, const std::string &user_typename, Boxed_Value r)
{ {
try { try {
return e.get_type(type_name) == r.get_type_info(); return e.get_type(user_typename) == r.get_type_info();
} catch (const std::range_error &) { } catch (const std::range_error &) {
return false; return false;
} }
@ -638,11 +638,11 @@ namespace chaiscript
*/ */
static void bootstrap(Dispatch_Engine &s) static void bootstrap(Dispatch_Engine &s)
{ {
s.add(type_<void>(), "void"); s.add(user_type<void>(), "void");
s.add(type_<bool>(), "bool"); s.add(user_type<bool>(), "bool");
s.add(type_<Boxed_Value>(), "Object"); s.add(user_type<Boxed_Value>(), "Object");
s.add(type_<Boxed_POD_Value>(), "PODObject"); s.add(user_type<Boxed_POD_Value>(), "PODObject");
s.add(type_<Proxy_Function>(), "function"); s.add(user_type<Proxy_Function>(), "function");
add_basic_constructors<bool>(s, "bool"); add_basic_constructors<bool>(s, "bool");
add_oper_assign<std::string>(s); add_oper_assign<std::string>(s);

View File

@ -22,7 +22,7 @@ namespace chaiscript
/** /**
* Input_Range, based on the D concept of ranges. * Input_Range, based on the D concept of ranges.
* \todo Update the Range code to base its capabilities on * \todo Update the Range code to base its capabilities on
* the type_traits of the iterator passed in * the user_typetraits of the iterator passed in
*/ */
template<typename Container> template<typename Container>
struct Input_Range struct Input_Range
@ -76,8 +76,8 @@ namespace chaiscript
template<typename ContainerType> template<typename ContainerType>
void bootstrap_input_range(Dispatch_Engine &system, const std::string &type) void bootstrap_input_range(Dispatch_Engine &system, const std::string &type)
{ {
system.add(type_<Input_Range<ContainerType> >(), type + "_Range"); system.add(user_type<Input_Range<ContainerType> >(), type + "_Range");
system.add(type_<typename ContainerType::iterator>(), type+"_Iterator"); system.add(user_type<typename ContainerType::iterator>(), type+"_Iterator");
system.add(constructor<Input_Range<ContainerType> (ContainerType &)>(), "range"); system.add(constructor<Input_Range<ContainerType> (ContainerType &)>(), "range");
system.add(constructor<Input_Range<ContainerType> (typename ContainerType::iterator)>(), "range"); system.add(constructor<Input_Range<ContainerType> (typename ContainerType::iterator)>(), "range");
@ -86,7 +86,7 @@ namespace chaiscript
system.add(constructor<Input_Range<ContainerType> (const ItrPair &)>(), "range"); system.add(constructor<Input_Range<ContainerType> (const ItrPair &)>(), "range");
system.add(type_<ItrPair>(), type+"_Iterator_Pair"); system.add(user_type<ItrPair>(), type+"_Iterator_Pair");
system.add(fun(&Input_Range<ContainerType>::empty), "empty"); system.add(fun(&Input_Range<ContainerType>::empty), "empty");
system.add(fun(&Input_Range<ContainerType>::pop_front), "pop_front"); system.add(fun(&Input_Range<ContainerType>::pop_front), "pop_front");
@ -259,7 +259,7 @@ namespace chaiscript
template<typename VectorType> template<typename VectorType>
void bootstrap_vector(Dispatch_Engine &system, const std::string &type) void bootstrap_vector(Dispatch_Engine &system, const std::string &type)
{ {
system.add(type_<VectorType>(), type); system.add(user_type<VectorType>(), type);
bootstrap_random_access_container<VectorType>(system, type); bootstrap_random_access_container<VectorType>(system, type);
bootstrap_back_insertion_sequence<VectorType>(system, type); bootstrap_back_insertion_sequence<VectorType>(system, type);
} }
@ -282,7 +282,7 @@ namespace chaiscript
template<typename PairType> template<typename PairType>
void bootstrap_pair(Dispatch_Engine &system, const std::string &type) void bootstrap_pair(Dispatch_Engine &system, const std::string &type)
{ {
system.add(type_<PairType>(), type); system.add(user_type<PairType>(), type);
system.add(fun(&PairType::first), "first"); system.add(fun(&PairType::first), "first");
system.add(fun(&PairType::second), "second"); system.add(fun(&PairType::second), "second");
@ -349,7 +349,7 @@ namespace chaiscript
template<typename MapType> template<typename MapType>
void bootstrap_map(Dispatch_Engine &system, const std::string &type) void bootstrap_map(Dispatch_Engine &system, const std::string &type)
{ {
system.add(type_<MapType>(), type); system.add(user_type<MapType>(), type);
system.add(fun(&MapType::operator[]), "[]"); system.add(fun(&MapType::operator[]), "[]");
bootstrap_unique_sorted_associative_container<MapType>(system, type); bootstrap_unique_sorted_associative_container<MapType>(system, type);
bootstrap_pair_associative_container<MapType>(system, type); bootstrap_pair_associative_container<MapType>(system, type);
@ -362,7 +362,7 @@ namespace chaiscript
template<typename String> template<typename String>
void bootstrap_string(Dispatch_Engine &system, const std::string &type) void bootstrap_string(Dispatch_Engine &system, const std::string &type)
{ {
system.add(type_<String>(), type); system.add(user_type<String>(), type);
add_oper_add<String>(system); add_oper_add<String>(system);
add_oper_add_equals<String>(system); add_oper_add_equals<String>(system);
add_opers_comparison<String>(system); add_opers_comparison<String>(system);

View File

@ -118,14 +118,14 @@ namespace chaiscript
template<typename T> template<typename T>
Type_Info type_(T) Type_Info user_type(T)
{ {
return Get_Type_Info<T>::get(); return Get_Type_Info<T>::get();
} }
template<typename T> template<typename T>
Type_Info type_() Type_Info user_type()
{ {
return Get_Type_Info<T>::get(); return Get_Type_Info<T>::get();
} }

View File

@ -21,6 +21,35 @@ namespace chaiscript
Eval_Engine engine; Eval_Engine engine;
ChaiScript_Parser parser; ChaiScript_Parser parser;
/**
* Evaluates the given string in by parsing it and running the results through the evaluator
*/
Boxed_Value do_eval(const std::string &input, const char *filename = "__EVAL__") {
//debug_print(tokens);
Boxed_Value value;
parser.clear_match_stack();
try {
if (parser.parse(input, filename)) {
//parser.show_match_stack();
value = eval_token<Eval_Engine>(engine, parser.ast());
}
}
catch (const Return_Value &rv) {
value = rv.retval;
}
return value;
}
/**
* Evaluates the given boxed string, used during eval() inside of a script
*/
const Boxed_Value internal_eval(const std::vector<Boxed_Value> &vals) {
return do_eval(boxed_cast<std::string>(vals.at(0)));
}
public: public:
ChaiScript_System() { ChaiScript_System() {
build_eval_system(); build_eval_system();
@ -34,6 +63,7 @@ namespace chaiscript
{ {
engine.add(t, name); engine.add(t, name);
} }
/** /**
* Helper for calling script code as if it were native C++ code * Helper for calling script code as if it were native C++ code
* example: * example:
@ -44,9 +74,18 @@ namespace chaiscript
template<typename FunctionType> template<typename FunctionType>
boost::function<FunctionType> functor(const std::string &script) boost::function<FunctionType> functor(const std::string &script)
{ {
return chaiscript::functor<FunctionType>(evaluate_string(script)); return chaiscript::functor<FunctionType>(eval(script));
} }
/**
* Evaluate a string via eval method
*/
Boxed_Value operator()(const std::string &script)
{
return do_eval(script);
}
/** /**
* Returns the current evaluation engine * Returns the current evaluation engine
*/ */
@ -64,16 +103,6 @@ namespace chaiscript
} }
} }
/**
* Evaluates the given boxed string, used during eval() inside of a script
*/
const Boxed_Value eval(const std::vector<Boxed_Value> &vals) {
std::string val;
val = boxed_cast<std::string &>(vals[0]);
return evaluate_string(val);
}
/** /**
* Helper function for loading a file * Helper function for loading a file
*/ */
@ -107,41 +136,39 @@ namespace chaiscript
bootstrap_pair<std::pair<Boxed_Value, Boxed_Value > >(engine, "Pair"); bootstrap_pair<std::pair<Boxed_Value, Boxed_Value > >(engine, "Pair");
engine.add(Proxy_Function( engine.add(Proxy_Function(
new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System<Eval_Engine>::eval, boost::ref(*this), _1), 1)), "eval"); new Dynamic_Proxy_Function(boost::bind(&ChaiScript_System<Eval_Engine>::internal_eval, boost::ref(*this), _1), 1)), "eval");
evaluate_string(chaiscript_prelude, "standard prelude"); do_eval(chaiscript_prelude, "standard prelude");
} }
/** template<typename T>
* Evaluates the given string in by parsing it and running the results through the evaluator T eval(const std::string &input)
*/ {
Boxed_Value evaluate_string(const std::string &input, const char *filename = "__EVAL__") { return boxed_cast<T>(do_eval(input));
//debug_print(tokens);
Boxed_Value value;
parser.clear_match_stack();
try {
if (parser.parse(input, filename)) {
//parser.show_match_stack();
value = eval_token<Eval_Engine>(engine, parser.ast());
}
}
catch (const Return_Value &rv) {
value = rv.retval;
} }
return value; Boxed_Value eval(const std::string &input)
{
return do_eval(input);
} }
/** /**
* Loads the file specified by filename, evaluates it, and returns the result * Loads the file specified by filename, evaluates it, and returns the result
*/ */
Boxed_Value evaluate_file(const char *filename) { Boxed_Value eval_file(const char *filename) {
return evaluate_string(load_file(filename), filename); return do_eval(load_file(filename), filename);
}
/**
* Loads the file specified by filename, evaluates it, and returns the as the specified type
*/
template<typename T>
T eval_file(const char *filename) {
return boxed_cast<T>(do_eval(load_file(filename), filename));
} }
}; };
typedef ChaiScript_System<Dispatch_Engine> ChaiScript_Engine; typedef ChaiScript_System<Dispatch_Engine> ChaiScript;
} }
#endif /* CHAISCRIPT_ENGINE_HPP_ */ #endif /* CHAISCRIPT_ENGINE_HPP_ */

View File

@ -49,7 +49,7 @@ struct System
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
using namespace chaiscript; using namespace chaiscript;
ChaiScript_Engine chai; ChaiScript chai;
//Create a new system object and share it with the chaiscript engine //Create a new system object and share it with the chaiscript engine
System system; System system;
@ -63,12 +63,12 @@ int main(int argc, char *argv[]) {
// The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application // The function "{ 'Callback1' + x }" is created in chaiscript and passed into our C++ application
// in the "add_callback" function of struct System the chaiscript function is converted into a // in the "add_callback" function of struct System the chaiscript function is converted into a
// boost::function, so it can be handled and called easily and type-safely // boost::function, so it can be handled and called easily and type-safely
chai.evaluate_string("system.add_callback('#1', fun(x) { 'Callback1 ' + x });"); chai.eval("system.add_callback('#1', fun(x) { 'Callback1 ' + x });");
// Because we are sharing the "system" object with the chaiscript engine we have equal // Because we are sharing the "system" object with the chaiscript engine we have equal
// access to it both from within chaiscript and from C++ code // access to it both from within chaiscript and from C++ code
system.do_callbacks("TestString"); system.do_callbacks("TestString");
chai.evaluate_string("system.do_callbacks(\"TestString\");"); chai.eval("system.do_callbacks(\"TestString\");");
// The log function is overloaded, therefore we have to give the C++ compiler a hint as to which // The log function is overloaded, therefore we have to give the C++ compiler a hint as to which
// version we want to register. One way to do this is to create a typedef of the function pointer // version we want to register. One way to do this is to create a typedef of the function pointer
@ -78,17 +78,42 @@ int main(int argc, char *argv[]) {
chai.add(fun(PlainLog(&log)), "log"); chai.add(fun(PlainLog(&log)), "log");
chai.add(fun(ModuleLog(&log)), "log"); chai.add(fun(ModuleLog(&log)), "log");
chai.evaluate_string("log('Test Message')"); chai.eval("log('Test Message')");
chai.evaluate_string("log('Test Module', 'Test Message');");
// A shortcut to using eval is just to use the chai operator()
chai("log('Test Module', 'Test Message');");
//Finally, it is possible to register any boost::function as a system function, in this //Finally, it is possible to register any boost::function as a system function, in this
//way, we can, for instance add a bound member function to the system //way, we can, for instance add a bound member function to the system
chai.add(fun(boost::function<void ()>(boost::bind(&System::do_callbacks, boost::ref(system), "Bound Test"))), "do_callbacks"); chai.add(fun(boost::function<void ()>(boost::bind(&System::do_callbacks, boost::ref(system), "Bound Test"))), "do_callbacks");
//Call bound version of do_callbacks //Call bound version of do_callbacks
chai.evaluate_string("do_callbacks()"); chai("do_callbacks()");
boost::function<void ()> caller = chai.functor<void ()>("fun() { system.do_callbacks(\"From Functor\"); }"); boost::function<void ()> caller = chai.functor<void ()>("fun() { system.do_callbacks(\"From Functor\"); }");
caller(); caller();
//If we would like a type-safe return value from all call, we can use
//the templated version of eval:
int i = chai.eval<int>("5+5");
std::cout << "5+5: " << i << std::endl;
//Add a new variable
chai("var scripti = 15");
//We can even get a handle to the variables in the system
int &scripti = chai.eval<int &>("scripti");
std::cout << "scripti: " << scripti << std::endl;
scripti *= 2;
std::cout << "scripti (updated): " << scripti << std::endl;
chai("print(\"Scripti from chai: \" + to_string(scripti))");
// Add examples of handling Boxed_Values directly when needed
// Add usage model for mixed use:
// chai.eval("call(?, ?)", 5, "hello world"); or something
} }

View File

@ -17,7 +17,7 @@ void print_help() {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
std::string input; std::string input;
chaiscript::ChaiScript_Engine chai; chaiscript::ChaiScript chai;
if (argc < 2) { if (argc < 2) {
std::cout << "eval> "; std::cout << "eval> ";
@ -32,7 +32,7 @@ int main(int argc, char *argv[]) {
else { else {
try { try {
//First, we evaluate it //First, we evaluate it
val = chai.evaluate_string(input); val = chai.eval(input);
//Then, we try to print the result of the evaluation to the user //Then, we try to print the result of the evaluation to the user
if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) { if (val.get_type_info().m_bare_type_info && *(val.get_type_info().m_bare_type_info) != typeid(void)) {
@ -57,7 +57,7 @@ int main(int argc, char *argv[]) {
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
std::string filename(argv[i]); std::string filename(argv[i]);
try { try {
chaiscript::Boxed_Value val = chai.evaluate_file(argv[i]); chaiscript::Boxed_Value val = chai.eval_file(argv[i]);
} }
catch (std::exception &e) { catch (std::exception &e) {
std::cout << e.what() << std::endl; std::cout << e.what() << std::endl;