GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
chaiscript_prelude.hpp
Go to the documentation of this file.
1// This file is distributed under the BSD License.
2// See "license.txt" for details.
3// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4// and 2009-2017, Jason Turner (jason@emptycrate.com)
5// http://www.chaiscript.com
6
7#ifndef CHAISCRIPT_PRELUDE_HPP_
8#define CHAISCRIPT_PRELUDE_HPP_
9
10namespace chaiscript {
12 static std::string chaiscript_prelude() { return R"chaiscript(
13
14def lt(l, r) {
15 if (call_exists(`<`, l, r)) {
16 l < r
17 } else {
18 type_name(l) < type_name(r)
19 }
20}
21
22
23def gt(l, r) {
24 if (call_exists(`>`, l, r)) {
25 l > r
26 } else {
27 type_name(l) > type_name(r)
28 }
29}
30
31def eq(l, r) {
32 if (call_exists(`==`, l, r)) {
33 l == r
34 } else {
35 false
36 }
37}
38
39def new(x) {
40 eval(type_name(x))();
41}
42
43def clone(double x) {
44 double(x).clone_var_attrs(x)
45}
46
47def clone(string x) {
48 string(x).clone_var_attrs(x)
49}
50
51def clone(vector x) {
52 vector(x).clone_var_attrs(x)
53}
54
55
56def clone(int x) {
57 int(x).clone_var_attrs(x)
58}
59
60def clone(x) : function_exists(type_name(x)) && call_exists(eval(type_name(x)), x)
61{
62 eval(type_name(x))(x).clone_var_attrs(x);
63}
64
65
66# to_string for Pair()
67def to_string(x) : call_exists(first, x) && call_exists(second, x) {
68 "<" + x.first.to_string() + ", " + x.second.to_string() + ">";
69}
70
71# to_string for containers
72def to_string(x) : call_exists(range, x) && !x.is_type("string"){
73 "[" + x.join(", ") + "]";
74}
75
76# Prints to console with no carriage return
77def puts(x) {
78 print_string(x.to_string());
79}
80
81# Prints to console with carriage return
82def print(x) {
83 println_string(x.to_string());
84}
85
86# Returns the maximum value of two numbers
87def max(a, b) {
88 if (a>b) {
89 a
90 } else {
91 b
92 }
93}
94
95# Returns the minimum value of two numbers
96def min(a, b)
97{
98 if (a<b)
99 {
100 a
101 } else {
102 b
103 }
104}
105
106
107# Returns true if the value is odd
108def odd(x) {
109 if (x % 2 == 1)
110 {
111 true
112 } else {
113 false
114 }
115}
116
117
118# Returns true if the value is even
119def even(x)
120{
121 if (x % 2 == 0)
122 {
123 true
124 } else {
125 false
126 }
127}
128
129
130# Inserts the third value at the position of the second value into the container of the first
131# while making a clone.
132def insert_at(container, pos, x)
133{
134 container.insert_ref_at(pos, clone(x));
135}
136
137# Returns the reverse of the given container
138def reverse(container) {
139 auto retval := new(container);
140 auto r := range(container);
141 while (!r.empty()) {
142 retval.push_back(r.back());
143 r.pop_back();
144 }
145 retval;
146}
147
148
149def range(r) : call_exists(range_internal, r)
150{
151 var ri := range_internal(r);
152 ri.get_var_attr("internal_obj") := r;
153 ri;
154}
155
156# Return a range from a range
157def range(r) : call_exists(empty, r) && call_exists(pop_front, r) && call_exists(pop_back, r) && call_exists(back, r) && call_exists(front, r)
158{
159 clone(r);
160}
161
162
163# The retro attribute that contains the underlying range
164attr retro::m_range;
165
166# Creates a retro from a retro by returning the original range
167def retro(r) : call_exists(get_type_name, r) && get_type_name(r) == "retro"
168{
169 clone(r.m_range)
170}
171
172
173# Creates a retro range from a range
174def 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)
175{
176 this.m_range = r;
177}
178
179# Returns the first value of a retro
180def retro::front()
181{
182 back(this.m_range)
183}
184
185# Returns the last value of a retro
186def retro::back()
187{
188 front(this.m_range)
189}
190
191# Moves the back iterator of a retro towards the front by one
192def retro::pop_back()
193{
194 pop_front(this.m_range)
195}
196
197# Moves the front iterator of a retro towards the back by one
198def retro::pop_front()
199{
200 pop_back(this.m_range)
201}
202
203# returns true if the retro is out of elements
204def retro::empty()
205{
206 empty(this.m_range);
207}
208
209# Performs the second value function over the container first value
210def for_each(container, func) : call_exists(range, container) {
211 var t_range := range(container);
212 while (!t_range.empty()) {
213 func(t_range.front());
214 t_range.pop_front();
215 }
216}
217
218def any_of(container, func) : call_exists(range, container) {
219 var t_range := range(container);
220 while (!t_range.empty()) {
221 if (func(t_range.front())) {
222 return true;
223 }
224 t_range.pop_front();
225 }
226 false;
227}
228
229def all_of(container, func) : call_exists(range, container) {
230 var t_range := range(container);
231 while (!t_range.empty()) {
232 if (!func(t_range.front())) {
233 return false;
234 }
235 t_range.pop_front();
236 }
237
238 true;
239}
240
241def back_inserter(container) {
242 bind(push_back, container, _);
243}
244
245def contains(container, item, compare_func) : call_exists(range, container) {
246 auto t_range := range(container);
247 while (!t_range.empty()) {
248 if ( compare_func(t_range.front(), item) ) {
249 return true;
250 }
251
252 t_range.pop_front();
253 }
254 false;
255}
256
257def contains(container, item) {
258 contains(container, item, eq)
259}
260
261def map(container, func, inserter) : call_exists(range, container) {
262 auto range := range(container);
263 while (!range.empty()) {
264 inserter(func(range.front()));
265 range.pop_front();
266 }
267}
268
269# Performs the second value function over the container first value. Creates a new container with the results
270def map(container, func) {
271 auto retval := new(container);
272 map(container, func, back_inserter(retval));
273 retval;
274}
275
276# Performs the second value function over the container first value. Starts with initial and continues with each element.
277def foldl(container, func, initial) : call_exists(range, container){
278 auto retval = initial;
279 auto range := range(container);
280 while (!range.empty()) {
281 retval = (func(range.front(), retval));
282 range.pop_front();
283 }
284 retval;
285}
286
287# Returns the sum of the elements of the given value
288def sum(container) {
289 foldl(container, `+`, 0.0)
290}
291
292# Returns the product of the elements of the given value
293def product(container) {
294 foldl(container, `*`, 1.0)
295}
296
297# Returns a new container with the elements of the first value concatenated with the elements of the second value
298def concat(x, y) : call_exists(clone, x) {
299 auto retval = x;
300 auto inserter := back_inserter(retval);
301 auto range := range(y);
302 while (!range.empty()) {
303 inserter(range.front());
304 range.pop_front();
305 }
306 retval;
307}
308
309
310def take(container, num, inserter) : call_exists(range, container) {
311 auto r := range(container);
312 auto i = num;
313 while ((i > 0) && (!r.empty())) {
314 inserter(r.front());
315 r.pop_front();
316 --i;
317 }
318}
319
320
321# Returns a new container with the given number of elements taken from the container
322def take(container, num) {
323 auto retval := new(container);
324 take(container, num, back_inserter(retval));
325 retval;
326}
327
328
329def take_while(container, f, inserter) : call_exists(range, container) {
330 auto r := range(container);
331 while ((!r.empty()) && f(r.front())) {
332 inserter(r.front());
333 r.pop_front();
334 }
335}
336
337
338# Returns a new container with the given elements match the second value function
339def take_while(container, f) {
340 auto retval := new(container);
341 take_while(container, f, back_inserter(retval));
342 retval;
343}
344
345
346def drop(container, num, inserter) : call_exists(range, container) {
347 auto r := range(container);
348 auto i = num;
349 while ((i > 0) && (!r.empty())) {
350 r.pop_front();
351 --i;
352 }
353 while (!r.empty()) {
354 inserter(r.front());
355 r.pop_front();
356 }
357}
358
359
360# Returns a new container with the given number of elements dropped from the given container
361def drop(container, num) {
362 auto retval := new(container);
363 drop(container, num, back_inserter(retval));
364 retval;
365}
366
367
368def drop_while(container, f, inserter) : call_exists(range, container) {
369 auto r := range(container);
370 while ((!r.empty())&& f(r.front())) {
371 r.pop_front();
372 }
373 while (!r.empty()) {
374 inserter(r.front());
375 r.pop_front();
376 }
377}
378
379
380# Returns a new container with the given elements dropped that match the second value function
381def drop_while(container, f) {
382 auto retval := new(container);
383 drop_while(container, f, back_inserter(retval));
384 retval;
385}
386
387
388# Applies the second value function to the container. Starts with the first two elements. Expects at least 2 elements.
389def reduce(container, func) : container.size() >= 2 && call_exists(range, container) {
390 auto r := range(container);
391 auto retval = r.front();
392 r.pop_front();
393 retval = func(retval, r.front());
394 r.pop_front();
395 while (!r.empty()) {
396 retval = func(retval, r.front());
397 r.pop_front();
398 }
399 retval;
400}
401
402
403# Returns a string of the elements in container delimited by the second value string
404def join(container, delim) {
405 auto retval = "";
406 auto range := range(container);
407 if (!range.empty()) {
408 retval += to_string(range.front());
409 range.pop_front();
410 while (!range.empty()) {
411 retval += delim;
412 retval += to_string(range.front());
413 range.pop_front();
414 }
415 }
416 retval;
417}
418
419
420def filter(container, f, inserter) : call_exists(range, container) {
421 auto r := range(container);
422 while (!r.empty()) {
423 if (f(r.front())) {
424 inserter(r.front());
425 }
426 r.pop_front();
427 }
428}
429
430
431# Returns a new Vector which match the second value function
432def filter(container, f) {
433 auto retval := new(container);
434 filter(container, f, back_inserter(retval));
435 retval;
436}
437
438
439def generate_range(x, y, inserter) {
440 auto i = x;
441 while (i <= y) {
442 inserter(i);
443 ++i;
444 }
445}
446
447
448# Returns a new Vector which represents the range from the first value to the second value
449def generate_range(x, y) {
450 auto retval := Vector();
451 generate_range(x,y,back_inserter(retval));
452 retval;
453}
454
455
456# Returns a new Vector with the first value to the second value as its elements
457def collate(x, y) {
458 return [x, y];
459}
460
461
462def zip_with(f, x, y, inserter) : call_exists(range, x) && call_exists(range, y) {
463 auto r_x := range(x);
464 auto r_y := range(y);
465 while (!r_x.empty() && !r_y.empty()) {
466 inserter(f(r_x.front(), r_y.front()));
467 r_x.pop_front();
468 r_y.pop_front();
469 }
470}
471
472
473# Returns a new Vector which joins matching elements of the second and third value with the first value function
474def zip_with(f, x, y) {
475 auto retval := Vector();
476 zip_with(f,x,y,back_inserter(retval));
477 retval;
478}
479
480
481# Returns a new Vector which joins matching elements of the first and second
482def zip(x, y) {
483 zip_with(collate, x, y);
484}
485
486
487# Returns the position of the second value string in the first value string
488def string::find(string substr) {
489 find(this, substr, size_t(0));
490}
491
492
493# Returns the position of last match of the second value string in the first value string
494def string::rfind(string substr) {
495 rfind(this, substr, size_t(-1));
496}
497
498
499# Returns the position of the first match of elements in the second value string in the first value string
500def string::find_first_of(string list) {
501 find_first_of(this, list, size_t(0));
502}
503
504
505# Returns the position of the last match of elements in the second value string in the first value string
506def string::find_last_of(string list) {
507 find_last_of(this, list, size_t(-1));
508}
509
510
511# Returns the position of the first non-matching element in the second value string in the first value string
512def string::find_first_not_of(string list) {
513 find_first_not_of(this, list, size_t(0));
514}
515
516
517# Returns the position of the last non-matching element in the second value string in the first value string
518def string::find_last_not_of(string list) {
519 find_last_not_of(this, list, size_t(-1));
520}
521
522
523def string::ltrim() {
524 drop_while(this, fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'});
525}
526
527
528def string::rtrim() {
529 reverse(drop_while(reverse(this), fun(x) { x == ' ' || x == '\t' || x == '\r' || x == '\n'}));
530}
531
532
533def string::trim() {
534 ltrim(rtrim(this));
535}
536
537
538def find(container, value, Function compare_func) : call_exists(range, container) {
539 auto range := range(container);
540 while (!range.empty()) {
541 if (compare_func(range.front(), value)) {
542 return range;
543 } else {
544 range.pop_front();
545 }
546 }
547 range;
548}
549
550
551def find(container, value) {
552 find(container, value, eq)
553}
554
555
556)chaiscript";
557}
558
559};
560}
561
562#endif /* CHAISCRIPT_PRELUDE_HPP_ */
Namespace chaiscript contains every API call that the average user will be concerned with.
Definition chaiscript_prelude.hpp:11
static std::string chaiscript_prelude()
Definition chaiscript_prelude.hpp:12