chaiscript.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_HPP_
  9. #define CHAISCRIPT_HPP_
  10. /// @mainpage
  11. /// [ChaiScript](http://www.chaiscript.com") is a scripting language designed specifically for integration with C++. It provides
  12. /// seamless integration with C++ on all levels, including shared_ptr objects, functors and exceptions.
  13. ///
  14. /// The parts of the ChaiScript API that the average user will be concerned with are contained in the
  15. /// chaiscript namespace and the chaiscript::ChaiScript class.
  16. ///
  17. /// The end user parts of the API are extremely simple both in size and ease of use.
  18. ///
  19. /// Currently, all source control and project management aspects of ChaiScript occur on [github](http://www.github.com/ChaiScript/ChaiScript").
  20. ///
  21. /// ------------------------------------------------------------
  22. ///
  23. /// @sa chaiscript
  24. /// @sa chaiscript::ChaiScript
  25. /// @sa ChaiScript_Language for Built in Functions
  26. /// @sa @ref LangGettingStarted
  27. /// @sa @ref LangKeywordRef
  28. /// @sa @ref LangInPlaceRef
  29. /// @sa @ref LangObjectSystemRef
  30. /// @sa http://www.chaiscript.com
  31. /// @sa http://www.github.com/ChaiScript/ChaiScript
  32. ///
  33. /// -----------------------------------------------------------
  34. ///
  35. /// @section gettingstarted API Getting Started
  36. ///
  37. /// - @ref basics
  38. /// - @ref compiling
  39. /// - @ref eval
  40. /// - @ref adding_items
  41. /// - @ref operatoroverloading
  42. /// - @ref add_class
  43. /// - @ref pointer_conversions
  44. /// - @ref baseclasses
  45. /// - @ref functionobjects
  46. /// - @ref threading
  47. /// - @ref exceptions
  48. ///
  49. ///
  50. /// @subsection basics Basics
  51. ///
  52. /// Basic simple example:
  53. ///
  54. /// ~~~~~~~{.cpp}
  55. /// //main.cpp
  56. /// #include <chaiscript/chaiscript.hpp>
  57. ///
  58. /// double function(int i, double j)
  59. /// {
  60. /// return i * j;
  61. /// }
  62. ///
  63. /// int main()
  64. /// {
  65. /// chaiscript::ChaiScript chai;
  66. /// chai.add(chaiscript::fun(&function), "function");
  67. ///
  68. /// double d = chai.eval<double>("function(3, 4.75);");
  69. /// }
  70. /// ~~~~~~~
  71. ///
  72. /// ------------------------------------------------------
  73. ///
  74. /// @subsection compiling Compiling ChaiScript Applications
  75. ///
  76. /// ChaiScript is a header only library with only one dependency: The
  77. /// operating system provided dynamic library loader, which has to be specified on some platforms.
  78. ///
  79. /// @subsubsection compilinggcc Compiling with GCC
  80. ///
  81. /// To compile the above application on a Unix like operating system (MacOS, Linux) with GCC you need to link
  82. /// the dynamic loader. For example:
  83. ///
  84. /// ~~~~~~~~
  85. /// gcc main.cpp -I/path/to/chaiscript/headers -ldl
  86. /// ~~~~~~~~
  87. ///
  88. /// Alternatively, you may compile without threading support.
  89. ///
  90. /// ~~~~~~~~
  91. /// gcc main.cpp -I/path/to/chaiscript/headers -ldl -DCHAISCRIPT_NO_THREADS
  92. /// ~~~~~~~~
  93. ///
  94. /// ------------------------------------------
  95. ///
  96. /// @subsection eval Evaluating Scripts
  97. ///
  98. /// Scripts can be evaluated with the () operator, eval method or eval_file method.
  99. ///
  100. /// @subsubsection parenoperator () Operator
  101. ///
  102. /// operator() can be used as a handy shortcut for evaluating ChaiScript snippets.
  103. ///
  104. /// ~~~~~~~~{.cpp}
  105. /// chaiscript::ChaiScript chai;
  106. /// chai("print(@"hello world@")");
  107. /// ~~~~~~~~
  108. ///
  109. /// @sa chaiscript::ChaiScript::operator()(const std::string &)
  110. ///
  111. /// @subsubsection evalmethod Method 'eval'
  112. ///
  113. /// The eval method is somewhat more verbose and can be used to get type safely return values
  114. /// from the script.
  115. ///
  116. /// ~~~~~~~~{.cpp}
  117. /// chaiscript::ChaiScript chai;
  118. /// chai.eval("callsomefunc()");
  119. /// int result = chai.eval<int>("1 + 3");
  120. /// // result now equals 4
  121. /// ~~~~~~~~
  122. ///
  123. /// @sa chaiscript::ChaiScript::eval
  124. ///
  125. /// @subsubsection evalfilemethod Method 'eval_file'
  126. ///
  127. /// The 'eval_file' method loads a file from disk and executes the script in it
  128. ///
  129. /// ~~~~~~~~{.cpp}
  130. /// chaiscript::ChaiScript chai;
  131. /// chai.eval_file("myfile.chai");
  132. /// std::string result = chai.eval_file<std::string>("myfile.chai") // extract the last value returned from the file
  133. /// ~~~~~~~~
  134. ///
  135. /// @sa chaiscript::ChaiScript::eval_file
  136. ///
  137. /// --------------------------------------------------
  138. ///
  139. /// @subsection adding_items Adding Items to ChaiScript
  140. ///
  141. /// ChaiScript supports 4 basic things that can be added: objects, functions, type infos and Modules
  142. ///
  143. /// @subsubsection adding_objects Adding Objects
  144. ///
  145. /// Named objects can be created with the chaiscript::var function. Note: adding a object
  146. /// adds it to the current thread scope, not to a global scope. If you have multiple
  147. /// threads that need to access the same variables you will need to add them
  148. /// separately for each thread, from the thread itself.
  149. ///
  150. /// ~~~~~~~~~{.cpp}
  151. /// using namespace chaiscript;
  152. /// ChaiScript chai;
  153. /// int i = 5;
  154. /// chai.add(var(i), "i");
  155. /// chai("print(i)");
  156. /// ~~~~~~~~~
  157. ///
  158. /// Immutable objects can be created with the chaiscript::const_var function.
  159. ///
  160. /// ~~~~~~~~~{.cpp}
  161. /// chai.add(const_var(i), "i");
  162. /// chai("i = 5"); // exception throw, cannot assign const var
  163. /// ~~~~~~~~~
  164. ///
  165. /// Named variables can only be accessed from the context they are created in.
  166. /// If you want a global variable, it must be const, and created with the
  167. /// chaiscript::ChaiScript::add_global_const function.
  168. ///
  169. /// ~~~~~~~~~{.cpp}
  170. /// chai.add_global_const(const_var(i), "i");
  171. /// chai("def somefun() { print(i); }; somefun();");
  172. /// ~~~~~~~~~
  173. ///
  174. /// @subsubsection adding_functions Adding Functions
  175. ///
  176. /// Functions, methods and members are all added using the same function: chaiscript::fun.
  177. ///
  178. /// ~~~~~~~~~{.cpp}
  179. /// using namespace chaiscript;
  180. ///
  181. /// class MyClass {
  182. /// public:
  183. /// int memberdata;
  184. /// void method();
  185. /// void method2(int);
  186. /// static void staticmethod();
  187. /// void overloadedmethod();
  188. /// void overloadedmethod(const std::string &);
  189. /// };
  190. ///
  191. /// ChaiScript chai;
  192. /// chai.add(fun(&MyClass::memberdata), "memberdata");
  193. /// chai.add(fun(&MyClass::method), "method");
  194. /// chai.add(fun(&MyClass::staticmethod), "staticmethod");
  195. /// ~~~~~~~~~
  196. ///
  197. /// Overloaded methods will need some help, to hint the compiler as to which overload you want:
  198. ///
  199. /// ~~~~~~~~~{.cpp}
  200. /// chai.add(fun<void (MyClass::*)()>(&MyClass::overloadedmethod), "overloadedmethod");
  201. /// chai.add(fun<void (MyClass::*)(const std::string &)>(&MyClass::overloadedmethod), "overloadedmethod");
  202. /// ~~~~~~~~~
  203. ///
  204. /// There are also shortcuts built into chaiscript::fun for binding up to the first two parameters of the function.
  205. ///
  206. /// ~~~~~~~~~{.cpp}
  207. /// MyClass obj;
  208. /// chai.add(fun(&MyClass::method, &obj), "method");
  209. /// chai("method()"); // equiv to obj.method()
  210. /// chai.add(fun(&MyClass::method2, &obj, 3), "method2");
  211. /// chai("method2()"); // equiv to obj.method2(3)
  212. /// ~~~~~~~~~
  213. ///
  214. /// @subsubsection addingtypeinfo Adding Type Info
  215. ///
  216. /// ChaiScript will automatically support any type implicitly provided to it in the form
  217. /// of objects and function parameters / return types. However, it can be nice to let ChaiScript
  218. /// know more details about the types you are giving it. For instance, the "clone" functionality
  219. /// cannot work unless there is a copy constructor registered and the name of the type is known
  220. /// (so that ChaiScript can look up the copy constructor).
  221. ///
  222. /// Continuing with the example "MyClass" from above:
  223. ///
  224. /// ~~~~~~~~{.cpp}
  225. /// chai.add(user_type<MyClass>(), "MyClass");
  226. /// ~~~~~~~~
  227. ///
  228. /// @subsubsection adding_modules Adding Modules
  229. ///
  230. /// Modules are holders for collections of ChaiScript registrations.
  231. ///
  232. /// ~~~~~~~~{.cpp}
  233. /// ModulePtr module = get_sum_module();
  234. /// chai.add(module);
  235. /// ~~~~~~~~
  236. ///
  237. /// @sa chaiscript::Module
  238. ///
  239. /// -----------------------------------------------------------------------
  240. ///
  241. /// @subsection operatoroverloading Operator Overloading
  242. ///
  243. /// Operators are just like any other function in ChaiScript, to overload an operator, simply register it.
  244. ///
  245. /// ~~~~~~~~{.cpp}
  246. /// class MyClass {
  247. /// MyClass operator+(const MyClass &) const;
  248. /// };
  249. ///
  250. /// chai.add(fun(&MyClass::operator+), "+");
  251. ///
  252. /// std::string append_string_int(const std::string &t_lhs, int t_rhs)
  253. /// {
  254. /// std::stringstream ss;
  255. /// ss << t_lhs << t_rhs;
  256. /// return ss.str();
  257. /// }
  258. ///
  259. /// chai.add(fun(append_string_int), "+");
  260. /// ~~~~~~~~
  261. ///
  262. /// @sa @ref adding_functions
  263. ///
  264. /// -----------------------------------------------------------------------
  265. ///
  266. /// @subsection add_class Class Helper Utility
  267. ///
  268. /// Much of the work of adding new classes to ChaiScript can be reduced with the help
  269. /// of the add_class helper utility.
  270. ///
  271. /// ~~~~~~~~{.cpp}
  272. /// class Test
  273. /// {
  274. /// public:
  275. /// void function() {}
  276. /// std::string function2() { return "Function2"; }
  277. /// void function3() {}
  278. /// std::string functionOverload(double) { return "double"; }
  279. /// std::string functionOverload(int) { return "int"; }
  280. /// };
  281. ///
  282. /// int main()
  283. /// {
  284. /// chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());
  285. ///
  286. /// chaiscript::utility::add_class<chaiscript::Test>(*m,
  287. /// "Test",
  288. /// { constructor<Test()>(),
  289. /// constructor<Test(const Test &)>() },
  290. /// { {fun(&Test::function), "function"},
  291. /// {fun(&Test::function2), "function2"},
  292. /// {fun(&Test::function2), "function3"}
  293. /// {fun(static_cast<std::string Test::*(double)>(&Test::functionOverload)), "functionOverload"}
  294. /// {fun(static_cast<std::string Test::*(int)>(&Test::functionOverload)), "functionOverload"} }
  295. /// );
  296. ///
  297. ///
  298. /// chaiscript::ChaiScript chai;
  299. /// chai.add(m);
  300. /// }
  301. /// ~~~~~~~~
  302. ///
  303. /// @sa @ref adding_modules
  304. ///
  305. /// -----------------------------------------------------------------------
  306. ///
  307. /// @subsection pointer_conversions Pointer / Object Conversions
  308. ///
  309. /// As much as possible, ChaiScript attempts to convert between &, *, const &, const *, std::shared_ptr<T>,
  310. /// std::shared_ptr<const T>, std::reference_wrapper<T>, std::reference_wrapper<const T> and value types automatically.
  311. ///
  312. /// If a chaiscript::var object was created in C++ from a pointer, it cannot be converted to a shared_ptr (this would add invalid reference counting).
  313. /// Const may be added, but never removed.
  314. ///
  315. /// The take away is that you can pretty much expect function calls to Just Work when you need them to.
  316. ///
  317. /// ~~~~~~~~{.cpp}
  318. /// void fun1(const int *);
  319. /// void fun2(int *);
  320. /// void fun3(int);
  321. /// void fun4(int &);
  322. /// void fun5(const int &);
  323. /// void fun5(std::shared_ptr<int>);
  324. /// void fun6(std::shared_ptr<const int>);
  325. /// void fun7(const std::shared_ptr<int> &);
  326. /// void fun8(const std::shared_ptr<const int> &);
  327. /// void fun9(std::reference_wrapper<int>);
  328. /// void fun10(std::reference_wrapper<const int>);
  329. ///
  330. /// int main()
  331. /// {
  332. /// using namespace chaiscript
  333. /// chaiscript::ChaiScript chai;
  334. /// chai.add(fun(fun1), "fun1");
  335. /// chai.add(fun(fun2), "fun2");
  336. /// chai.add(fun(fun3), "fun3");
  337. /// chai.add(fun(fun4), "fun4");
  338. /// chai.add(fun(fun5), "fun5");
  339. /// chai.add(fun(fun6), "fun6");
  340. /// chai.add(fun(fun7), "fun7");
  341. /// chai.add(fun(fun8), "fun8");
  342. /// chai.add(fun(fun9), "fun9");
  343. /// chai.add(fun(fun10), "fun10");
  344. ///
  345. /// chai("var i = 10;");
  346. /// chai("fun1(i)");
  347. /// chai("fun2(i)");
  348. /// chai("fun3(i)");
  349. /// chai("fun4(i)");
  350. /// chai("fun5(i)");
  351. /// chai("fun6(i)");
  352. /// chai("fun7(i)");
  353. /// chai("fun8(i)");
  354. /// chai("fun9(i)");
  355. /// chai("fun10(i)");
  356. /// }
  357. /// ~~~~~~~~
  358. ///
  359. /// See the unit test unittests/boxed_cast_test.cpp for a complete breakdown of the automatic casts that
  360. /// available and tested.
  361. ///
  362. /// -----------------------------------------------------------------------
  363. ///
  364. /// @subsection baseclasses Base Classes
  365. ///
  366. /// ChaiScript supports handling of passing a derived class object to a function expecting a base class object.
  367. /// For the process to work, the base/derived relationship must be registered with the engine.
  368. ///
  369. /// ~~~~~~~~{.cpp}
  370. /// class Base {};
  371. /// class Derived : public Base {};
  372. /// void myfunction(Base *b);
  373. ///
  374. /// int main()
  375. /// {
  376. /// chaiscript::ChaiScript chai;
  377. /// chai.add(chaiscript::base_class<Base, Derived>());
  378. /// Derived d;
  379. /// chai.add(chaiscript::var(&d), "d");
  380. /// chai.add(chaiscript::fun(&myfunction), "myfunction");
  381. /// chai("myfunction(d)");
  382. /// }
  383. /// ~~~~~~~~
  384. ///
  385. /// -----------------------------------------------------------------------
  386. ///
  387. ///
  388. /// @subsection functionobjects Function Objects
  389. ///
  390. /// Functions are first class objects in ChaiScript and ChaiScript supports automatic conversion
  391. /// between ChaiScript functions and std::function objects.
  392. ///
  393. /// ~~~~~~~~{.cpp}
  394. /// void callafunc(const std::function<void (const std::string &)> &t_func)
  395. /// {
  396. /// t_func("bob");
  397. /// }
  398. ///
  399. /// int main()
  400. /// {
  401. /// chaiscript::ChaiScript chai;
  402. /// chai.add(chaiscript::fun(&callafunc), "callafunc");
  403. /// chai("callafunc(fun(x) { print(x); })"); // pass a lambda function to the registered function
  404. /// // which expects a typed std::function
  405. ///
  406. /// std::function<void ()> f = chai.eval<std::function<void ()> >("dump_system");
  407. /// f(); // call the ChaiScript function dump_system, from C++
  408. /// }
  409. /// ~~~~~~~~
  410. ///
  411. /// -----------------------------------------------------------------------
  412. ///
  413. ///
  414. /// @subsection threading Threading
  415. ///
  416. /// Thread safety is automatically handled within the ChaiScript system. Objects can be added
  417. /// and scripts executed from multiple threads. For each thread that executes scripts, a new
  418. /// context is created and managed by the engine.
  419. ///
  420. /// Thread safety can be disabled by defining CHAISCRIPT_NO_THREADS when using the library.
  421. ///
  422. /// Disabling thread safety increases performance in many cases.
  423. ///
  424. /// -----------------------------------------------------------------------
  425. ///
  426. ///
  427. /// @subsection exceptions Exception Handling
  428. ///
  429. /// @subsubsection exceptionsbasics Exception Handling Basics
  430. ///
  431. /// Exceptions can be thrown in ChaiScript and caught in C++ or thrown in C++ and caught in
  432. /// ChaiScript.
  433. ///
  434. /// ~~~~~~~~{.cpp}
  435. /// void throwexception()
  436. /// {
  437. /// throw std::runtime_error("err");
  438. /// }
  439. ///
  440. /// int main()
  441. /// {
  442. /// // Throw in C++, catch in ChaiScript
  443. /// chaiscript::ChaiScript chai;
  444. /// chai.add(chaiscript::fun(&throwexception), "throwexception");
  445. /// chai("try { throwexception(); } catch (e) { print(e.what()); }"); // prints "err"
  446. ///
  447. /// // Throw in ChaiScript, catch in C++
  448. /// try {
  449. /// chai("throw(1)");
  450. /// } catch (chaiscript::Boxed_Value bv) {
  451. /// int i = chaiscript::boxed_cast<int>(bv);
  452. /// // i == 1
  453. /// }
  454. /// }
  455. /// ~~~~~~~~
  456. ///
  457. /// @subsubsection exceptionsautomatic Exception Handling Automatic Unboxing
  458. ///
  459. /// As an alternative to the manual unboxing of exceptions shown above, exception specifications allow the user to tell
  460. /// ChaiScript what possible exceptions are expected from the script being executed.
  461. ///
  462. /// Example:
  463. /// ~~~~~~~~{.cpp}
  464. /// chaiscript::ChaiScript chai;
  465. ///
  466. /// try {
  467. /// chai.eval("throw(runtime_error(@"error@"))", chaiscript::exception_specification<int, double, float, const std::string &, const std::exception &>());
  468. /// } catch (const double e) {
  469. /// } catch (int) {
  470. /// } catch (float) {
  471. /// } catch (const std::string &) {
  472. /// } catch (const std::exception &e) {
  473. /// // This is the one what will be called in the specific throw() above
  474. /// }
  475. /// ~~~~~~~~
  476. ///
  477. /// @sa chaiscript::Exception_Handler for details on automatic exception unboxing
  478. /// @sa chaiscript::exception_specification
  479. /// @page LangObjectSystemRef ChaiScript Language Object Model Reference
  480. ///
  481. ///
  482. /// ChaiScript has an object system built in, for types defined within the ChaiScript system.
  483. ///
  484. /// ~~~~~~~~~
  485. /// attr Rectangle::height
  486. /// attr Rectangle::width
  487. /// def Rectangle::Rectangle() { this.height = 10; this.width = 20 }
  488. /// def Rectangle::area() { this.height * this.width }
  489. ///
  490. /// var rect = Rectangle()
  491. /// rect.height = 30
  492. /// print(rect.area())
  493. /// ~~~~~~~~~
  494. ///
  495. /// Since ChaiScript 5.4.0 it has been possible to use the "class" keyword to simplify this code.
  496. ///
  497. /// ~~~~~~~~~
  498. /// class Rectangle {
  499. /// attr height
  500. /// attr width
  501. /// def Rectangle() { this.height = 10; this.width = 20 }
  502. /// def area() { this.height * this.width }
  503. /// }
  504. ///
  505. /// var rect = Rectangle()
  506. /// rect.height = 30
  507. /// print(rect.area())
  508. /// ~~~~~~~~~
  509. ///
  510. /// @sa @ref keywordattr
  511. /// @sa @ref keyworddef
  512. /// @page LangInPlaceRef ChaiScript Language In-Place Creation Reference
  513. /// @section inplacevector Vector
  514. ///
  515. /// ~~~~~~~~~
  516. /// In-place Vector ::= "[" [expression ("," expression)*] "]"
  517. /// ~~~~~~~~~
  518. ///
  519. /// @section inplacerangedvector Ranged Vector
  520. ///
  521. /// ~~~~~~~~~
  522. /// In-place Ranged Vector ::= "[" value ".." value "]"
  523. /// ~~~~~~~~~
  524. ///
  525. /// Creates a vector over a range (eg. 1..10)
  526. ///
  527. /// @section inplacemap Map
  528. ///
  529. /// ~~~~~~~~
  530. /// In-place Map ::= "[" (string ":" expression)+ "]"
  531. /// ~~~~~~~~
  532. /// @page LangGettingStarted ChaiScript Language Getting Started
  533. ///
  534. /// ChaiScript is a simple language that should feel familiar to anyone who knows
  535. /// C++ or ECMAScript (JavaScript).
  536. ///
  537. /// -----------------------------------------------------------------------
  538. ///
  539. /// @section chaiscriptloops Loops
  540. ///
  541. /// Common looping constructs exist in ChaiScript
  542. ///
  543. /// ~~~~~~~~
  544. /// var i = 0;
  545. /// while (i < 10)
  546. /// {
  547. /// // do something
  548. /// ++i;
  549. /// }
  550. /// ~~~~~~~~
  551. ///
  552. /// ~~~~~~~~
  553. /// for (var i = 0; i < 10; ++i)
  554. /// {
  555. /// // do something
  556. /// }
  557. /// ~~~~~~~~
  558. ///
  559. /// @sa @ref keywordfor
  560. /// @sa @ref keywordwhile
  561. ///
  562. /// -----------------------------------------------------------------------
  563. ///
  564. /// @section chaiscriptifs Conditionals
  565. ///
  566. /// If statements work as expected
  567. ///
  568. /// ~~~~~~~~
  569. /// var b = true;
  570. ///
  571. /// if (b) {
  572. /// // do something
  573. /// } else if (c < 10) {
  574. /// // do something else
  575. /// } else {
  576. /// // or do this
  577. /// }
  578. /// ~~~~~~~~
  579. ///
  580. /// @sa @ref keywordif
  581. ///
  582. /// -----------------------------------------------------------------------
  583. ///
  584. /// @section chaiscriptfunctions Functions
  585. ///
  586. /// Functions are defined with the def keyword
  587. ///
  588. /// ~~~~~~~~
  589. /// def myfun(x) { print(x); }
  590. ///
  591. /// myfun(10);
  592. /// ~~~~~~~~
  593. ///
  594. /// Functions may have "guards" which determine if which is called.
  595. ///
  596. /// ~~~~~~~~
  597. /// eval> def myfun2(x) : x < 10 { print("less than 10"); }
  598. /// eval> def myfun2(x) : x >= 10 { print("10 or greater"); }
  599. /// eval> myfun2(5)
  600. /// less than 10
  601. /// eval> myfun2(12)
  602. /// 10 or greater
  603. /// ~~~~~~~~
  604. ///
  605. /// @sa @ref keyworddef
  606. /// @sa @ref keywordattr
  607. /// @sa @ref LangObjectSystemRef
  608. ///
  609. /// -----------------------------------------------------------------------
  610. ///
  611. /// @section chaiscriptfunctionobjects Function Objects
  612. ///
  613. /// Functions are first class types in ChaiScript and can be used as variables.
  614. ///
  615. /// ~~~~~~~~
  616. /// eval> var p = print;
  617. /// eval> p(1);
  618. /// 1
  619. /// ~~~~~~~~
  620. ///
  621. /// They can also be passed to functions.
  622. ///
  623. /// ~~~~~~~~
  624. /// eval> def callfunc(f, lhs, rhs) { return f(lhs, rhs); }
  625. /// eval> def do_something(lhs, rhs) { print("lhs: ${lhs}, rhs: ${rhs}"); }
  626. /// eval> callfunc(do_something, 1, 2);
  627. /// lhs: 1, rhs: 2
  628. /// ~~~~~~~~
  629. ///
  630. /// Operators can also be treated as functions by using the back tick operator. Building on the above example:
  631. ///
  632. /// ~~~~~~~~
  633. /// eval> callfunc(`+`, 1, 4);
  634. /// 5
  635. /// eval> callfunc(`*`, 3, 2);
  636. /// 6
  637. /// ~~~~~~~~
  638. ///
  639. /// -----------------------------------------------------------------------
  640. ///
  641. /// @sa @ref LangKeywordRef
  642. /// @sa ChaiScript_Language for Built in Functions
  643. /// @page LangKeywordRef ChaiScript Language Keyword Reference
  644. ///
  645. ///
  646. /// -----------------------------------------------------------------------
  647. ///
  648. /// @section keywordattr attr
  649. /// Defines a ChaiScript object attribute
  650. ///
  651. /// ~~~~~~~~
  652. /// Attribute Definition ::= "attr" class_name "::" attribute_name
  653. /// ~~~~~~~~
  654. ///
  655. /// @sa @ref LangObjectSystemRef
  656. ///
  657. ///
  658. /// -----------------------------------------------------------------------
  659. ///
  660. /// @section keywordauto auto
  661. ///
  662. /// Defines a variable
  663. ///
  664. /// ~~~~~~~~
  665. /// Variable ::= "auto" identifier
  666. /// ~~~~~~~~
  667. ///
  668. /// Synonym for @ref keywordvar
  669. ///
  670. /// -----------------------------------------------------------------------
  671. ///
  672. /// @section keywordbreak break
  673. /// Stops execution of a looping block.
  674. ///
  675. /// ~~~~~~~~
  676. /// Break Statement ::= "break"
  677. /// ~~~~~~~~
  678. ///
  679. /// @sa @ref keywordfor
  680. /// @sa @ref keywordwhile
  681. ///
  682. ///
  683. /// -----------------------------------------------------------------------
  684. ///
  685. /// @section keyworddef def
  686. /// Begins a function or method definition
  687. ///
  688. /// ~~~~~~~~
  689. /// Function Definition ::= "def" identifier "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
  690. /// Method Definition ::= "def" class_name "::" method_name "(" [[type] arg ("," [type] arg)*] ")" [":" guard] block
  691. /// ~~~~~~~~
  692. ///
  693. /// identifier: name of function. Required.
  694. /// args: comma-delimited list of parameter names with optional type specifiers. Optional.
  695. /// guards: guarding statement that act as a prerequisite for the function. Optional.
  696. /// { }: scoped block as function body. Required.
  697. ///
  698. /// Functions return values in one of two ways:
  699. ///
  700. /// By using an explicit return call, optionally passing the value to be returned.
  701. /// By implicitly returning the value of the last expression (if it is not a while or for loop).
  702. ///
  703. /// Method definitions for known types extend those types with new methods. This includes C++ and ChaiScript defined types.
  704. /// Method definitions for unknown types implicitly define the named type.
  705. ///
  706. /// @sa @ref LangObjectSystemRef
  707. ///
  708. ///
  709. /// -----------------------------------------------------------------------
  710. ///
  711. /// @section keywordelse else
  712. /// @sa @ref keywordif
  713. ///
  714. ///
  715. /// -----------------------------------------------------------------------
  716. ///
  717. /// @section keywordfor for
  718. /// ~~~~~~~~
  719. /// For Block ::= "for" "(" [initial] ";" stop_condition ";" loop_expression ")" block
  720. /// ~~~~~~~~
  721. /// This loop can be broken using the @ref keywordbreak command.
  722. ///
  723. ///
  724. /// -----------------------------------------------------------------------
  725. ///
  726. /// @section keywordfun fun
  727. /// Begins an anonymous function declaration (sometimes called a lambda).
  728. ///
  729. /// ~~~~~~~~
  730. /// Lambda ::= "fun" "(" [variable] ("," variable)* ")" block
  731. /// ~~~~~~~~
  732. ///
  733. /// _Example_
  734. ///
  735. /// ~~~~~~~~
  736. /// // Generate an anonymous function object that adds 2 to its parameter
  737. /// var f = fun(x) { x + 2; }
  738. /// ~~~~~~~~
  739. ///
  740. /// @sa @ref keyworddef for more details on ChaiScript functions
  741. ///
  742. ///
  743. /// -----------------------------------------------------------------------
  744. ///
  745. /// @section keywordif if
  746. /// Begins a conditional block of code that only executes if the condition evaluates as true.
  747. /// ~~~~~~~~
  748. /// If Block ::= "if" "(" condition ")" block
  749. /// Else If Block ::= "else if" "(" condition ")" block
  750. /// Else Block ::= "else" block
  751. /// ~~~~~~~~
  752. ///
  753. /// _Example_
  754. ///
  755. /// ~~~~~~~~
  756. /// if (true) {
  757. /// // do something
  758. /// } else if (false) {
  759. /// // do something else
  760. /// } else {
  761. /// // otherwise do this
  762. /// }
  763. /// ~~~~~~~~
  764. ///
  765. ///
  766. /// -----------------------------------------------------------------------
  767. ///
  768. /// @section keywordtry try
  769. /// ~~~~~~~~
  770. /// Try Block ::= "try" block
  771. /// ("catch" ["(" [type] variable ")"] [":" guards] block)+
  772. /// ["finally" block]
  773. /// ~~~~~~~~
  774. ///
  775. /// @sa ChaiScript_Language::throw
  776. ///
  777. ///
  778. /// -----------------------------------------------------------------------
  779. ///
  780. /// @section keywordwhile while
  781. ///
  782. /// Begins a conditional block of code that loops 0 or more times, as long as the condition is true
  783. ///
  784. /// ~~~~~~~~
  785. /// While Block ::= "while" "(" condition ")" block
  786. /// ~~~~~~~~
  787. ///
  788. /// This loop can be broken using the @ref keywordbreak command.
  789. ///
  790. ///
  791. /// -----------------------------------------------------------------------
  792. ///
  793. /// @section keywordvar var
  794. ///
  795. /// Defines a variable
  796. ///
  797. /// ~~~~~~~~
  798. /// Variable ::= "var" identifier
  799. /// ~~~~~~~~
  800. ///
  801. /// Synonym for @ref keywordauto
  802. /// @namespace chaiscript
  803. /// @brief Namespace chaiscript contains every API call that the average user will be concerned with.
  804. /// @namespace chaiscript::detail
  805. /// @brief Classes and functions reserved for internal use. Items in this namespace are not supported.
  806. #include "chaiscript_basic.hpp"
  807. #include "language/chaiscript_parser.hpp"
  808. #include "chaiscript_stdlib.hpp"
  809. namespace chaiscript
  810. {
  811. class ChaiScript : public ChaiScript_Basic
  812. {
  813. public:
  814. ChaiScript(std::vector<std::string> t_modulepaths = {},
  815. std::vector<std::string> t_usepaths = {},
  816. const std::vector<Options> &t_opts = chaiscript::default_options())
  817. : ChaiScript_Basic(
  818. chaiscript::Std_Lib::library(),
  819. std::make_unique<parser::ChaiScript_Parser<eval::Noop_Tracer, optimizer::Optimizer_Default>>(),
  820. t_modulepaths, t_usepaths, t_opts)
  821. {
  822. }
  823. };
  824. }
  825. #endif /* CHAISCRIPT_HPP_ */