Use C++11 Raw Strings for chaiscript prelude
This commit is contained in:
parent
a3b50d4151
commit
a6924bcc9e
@ -91,7 +91,7 @@ endif()
|
|||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
|
|
||||||
set (Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.hpp include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp)
|
set (Chai_INCLUDES include/chaiscript/chaiscript.hpp include/chaiscript/chaiscript_threading.hpp include/chaiscript/dispatchkit/bad_boxed_cast.hpp include/chaiscript/dispatchkit/bind_first.hpp include/chaiscript/dispatchkit/bootstrap.hpp include/chaiscript/dispatchkit/bootstrap_stl.hpp include/chaiscript/dispatchkit/boxed_cast.hpp include/chaiscript/dispatchkit/boxed_cast_helper.hpp include/chaiscript/dispatchkit/boxed_number.hpp include/chaiscript/dispatchkit/boxed_value.hpp include/chaiscript/dispatchkit/dispatchkit.hpp include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp include/chaiscript/dispatchkit/dynamic_object.hpp include/chaiscript/dispatchkit/exception_specification.hpp include/chaiscript/dispatchkit/function_call.hpp include/chaiscript/dispatchkit/function_call_detail.hpp include/chaiscript/dispatchkit/handle_return.hpp include/chaiscript/dispatchkit/operators.hpp include/chaiscript/dispatchkit/proxy_constructors.hpp include/chaiscript/dispatchkit/proxy_functions.hpp include/chaiscript/dispatchkit/proxy_functions_detail.hpp include/chaiscript/dispatchkit/register_function.hpp include/chaiscript/dispatchkit/type_info.hpp include/chaiscript/language/chaiscript_algebraic.hpp include/chaiscript/language/chaiscript_common.hpp include/chaiscript/language/chaiscript_engine.hpp include/chaiscript/language/chaiscript_eval.hpp include/chaiscript/language/chaiscript_parser.hpp include/chaiscript/language/chaiscript_prelude.chai include/chaiscript/language/chaiscript_prelude_docs.hpp include/chaiscript/utility/utility.hpp)
|
||||||
|
|
||||||
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
set_source_files_properties(${Chai_INCLUDES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "chaiscript_prelude.hpp"
|
#include "chaiscript_prelude.chai"
|
||||||
#include "chaiscript_parser.hpp"
|
#include "chaiscript_parser.hpp"
|
||||||
#include "../dispatchkit/exception_specification.hpp"
|
#include "../dispatchkit/exception_specification.hpp"
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ namespace chaiscript
|
|||||||
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
m_engine.add(fun(&ChaiScript::internal_eval, this), "eval");
|
||||||
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
|
m_engine.add(fun(&ChaiScript::internal_eval_ast, this), "eval");
|
||||||
|
|
||||||
do_eval(chaiscript_prelude, "standard prelude");
|
do_eval(ChaiScript_Prelude::chaiscript_prelude, "standard prelude");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "chaiscript_prelude.hpp"
|
|
||||||
#include "chaiscript_common.hpp"
|
#include "chaiscript_common.hpp"
|
||||||
|
|
||||||
namespace chaiscript
|
namespace chaiscript
|
||||||
|
530
include/chaiscript/language/chaiscript_prelude.chai
Normal file
530
include/chaiscript/language/chaiscript_prelude.chai
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
// This file is distributed under the BSD License.
|
||||||
|
// See "license.txt" for details.
|
||||||
|
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
||||||
|
// and Jason Turner (jason@emptycrate.com)
|
||||||
|
// http://www.chaiscript.com
|
||||||
|
|
||||||
|
#ifndef CHAISCRIPT_PRELUDE_HPP_
|
||||||
|
#define CHAISCRIPT_PRELUDE_HPP_
|
||||||
|
|
||||||
|
namespace chaiscript {
|
||||||
|
struct ChaiScript_Prelude {
|
||||||
|
constexpr static const char *chaiscript_prelude=R""(
|
||||||
|
|
||||||
|
def lt(l, r) {
|
||||||
|
if (call_exists(`<`, l, r)) {
|
||||||
|
l < r
|
||||||
|
} else {
|
||||||
|
type_name(l) < type_name(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def gt(l, r) {
|
||||||
|
if (call_exists(`>`, l, r)) {
|
||||||
|
l > r
|
||||||
|
} else {
|
||||||
|
type_name(l) > type_name(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def eq(l, r) {
|
||||||
|
if (call_exists(`==`, l, r)) {
|
||||||
|
l == r
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def new(x) {
|
||||||
|
eval(type_name(x))();
|
||||||
|
}
|
||||||
|
|
||||||
|
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x)
|
||||||
|
{
|
||||||
|
eval(type_name(x))(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# to_string for Pair()
|
||||||
|
def to_string(x) : call_exists(first, x) && call_exists(second, x) {
|
||||||
|
"<" + x.first.to_string() + ", " + x.second.to_string() + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
# to_string for containers
|
||||||
|
def to_string(x) : call_exists(range, x) && !x.is_type("string"){
|
||||||
|
"[" + x.join(", ") + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Basic to_string function
|
||||||
|
def to_string(x) {
|
||||||
|
internal_to_string(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prints to console with no carriage return
|
||||||
|
def puts(x) {
|
||||||
|
print_string(x.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prints to console with carriage return
|
||||||
|
def print(x) {
|
||||||
|
println_string(x.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the maximum value of two numbers
|
||||||
|
def max(a, b) {
|
||||||
|
if (a>b) {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the minimum value of two numbers
|
||||||
|
def min(a, b)
|
||||||
|
{
|
||||||
|
if (a<b)
|
||||||
|
{
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns true if the value is odd
|
||||||
|
def odd(x) {
|
||||||
|
if (x % 2 == 1)
|
||||||
|
{
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns true if the value is even
|
||||||
|
def even(x)
|
||||||
|
{
|
||||||
|
if (x % 2 == 0)
|
||||||
|
{
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Pushes the second value onto the container first value while making a clone of the value
|
||||||
|
def push_back(container, x) : call_exists(push_back_ref, container, x)
|
||||||
|
{
|
||||||
|
container.push_back_ref(clone(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pushes the second value onto the front of the container first value while making a clone of the value
|
||||||
|
def push_front(container, x) : call_exists(push_front_ref, container, x)
|
||||||
|
{
|
||||||
|
container.push_front_ref(clone(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Inserts the third value at the position of the second value into the container of the first
|
||||||
|
# while making a clone.
|
||||||
|
def insert_at(container, pos, x)
|
||||||
|
{
|
||||||
|
container.insert_ref_at(pos, clone(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the reverse of the given container
|
||||||
|
def reverse(container) {
|
||||||
|
auto retval = new(container);
|
||||||
|
auto r = range(container);
|
||||||
|
while (!r.empty()) {
|
||||||
|
retval.push_back(r.back());
|
||||||
|
r.pop_back();
|
||||||
|
}
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return a range from a range
|
||||||
|
def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
|
||||||
|
{
|
||||||
|
return clone(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# The retro attribute that contains the underlying range
|
||||||
|
attr retro::m_range;
|
||||||
|
|
||||||
|
# Creates a retro from a retro by returning the original range
|
||||||
|
def retro(r) : call_exists(get_type_name, r) && get_type_name(r) == "retro"
|
||||||
|
{
|
||||||
|
clone(r.m_range)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Creates a retro range from a range
|
||||||
|
def retro::retro(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
|
||||||
|
{
|
||||||
|
this.m_range = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the first value of a retro
|
||||||
|
def retro::front()
|
||||||
|
{
|
||||||
|
back(this.m_range)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the last value of a retro
|
||||||
|
def retro::back()
|
||||||
|
{
|
||||||
|
front(this.m_range)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Moves the back iterator of a retro towards the front by one
|
||||||
|
def retro::pop_back()
|
||||||
|
{
|
||||||
|
pop_front(this.m_range)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Moves the front iterator of a retro towards the back by one
|
||||||
|
def retro::pop_front()
|
||||||
|
{
|
||||||
|
pop_back(this.m_range)
|
||||||
|
}
|
||||||
|
|
||||||
|
# returns true if the retro is out of elements
|
||||||
|
def retro::empty()
|
||||||
|
{
|
||||||
|
empty(this.m_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Performs the second value function over the container first value
|
||||||
|
def for_each(container, func) : call_exists(range, container) {
|
||||||
|
var t_range = range(container);
|
||||||
|
while (!t_range.empty()) {
|
||||||
|
func(t_range.front());
|
||||||
|
t_range.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def back_inserter(container) {
|
||||||
|
bind(push_back, container, _);
|
||||||
|
}
|
||||||
|
|
||||||
|
def contains(container, item, compare_func) : call_exists(range, container) {
|
||||||
|
auto t_range = range(container);
|
||||||
|
while (!t_range.empty()) {
|
||||||
|
if ( compare_func(t_range.front(), item) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_range.pop_front();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
def contains(container, item) {
|
||||||
|
return contains(container, item, eq)
|
||||||
|
}
|
||||||
|
|
||||||
|
def map(container, func, inserter) : call_exists(range, container) {
|
||||||
|
auto range = range(container);
|
||||||
|
while (!range.empty()) {
|
||||||
|
inserter(func(range.front()));
|
||||||
|
range.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Performs the second value function over the container first value. Creates a new container with the results
|
||||||
|
def map(container, func) {
|
||||||
|
auto retval = new(container);
|
||||||
|
map(container, func, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Performs the second value function over the container first value. Starts with initial and continues with each element.
|
||||||
|
def foldl(container, func, initial) : call_exists(range, container){
|
||||||
|
auto retval = initial;
|
||||||
|
auto range = range(container);
|
||||||
|
while (!range.empty()) {
|
||||||
|
retval = (func(range.front(), retval));
|
||||||
|
range.pop_front();
|
||||||
|
}
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the sum of the elements of the given value
|
||||||
|
def sum(container) {
|
||||||
|
foldl(container, `+`, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns the product of the elements of the given value
|
||||||
|
def product(container) {
|
||||||
|
foldl(container, `*`, 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Returns a new container with the elements of the first value concatenated with the elements of the second value
|
||||||
|
def concat(x, y) : call_exists(clone, x) {
|
||||||
|
auto retval = x;
|
||||||
|
auto inserter = back_inserter(retval);
|
||||||
|
auto range = range(y);
|
||||||
|
while (!range.empty()) {
|
||||||
|
inserter(range.front());
|
||||||
|
range.pop_front();
|
||||||
|
}
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def take(container, num, inserter) : call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
auto i = num;
|
||||||
|
while ((i > 0) && (!r.empty())) {
|
||||||
|
inserter(r.front());
|
||||||
|
r.pop_front();
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new container with the given number of elements taken from the container
|
||||||
|
def take(container, num) {
|
||||||
|
auto retval = new(container);
|
||||||
|
take(container, num, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def take_while(container, f, inserter) : call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
while ((!r.empty()) && f(r.front())) {
|
||||||
|
inserter(r.front());
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new container with the given elements match the second value function
|
||||||
|
def take_while(container, f) {
|
||||||
|
auto retval = new(container);
|
||||||
|
take_while(container, f, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def drop(container, num, inserter) : call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
auto i = num;
|
||||||
|
while ((i > 0) && (!r.empty())) {
|
||||||
|
r.pop_front();
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
while (!r.empty()) {
|
||||||
|
inserter(r.front());
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new container with the given number of elements dropped from the given container
|
||||||
|
def drop(container, num) {
|
||||||
|
auto retval = new(container);
|
||||||
|
drop(container, num, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def drop_while(container, f, inserter) : call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
while ((!r.empty())&& f(r.front())) {
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
while (!r.empty()) {
|
||||||
|
inserter(r.front());
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new container with the given elements dropped that match the second value function
|
||||||
|
def drop_while(container, f) {
|
||||||
|
auto retval = new(container);
|
||||||
|
drop_while(container, f, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements.
|
||||||
|
def reduce(container, func) : container.size() >= 2 && call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
auto retval = r.front();
|
||||||
|
r.pop_front();
|
||||||
|
retval = func(retval, r.front());
|
||||||
|
r.pop_front();
|
||||||
|
while (!r.empty()) {
|
||||||
|
retval = func(retval, r.front());
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a string of the elements in container delimited by the second value string
|
||||||
|
def join(container, delim) {
|
||||||
|
auto retval = "";
|
||||||
|
auto range = range(container);
|
||||||
|
if (!range.empty()) {
|
||||||
|
retval += to_string(range.front());
|
||||||
|
range.pop_front();
|
||||||
|
while (!range.empty()) {
|
||||||
|
retval += delim;
|
||||||
|
retval += to_string(range.front());
|
||||||
|
range.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def filter(container, f, inserter) : call_exists(range, container) {
|
||||||
|
auto r = range(container);
|
||||||
|
while (!r.empty()) {
|
||||||
|
if (f(r.front())) {
|
||||||
|
inserter(r.front());
|
||||||
|
}
|
||||||
|
r.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new Vector which match the second value function
|
||||||
|
def filter(container, f) {
|
||||||
|
auto retval = new(container);
|
||||||
|
filter(container, f, back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_range(x, y, inserter) {
|
||||||
|
auto i = x;
|
||||||
|
while (i <= y) {
|
||||||
|
inserter(i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new Vector which represents the range from the first value to the second value
|
||||||
|
def generate_range(x, y) {
|
||||||
|
auto retval = Vector();
|
||||||
|
generate_range(x,y,back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new Vector with the first value to the second value as its elements
|
||||||
|
def collate(x, y) {
|
||||||
|
return [x, y];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) {
|
||||||
|
auto r_x = range(x);
|
||||||
|
auto r_y = range(y);
|
||||||
|
while (!r_x.empty() && !r_y.empty()) {
|
||||||
|
inserter(f(r_x.front(), r_y.front()));
|
||||||
|
r_x.pop_front();
|
||||||
|
r_y.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new Vector which joins matching elements of the second and third value with the first value function
|
||||||
|
def zip_with(f, x, y) {
|
||||||
|
auto retval = Vector();
|
||||||
|
zip_with(f,x,y,back_inserter(retval));
|
||||||
|
retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns a new Vector which joins matching elements of the first and second
|
||||||
|
def zip(x, y) {
|
||||||
|
zip_with(collate, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of the second value string in the first value string
|
||||||
|
def string::find(substr) : is_type(substr, "string") {
|
||||||
|
int(find(this, substr, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of last match of the second value string in the first value string
|
||||||
|
def string::rfind(substr) : is_type(substr, "string") {
|
||||||
|
int(rfind(this, substr, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of the first match of elements in the second value string in the first value string
|
||||||
|
def string::find_first_of(list) : is_type(list, "string") {
|
||||||
|
int(find_first_of(this, list, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of the last match of elements in the second value string in the first value string
|
||||||
|
def string::find_last_of(list) : is_type(list, "string") {
|
||||||
|
int(find_last_of(this, list, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of the first non-matching element in the second value string in the first value string
|
||||||
|
def string::find_first_not_of(list) : is_type(list, "string") {
|
||||||
|
int(find_first_not_of(this, list, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Returns the position of the last non-matching element in the second value string in the first value string
|
||||||
|
def string::find_last_not_of(list) : is_type(list, "string") {
|
||||||
|
int(find_last_not_of(this, list, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def string::ltrim() {
|
||||||
|
drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def string::rtrim() {
|
||||||
|
reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def string::trim() {
|
||||||
|
ltrim(rtrim(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") {
|
||||||
|
auto range = range(container);
|
||||||
|
while (!range.empty()) {
|
||||||
|
if (compare_func(range.front(), value)) {
|
||||||
|
return range;
|
||||||
|
} else {
|
||||||
|
range.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def find(container, value) {
|
||||||
|
return find(container, value, eq)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
)"";
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CHAISCRIPT_PRELUDE_HPP_ */
|
@ -1,329 +0,0 @@
|
|||||||
// This file is distributed under the BSD License.
|
|
||||||
// See "license.txt" for details.
|
|
||||||
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
|
|
||||||
// and Jason Turner (jason@emptycrate.com)
|
|
||||||
// http://www.chaiscript.com
|
|
||||||
|
|
||||||
#ifndef CHAISCRIPT_PRELUDE_HPP_
|
|
||||||
#define CHAISCRIPT_PRELUDE_HPP_
|
|
||||||
|
|
||||||
//Note, the expression "[x,y]" in "collate" is parsed as two separate expressions
|
|
||||||
//by C++, so CODE_STRING, takes two expressions and adds in the missing comma
|
|
||||||
#define CODE_STRING(x, y) #x ", " #y
|
|
||||||
|
|
||||||
#define chaiscript_prelude CODE_STRING(\
|
|
||||||
def lt(l, r) { if (call_exists(`<`, l, r)) { l < r } else { type_name(l) < type_name(r) } } \n\
|
|
||||||
def gt(l, r) { if (call_exists(`>`, l, r)) { l > r } else { type_name(l) > type_name(r) } } \n\
|
|
||||||
def eq(l, r) { if (call_exists(`==`, l, r)) { l == r } else { false } } \n\
|
|
||||||
def new(x) { eval(type_name(x))(); } \n\
|
|
||||||
def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x) { eval(type_name(x))(x); } \n\
|
|
||||||
# to_string for Pair()\n\
|
|
||||||
def to_string(x) : call_exists(first, x) && call_exists(second, x) { \n\
|
|
||||||
"<" + x.first.to_string() + ", " + x.second.to_string() + ">"; \n\
|
|
||||||
}\n\
|
|
||||||
# to_string for containers\n\
|
|
||||||
def to_string(x) : call_exists(range, x) && !x.is_type("string"){ \n\
|
|
||||||
"[" + x.join(", ") + "]"; \n\
|
|
||||||
}\n\
|
|
||||||
# Basic to_string function\n\
|
|
||||||
def to_string(x) { \n\
|
|
||||||
internal_to_string(x); \n\
|
|
||||||
}\n\
|
|
||||||
# Prints to console with no carriage return\n\
|
|
||||||
def puts(x) { \n\
|
|
||||||
print_string(x.to_string()); \n\
|
|
||||||
} \n\
|
|
||||||
# Prints to console with carriage return\n\
|
|
||||||
def print(x) { \n\
|
|
||||||
println_string(x.to_string()); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the maximum value of two numbers\n\
|
|
||||||
def max(a, b) { if (a>b) { a } else { b } } \n\
|
|
||||||
# Returns the minimum value of two numbers\n\
|
|
||||||
def min(a, b) { if (a<b) { a } else { b } } \n\
|
|
||||||
# Returns true if the value is odd\n\
|
|
||||||
def odd(x) { if (x % 2 == 1) { true } else { false } } \n\
|
|
||||||
# Returns true if the value is even\n\
|
|
||||||
def even(x) { if (x % 2 == 0) { true } else { false } } \n\
|
|
||||||
# Pushes the second value onto the container first value while making a clone of the value\n\
|
|
||||||
def push_back(container, x) : call_exists(push_back_ref, container, x) { container.push_back_ref(clone(x)) } \n\
|
|
||||||
# Pushes the second value onto the front of the container first value while making a clone of the value\n\
|
|
||||||
def push_front(container, x) : call_exists(push_front_ref, container, x) { container.push_front_ref(clone(x)) } \n\
|
|
||||||
# Inserts the third value at the position of the second value into the container of the first\n\
|
|
||||||
# while making a clone. \n\
|
|
||||||
def insert_at(container, pos, x) { container.insert_ref_at(pos, clone(x)); } \n\
|
|
||||||
# Returns the reverse of the given container\n\
|
|
||||||
def reverse(container) {\n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
while (!r.empty()) { \n\
|
|
||||||
retval.push_back(r.back()); \n\
|
|
||||||
r.pop_back(); \n\
|
|
||||||
} \n\
|
|
||||||
retval; \n\
|
|
||||||
} \n\
|
|
||||||
# Return a range from a range \n\
|
|
||||||
def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r) { return clone(r); }\n\
|
|
||||||
# The retro attribute that contains the underlying range \n\
|
|
||||||
attr retro::m_range; \n\
|
|
||||||
# Creates a retro from a retro by returning the original range\n\
|
|
||||||
def retro(r) : call_exists(get_type_name, r) && get_type_name(r) == "retro" { clone(r.m_range) }\n\
|
|
||||||
# Creates a retro range from a range\n\
|
|
||||||
def retro::retro(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r) { this.m_range = r; }\n\
|
|
||||||
# Returns the first value of a retro\n\
|
|
||||||
def retro::front() { back(this.m_range) }\n\
|
|
||||||
# Returns the last value of a retro\n\
|
|
||||||
def retro::back() { front(this.m_range) }\n\
|
|
||||||
# Moves the back iterator of a retro towards the front by one \n\
|
|
||||||
def retro::pop_back() { pop_front(this.m_range) }\n\
|
|
||||||
# Moves the front iterator of a retro towards the back by one \n\
|
|
||||||
def retro::pop_front() { pop_back(this.m_range) } \n\
|
|
||||||
# returns true if the retro is out of elements \n\
|
|
||||||
def retro::empty() { empty(this.m_range); } \n\
|
|
||||||
# Performs the second value function over the container first value\n\
|
|
||||||
def for_each(container, func) : call_exists(range, container) { \n\
|
|
||||||
auto t_range = range(container); \n\
|
|
||||||
while (!t_range.empty()) { \n\
|
|
||||||
func(t_range.front()); \n\
|
|
||||||
t_range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
def back_inserter(container) { \n\
|
|
||||||
bind(push_back, container, _); \n\
|
|
||||||
}\n\
|
|
||||||
\n\
|
|
||||||
def contains(container, item, compare_func) : call_exists(range, container) { \n\
|
|
||||||
auto t_range = range(container); \n\
|
|
||||||
while (!t_range.empty()) { \n\
|
|
||||||
if ( compare_func(t_range.front(), item) ) { return true; } \n\
|
|
||||||
t_range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
return false; \n\
|
|
||||||
} \n\
|
|
||||||
def contains(container, item) { return contains(container, item, eq) } \n\
|
|
||||||
def map(container, func, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto range = range(container); \n\
|
|
||||||
while (!range.empty()) { \n\
|
|
||||||
inserter(func(range.front())); \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Performs the second value function over the container first value. Creates a new container with the results\n\
|
|
||||||
def map(container, func) { \n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
map(container, func, back_inserter(retval));\n\
|
|
||||||
retval;\n\
|
|
||||||
}\n\
|
|
||||||
# Performs the second value function over the container first value. Starts with initial and continues with each element.\n\
|
|
||||||
def foldl(container, func, initial) : call_exists(range, container){ \n\
|
|
||||||
auto retval = initial; \n\
|
|
||||||
auto range = range(container); \n\
|
|
||||||
while (!range.empty()) { \n\
|
|
||||||
retval = (func(range.front(), retval)); \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
retval; \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the sum of the elements of the given value\n\
|
|
||||||
def sum(container) { foldl(container, `+`, 0.0) } \n\
|
|
||||||
# Returns the product of the elements of the given value\n\
|
|
||||||
def product(container) { foldl(container, `*`, 1.0) } \n\
|
|
||||||
# Returns a new container with the elements of the first value concatenated with the elements of the second value\n\
|
|
||||||
def concat(x, y) : call_exists(clone, x) { \n\
|
|
||||||
auto retval = x; \n\
|
|
||||||
auto inserter = back_inserter(retval); \n\
|
|
||||||
auto range = range(y); \n\
|
|
||||||
while (!range.empty()) { \n\
|
|
||||||
inserter(range.front()); \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
retval; \n\
|
|
||||||
} \n\
|
|
||||||
def take(container, num, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
auto i = num; \n\
|
|
||||||
while ((i > 0) && (!r.empty())) { \n\
|
|
||||||
inserter(r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
--i; \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new container with the given number of elements taken from the container\n\
|
|
||||||
def take(container, num) {\n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
take(container, num, back_inserter(retval)); \n\
|
|
||||||
retval; \n\
|
|
||||||
}\n\
|
|
||||||
def take_while(container, f, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
while ((!r.empty()) && f(r.front())) { \n\
|
|
||||||
inserter(r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new container with the given elements match the second value function\n\
|
|
||||||
def take_while(container, f) {\n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
take_while(container, f, back_inserter(retval)); \n\
|
|
||||||
retval;\n\
|
|
||||||
}\n\
|
|
||||||
def drop(container, num, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
auto i = num; \n\
|
|
||||||
while ((i > 0) && (!r.empty())) { \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
--i; \n\
|
|
||||||
} \n\
|
|
||||||
while (!r.empty()) { \n\
|
|
||||||
inserter(r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new container with the given number of elements dropped from the given container \n\
|
|
||||||
def drop(container, num) {\n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
drop(container, num, back_inserter(retval)); \n\
|
|
||||||
retval; \n\
|
|
||||||
}\n\
|
|
||||||
def drop_while(container, f, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
while ((!r.empty())&& f(r.front())) { \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
while (!r.empty()) { \n\
|
|
||||||
inserter(r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new container with the given elements dropped that match the second value function\n\
|
|
||||||
def drop_while(container, f) {\n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
drop_while(container, f, back_inserter(retval)); \n\
|
|
||||||
retval; \n\
|
|
||||||
}\n\
|
|
||||||
# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements.\n\
|
|
||||||
def reduce(container, func) : container.size() >= 2 && call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
auto retval = r.front(); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
retval = func(retval, r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
while (!r.empty()) { \n\
|
|
||||||
retval = func(retval, r.front()); \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
retval; \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a string of the elements in container delimited by the second value string\n\
|
|
||||||
def join(container, delim) { \n\
|
|
||||||
auto retval = ""; \n\
|
|
||||||
auto range = range(container); \n\
|
|
||||||
if (!range.empty()) { \n\
|
|
||||||
retval += to_string(range.front()); \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
while (!range.empty()) { \n\
|
|
||||||
retval += delim; \n\
|
|
||||||
retval += to_string(range.front()); \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
retval; \n\
|
|
||||||
} \n\
|
|
||||||
def filter(container, f, inserter) : call_exists(range, container) { \n\
|
|
||||||
auto r = range(container); \n\
|
|
||||||
while (!r.empty()) { \n\
|
|
||||||
if (f(r.front())) { \n\
|
|
||||||
inserter(r.front()); \n\
|
|
||||||
} \n\
|
|
||||||
r.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new Vector which match the second value function\n\
|
|
||||||
def filter(container, f) { \n\
|
|
||||||
auto retval = new(container); \n\
|
|
||||||
filter(container, f, back_inserter(retval));\n\
|
|
||||||
retval;\n\
|
|
||||||
}\n\
|
|
||||||
def generate_range(x, y, inserter) { \n\
|
|
||||||
auto i = x; \n\
|
|
||||||
while (i <= y) { \n\
|
|
||||||
inserter(i); \n\
|
|
||||||
++i; \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new Vector which represents the range from the first value to the second value\n\
|
|
||||||
def generate_range(x, y) { \n\
|
|
||||||
auto retval = Vector(); \n\
|
|
||||||
generate_range(x,y,back_inserter(retval)); \n\
|
|
||||||
retval; \n\
|
|
||||||
}\n\
|
|
||||||
# Returns a new Vector with the first value to the second value as its elements\n\
|
|
||||||
def collate(x, y) { \n\
|
|
||||||
return [x, y]; \n\
|
|
||||||
} \n\
|
|
||||||
def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) { \n\
|
|
||||||
auto r_x = range(x); \n\
|
|
||||||
auto r_y = range(y); \n\
|
|
||||||
while (!r_x.empty() && !r_y.empty()) { \n\
|
|
||||||
inserter(f(r_x.front(), r_y.front())); \n\
|
|
||||||
r_x.pop_front(); \n\
|
|
||||||
r_y.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
# Returns a new Vector which joins matching elements of the second and third value with the first value function\n\
|
|
||||||
def zip_with(f, x, y) { \n\
|
|
||||||
auto retval = Vector(); \n\
|
|
||||||
zip_with(f,x,y,back_inserter(retval)); \n\
|
|
||||||
retval;\n\
|
|
||||||
}\n\
|
|
||||||
# Returns a new Vector which joins matching elements of the first and second\n\
|
|
||||||
def zip(x, y) { \n\
|
|
||||||
zip_with(collate, x, y); \n\
|
|
||||||
}\n\
|
|
||||||
# Returns the position of the second value string in the first value string\n\
|
|
||||||
def string::find(substr) : is_type(substr, "string") { \n\
|
|
||||||
int(find(this, substr, 0)); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the position of last match of the second value string in the first value string\n\
|
|
||||||
def string::rfind(substr) : is_type(substr, "string") { \n\
|
|
||||||
int(rfind(this, substr, -1)); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the position of the first match of elements in the second value string in the first value string\n\
|
|
||||||
def string::find_first_of(list) : is_type(list, "string") { \n\
|
|
||||||
int(find_first_of(this, list, 0)); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the position of the last match of elements in the second value string in the first value string\n\
|
|
||||||
def string::find_last_of(list) : is_type(list, "string") { \n\
|
|
||||||
int(find_last_of(this, list, -1)); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the position of the first non-matching element in the second value string in the first value string\n\
|
|
||||||
def string::find_first_not_of(list) : is_type(list, "string") { \n\
|
|
||||||
int(find_first_not_of(this, list, 0)); \n\
|
|
||||||
} \n\
|
|
||||||
# Returns the position of the last non-matching element in the second value string in the first value string\n\
|
|
||||||
def string::find_last_not_of(list) : is_type(list, "string") { \n\
|
|
||||||
int(find_last_not_of(this, list, -1)); \n\
|
|
||||||
} \n\
|
|
||||||
def string::ltrim() { \n\
|
|
||||||
drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}); \n\
|
|
||||||
} \n\
|
|
||||||
def string::rtrim() { \n\
|
|
||||||
reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'})); \n\
|
|
||||||
} \n\
|
|
||||||
def string::trim() { \n\
|
|
||||||
ltrim(rtrim(this)); \n\
|
|
||||||
} \n\
|
|
||||||
def find(container, value, compare_func) : call_exists(range, container) && is_type(compare_func, "Function") { \n\
|
|
||||||
auto range = range(container); \n\
|
|
||||||
while (!range.empty()) { \n\
|
|
||||||
if (compare_func(range.front(), value)) { \n\
|
|
||||||
return range; \n\
|
|
||||||
} else { \n\
|
|
||||||
range.pop_front(); \n\
|
|
||||||
} \n\
|
|
||||||
} \n\
|
|
||||||
return range; \n\
|
|
||||||
} \n\
|
|
||||||
def find(container, value) { return find(container, value, eq) } \
|
|
||||||
)
|
|
||||||
#endif /* CHAISCRIPT_PRELUDE_HPP_ */
|
|
Loading…
x
Reference in New Issue
Block a user