Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_function_script.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * afw_function_execute_* functions for adaptive script
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 /*
19  * Adaptive function: assign
20  *
21  * afw_function_execute_assign
22  *
23  * See afw_function_bindings.h for more information.
24  *
25  * Assign a value to the innermost structured block definition of a variable.
26  * If the variable is not defined, the variable is defined in the innermost
27  * structured block. An error is thrown if not called from a list of values in
28  * a structured function.
29  *
30  * This function is not pure, so it may return a different result
31  * given exactly the same parameters and has side effects.
32  *
33  * Declaration:
34  *
35  * ```
36  * function assign(
37  * name: string,
38  * value: any
39  * ): any;
40  * ```
41  *
42  * Parameters:
43  *
44  * name - (string) Variable name.
45  *
46  * value - (any dataType) This is the value to assign to the variable.
47  *
48  * Returns:
49  *
50  * (any dataType) The value assigned.
51  */
52 const afw_value_t *
55 {
56  /* Only allowed in a block value. See afw_value_block.c */
57  AFW_THROW_ERROR_Z(general, "Misplaced assign()", x->xctx);
58 }
59 
60 
61 
62 /*
63  * Adaptive function: break
64  *
65  * afw_function_execute_break
66  *
67  * See afw_function_bindings.h for more information.
68  *
69  * This is a special function that can be called to break out of the body of a
70  * loop. If called outside of a loop body, an error is thrown.
71  *
72  * This function is pure, so it will always return the same result
73  * given exactly the same parameters and has no side effects.
74  *
75  * Declaration:
76  *
77  * ```
78  * function break(
79  * value?: any
80  * ): any;
81  * ```
82  *
83  * Parameters:
84  *
85  * value - (optional any dataType) The value to evaluate that the enclosing
86  * loop will return. If not specified, the last evaluated value or a null
87  * value will be returned.
88  *
89  * Returns:
90  *
91  * (any dataType) This function returns from the body of a loop with the last
92  * evaluated value.
93  */
94 const afw_value_t *
97 {
98  /* Only allowed in a block value. See afw_value_block.c */
99  AFW_THROW_ERROR_Z(general, "Misplaced break()", x->xctx);
100 }
101 
102 
103 
104 /*
105  * Adaptive function: compile<script>
106  *
107  * afw_function_execute_compile_script
108  *
109  * See afw_function_bindings.h for more information.
110  *
111  * Compile script value and return either an unevaluated adaptive value or a
112  * string containing the compiler listing.
113  *
114  * This function is pure, so it will always return the same result
115  * given exactly the same parameters and has no side effects.
116  *
117  * Declaration:
118  *
119  * ```
120  * function compile<script>(
121  * source: script,
122  * listing?: any
123  * ): unevaluated;
124  * ```
125  *
126  * Parameters:
127  *
128  * source - (script) script string to compile.
129  *
130  * listing - (optional any dataType) If specified, a compiler listing is
131  * produced instead of an unevaluated expression value.
132  *
133  * This parameter can be an integer between 0 and 10 of a string that is
134  * used for indentation. If 0 is specified, no whitespace is added to the
135  * resulting string. If 1 through 10 is specified, that number of spaces
136  * is used.
137  *
138  * Returns:
139  *
140  * (unevaluated)
141  */
142 const afw_value_t *
145 {
146  const afw_value_script_t *script;
147  const afw_value_t *result;
148  const afw_utf8_t *listing;
149 
151 
152  result = afw_compile_to_value(
153  &script->internal, AFW_FUNCTION_SOURCE_LOCATION,
154  afw_compile_type_script,
155  NULL, NULL, x->p, x->xctx);
156 
158  listing = afw_function_evaluate_whitespace_parameter(x, 2);
159  result = afw_value_create_string(
160  afw_value_compiler_listing_to_string(result, listing,
161  x->p, x->xctx),
162  x->p, x->xctx);
163  }
164 
165  return result;
166 }
167 
168 
169 
170 /*
171  * Adaptive function: const
172  *
173  * afw_function_execute_const
174  *
175  * See afw_function_bindings.h for more information.
176  *
177  * Define one or more statically scoped constants local to the current script
178  * block with a permanent value. These constants can be accessed from the
179  * current block and inner blocks, but can not be assigned a different value.
180  *
181  * This function is pure, so it will always return the same result
182  * given exactly the same parameters and has no side effects.
183  *
184  * Declaration:
185  *
186  * ```
187  * function const(
188  * name: (list string),
189  * value: any,
190  * type?: (object _AdaptiveValueMeta_)
191  * ): any;
192  * ```
193  *
194  * Parameters:
195  *
196  * name - (list string) The name of one or more constants to defined in the
197  * current block.
198  *
199  * value - (any dataType) This is the value of the constant(s).
200  *
201  * type - (optional object _AdaptiveValueMeta_) The type of the constant(s).
202  *
203  * Returns:
204  *
205  * (any dataType) The value assigned.
206  */
207 const afw_value_t *
210 {
211  /* Only allowed in a block value. See afw_value_block.c */
212  AFW_THROW_ERROR_Z(general, "Misplaced const()", x->xctx);
213 }
214 
215 
216 
217 /*
218  * Adaptive function: continue
219  *
220  * afw_function_execute_continue
221  *
222  * See afw_function_bindings.h for more information.
223  *
224  * This is a special function that can be called in the body of a loop function
225  * to test the condition and, if true, start evaluating the body again. If
226  * called outside of a loop body, an error is thrown.
227  *
228  * This function is pure, so it will always return the same result
229  * given exactly the same parameters and has no side effects.
230  *
231  * Declaration:
232  *
233  * ```
234  * function continue(
235  *
236  * ): any;
237  * ```
238  *
239  * Parameters:
240  *
241  * Returns:
242  *
243  * (any dataType) This function does not return.
244  */
245 const afw_value_t *
248 {
249  /* Only allowed in a block value. See afw_value_block.c */
250  AFW_THROW_ERROR_Z(general, "Misplaced continue()", x->xctx);
251 }
252 
253 
254 
255 /*
256  * Adaptive function: do_while
257  *
258  * afw_function_execute_do_while
259  *
260  * See afw_function_bindings.h for more information.
261  *
262  * This creates a new structured block with a new nested variable scope.
263  *
264  * This function will evaluate a list of values at least once while a condition
265  * is true. See the related functions "break", "continue", and "return".
266  *
267  * This function is pure, so it will always return the same result
268  * given exactly the same parameters and has no side effects.
269  *
270  * Declaration:
271  *
272  * ```
273  * function do_while(
274  * condition: boolean,
275  * body: list
276  * ): any;
277  * ```
278  *
279  * Parameters:
280  *
281  * condition - (boolean) While this condition is true, the loop will
282  * continue. This is evaluated in the loop's scope.
283  *
284  * body - (list) This is a list of values that are evaluated for each
285  * iteration of the loop. Each value in body is evaluated in order until
286  * the end of the list or until a "break", "continue" or "return"
287  * function is encountered.
288  *
289  * Returns:
290  *
291  * (any dataType) The last value evaluated in body or null if the body is
292  * empty.
293  */
294 const afw_value_t *
297 {
298  const afw_value_t *result;
299  afw_value_block_statement_type_t type;
300 
301  /* Can be called outside of a block, but usually part of a block value. */
302  result = afw_value_block_evaluate_do_while(x,
303  &type, x->argc, x->argv, x->p, x->xctx);
304 
305  return result;
306 }
307 
308 
309 
310 /*
311  * Adaptive function: evaluate<script>
312  *
313  * afw_function_execute_evaluate_script
314  *
315  * See afw_function_bindings.h for more information.
316  *
317  * Compile and evaluate script value.
318  *
319  * This function is not pure, so it may return a different result
320  * given exactly the same parameters.
321  *
322  * Declaration:
323  *
324  * ```
325  * function evaluate<script>(
326  * source: script,
327  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
328  * ): unevaluated;
329  * ```
330  *
331  * Parameters:
332  *
333  * source - (script) script string to compile and evaluate.
334  *
335  * additionalUntrustedQualifiedVariables - (optional object
336  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
337  * qualified variables that can be accessed during evaluation. These
338  * variables will not be used by anything that needs to ensure its
339  * qualified variables must come from a trusted source, such as
340  * authorization. This parameter is intended to be used for testing only
341  * and should not be used for anything running in production.
342  *
343  * Returns:
344  *
345  * (unevaluated)
346  */
347 const afw_value_t *
350 {
351  const afw_value_script_t *script;
352  const afw_value_t *compiled;
353  const afw_value_t *value;
354 
356 
357  compiled = afw_compile_to_value(
358  &script->internal, AFW_FUNCTION_SOURCE_LOCATION,
359  afw_compile_type_script,
360  NULL, NULL, x->p, x->xctx);
361 
364  compiled, x->argv[2], x->p, x->xctx);
365  }
366  else {
367  value = afw_value_evaluate(compiled, x->p, x->xctx);
368  }
369 
370  return value;
371 }
372 
373 
374 
375 /*
376  * Adaptive function: for
377  *
378  * afw_function_execute_for
379  *
380  * See afw_function_bindings.h for more information.
381  *
382  * This creates a new structured block with a new nested variable scope.
383  *
384  * This function loops while condition is true. If the condition is false for
385  * the first iteration, the loop returns a null value.
386  *
387  * This function is pure, so it will always return the same result
388  * given exactly the same parameters and has no side effects.
389  *
390  * Declaration:
391  *
392  * ```
393  * function for(
394  * initial?: list,
395  * condition?: boolean,
396  * increment?: list,
397  * body?: list
398  * ): any;
399  * ```
400  *
401  * Parameters:
402  *
403  * initial - (optional list) This is a list of values to evaluate before the
404  * loop starts. The values will normally be a call to the "assign"
405  * function.
406  *
407  * condition - (optional boolean) While this condition is true, the loop will
408  * continue.
409  *
410  * increment - (optional list) This is a list of values to evaluate after
411  * each iteration of the loop. The values will normally be a call to the
412  * "assign" function.
413  *
414  * body - (optional list) This is a list of values that are evaluated for
415  * each iteration of the loop. Each value in body is evaluated in order
416  * until the end of the list or until a "break", "continue" or "return"
417  * function is encountered.
418  *
419  * Returns:
420  *
421  * (any dataType) The last value evaluated in body or null if condition
422  * evaluates to false the first time.
423  */
424 const afw_value_t *
427 {
428  const afw_value_t *result;
429  afw_value_block_statement_type_t type;
430 
431  /* Can be called outside of a block, but usually part of a block value. */
432  result = afw_value_block_evaluate_for(x,
433  &type, x->argc, x->argv, x->p, x->xctx);
434 
435  return result;
436 }
437 
438 
439 
440 /*
441  * Adaptive function: foreach
442  *
443  * afw_function_execute_foreach
444  *
445  * See afw_function_bindings.h for more information.
446  *
447  * This creates a new structured block with a new nested variable scope.
448  *
449  * This function will evaluate a list of values while a condition is true with
450  * initial and increment values. The condition is tested at the beginning of
451  * the loop. If the condition is false for the first iteration, the loop
452  * returns a null value.
453  *
454  * This function is pure, so it will always return the same result
455  * given exactly the same parameters and has no side effects.
456  *
457  * Declaration:
458  *
459  * ```
460  * function foreach(
461  * name: (list string),
462  * value: any,
463  * body?: list
464  * ): any;
465  * ```
466  *
467  * Parameters:
468  *
469  * name - (list string) Variable name(s).
470  *
471  * value - (any dataType) Any list, object or single value.
472  *
473  * body - (optional list) This is a list of values that are evaluated for
474  * each iteration of the loop. Each value in body is evaluated in order
475  * until the end of the list or until a "break", "continue" or "return"
476  * function is encountered.
477  *
478  * Returns:
479  *
480  * (any dataType) The last value evaluated in body or null if condition
481  * evaluates to false the first time.
482  */
483 const afw_value_t *
486 {
487  const afw_value_t *result;
488  afw_value_block_statement_type_t type;
489 
490  /* Can be called outside of a block, but usually part of a block value. */
491  result = afw_value_block_evaluate_foreach(x,
492  &type, x->argc, x->argv, x->p, x->xctx);
493 
494  return result;
495 }
496 
497 
498 
499 /*
500  * Adaptive function: if
501  *
502  * afw_function_execute_if
503  *
504  * See afw_function_bindings.h for more information.
505  *
506  * Evaluate one of two different values depending on test condition.
507  *
508  * This function is pure, so it will always return the same result
509  * given exactly the same parameters and has no side effects.
510  *
511  * Declaration:
512  *
513  * ```
514  * function if(
515  * condition: boolean,
516  * then: list,
517  * else?: list
518  * ): any;
519  * ```
520  *
521  * Parameters:
522  *
523  * condition - (boolean) If true, parameter "then" is evaluated for result.
524  * If false, parameter "else" is evaluated.
525  *
526  * then - (list) This is the body of a structured block that is evaluated if
527  * "condition" is true. See the "body" parameter of the "block" function
528  * for information on how the body is processed.
529  *
530  * else - (optional list) This is the body of a structured block that is
531  * evaluated if "condition" is false. If not specified and condition is
532  * false, a null value is returned. See the "body" parameter of the
533  * "block" function for information on how the body is processed.
534  *
535  * Returns:
536  *
537  * (any dataType) The result of evaluating "then" or "else".
538  */
539 const afw_value_t *
542 {
543  const afw_value_t *result;
544  afw_value_block_statement_type_t type;
545 
546  /* Can be called outside of a block, but usually part of a block value. */
547  result = afw_value_block_evaluate_if(x,
548  &type, x->argc, x->argv, false, x->p, x->xctx);
549 
550  return result;
551 }
552 
553 
554 
555 /*
556  * Adaptive function: loc
557  *
558  * afw_function_execute_loc
559  *
560  * See afw_function_bindings.h for more information.
561  *
562  * Declare one or more statically scoped variable locations local to the
563  * current script block and optionally assign them an initial value. These
564  * variables can be accessed and assigned different values from the current
565  * block and inner blocks.
566  *
567  * This function is pure, so it will always return the same result
568  * given exactly the same parameters and has no side effects.
569  *
570  * Declaration:
571  *
572  * ```
573  * function loc(
574  * name: (list string),
575  * value?: any,
576  * type?: (object _AdaptiveValueMeta_)
577  * ): any;
578  * ```
579  *
580  * Parameters:
581  *
582  * name - (list string) The name of one or more variables to declared in the
583  * current block.
584  *
585  * value - (optional any dataType) This is the initial value of the
586  * variable(s). If not specified, the variable will have a value of
587  * undefined.
588  *
589  * type - (optional object _AdaptiveValueMeta_) The type of the variable(s).
590  *
591  * Returns:
592  *
593  * (any dataType) The value assigned.
594  */
595 const afw_value_t *
598 {
599  /* Only allowed in a block value. See afw_value_block.c */
600  AFW_THROW_ERROR_Z(general, "Misplaced loc()", x->xctx);
601 }
602 
603 
604 
605 /*
606  * Adaptive function: return
607  *
608  * afw_function_execute_return
609  *
610  * See afw_function_bindings.h for more information.
611  *
612  * Return from the outermost structured block. If the expression of a lambda
613  * function is a block function, this will effectively return from the lambda
614  * function. If called outside of a structured block, an error is thrown.
615  *
616  * This function is pure, so it will always return the same result
617  * given exactly the same parameters and has no side effects.
618  *
619  * Declaration:
620  *
621  * ```
622  * function return(
623  * value?: any
624  * ): any;
625  * ```
626  *
627  * Parameters:
628  *
629  * value - (optional any dataType) The value to evaluate that the outermost
630  * block will return. If not specified, the last evaluated value or a
631  * null value will be returned.
632  *
633  * Returns:
634  *
635  * (any dataType) This function returns from the outermost structured block
636  * with the last evaluated value.
637  */
638 const afw_value_t *
641 {
642  /* Only allowed in a block value. See afw_value_block.c */
643  AFW_THROW_ERROR_Z(general, "Misplaced return()", x->xctx);
644 }
645 
646 
647 
648 /*
649  * Adaptive function: while
650  *
651  * afw_function_execute_while
652  *
653  * See afw_function_bindings.h for more information.
654  *
655  * This creates a new structured block with a new nested variable scope.
656  *
657  * This function will evaluate a list of values while a condition is true. The
658  * condition is tested at the beginning of the loop. If the condition is false
659  * for the first iteration, the loop returns a null value. See the related
660  * functions "break", "continue", and "return".
661  *
662  * This function is pure, so it will always return the same result
663  * given exactly the same parameters and has no side effects.
664  *
665  * Declaration:
666  *
667  * ```
668  * function while(
669  * condition: boolean,
670  * body: list
671  * ): any;
672  * ```
673  *
674  * Parameters:
675  *
676  * condition - (boolean) While this condition is true, the loop will
677  * continue. This is evaluated in the loop's scope.
678  *
679  * body - (list) This is a list of values that are evaluated for each
680  * iteration of the loop. Each value in body is evaluated in order until
681  * the end of the list or until a "break", "continue" or "return"
682  * function is encountered.
683  *
684  * Returns:
685  *
686  * (any dataType) The last value evaluated in body or null if condition
687  * evaluates to false the first time.
688  */
689 const afw_value_t *
692 {
693  const afw_value_t *result;
694  afw_value_block_statement_type_t type;
695 
696  /* Can be called outside of a block, but usually part of a block value. */
697  result = afw_value_block_evaluate_while(x,
698  &type, x->argc, x->argv, x->p, x->xctx);
699 
700  return result;
701 }
Adaptive Framework Core Internal.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define afw_compile_to_value(string, source_location, compile_type, parent, shared, p, xctx)
Compile string to adaptive value.
Definition: afw_compile.h:189
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_FUNCTION_SOURCE_LOCATION
Source location of a value.
Definition: afw_function.h:341
#define AFW_FUNCTION_EVALUATE_REQUIRED_DATA_TYPE_PARAMETER(A_RESULT, A_N, A_TYPE)
Evaluate an arg for a particular data type.
Definition: afw_function.h:328
#define AFW_FUNCTION_PARAMETER_IS_PRESENT(A_N)
Determine if a specific parameter value is present.
Definition: afw_function.h:242
const afw_value_t * afw_function_execute_assign(afw_function_execute_t *x)
Adaptive Function assign
const afw_value_t * afw_function_execute_loc(afw_function_execute_t *x)
Adaptive Function loc
const afw_value_t * afw_function_execute_continue(afw_function_execute_t *x)
Adaptive Function continue
const afw_value_t * afw_function_execute_evaluate_script(afw_function_execute_t *x)
Adaptive Function evaluate<script>
const afw_value_t * afw_function_execute_foreach(afw_function_execute_t *x)
Adaptive Function foreach
const afw_value_t * afw_function_execute_do_while(afw_function_execute_t *x)
Adaptive Function do_while
const afw_value_t * afw_function_execute_const(afw_function_execute_t *x)
Adaptive Function const
const afw_value_t * afw_function_execute_break(afw_function_execute_t *x)
Adaptive Function break
const afw_value_t * afw_function_execute_compile_script(afw_function_execute_t *x)
Adaptive Function compile<script>
const afw_value_t * afw_function_execute_for(afw_function_execute_t *x)
Adaptive Function for
const afw_value_t * afw_function_execute_if(afw_function_execute_t *x)
Adaptive Function if
const afw_value_t * afw_function_execute_while(afw_function_execute_t *x)
Adaptive Function while
const afw_value_t * afw_function_execute_return(afw_function_execute_t *x)
Adaptive Function return
afw_value_compiler_listing_to_string(const afw_value_t *value, const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Decompile a value to a compiler listing string.
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
afw_value_evaluate_with_additional_untrusted_qualified_variables(const afw_value_t *value, const afw_value_t *untrusted_qualified_variables, const afw_pool_t *p, afw_xctx_t *xctx)
Evaluate a value with additional insecure context.
Definition: afw_value.c:534
Function execute parameter.
Definition: afw_function.h:53
const afw_value_t *const * argv
This is the function parameters.
Definition: afw_function.h:86
afw_xctx_t * xctx
The execution context (xctx) of caller.
Definition: afw_function.h:62
const afw_pool_t * p
Pool for result.
Definition: afw_function.h:59
afw_size_t argc
This is the argv count not counting argv[0].
Definition: afw_function.h:89
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_value public struct.
struct for data type script values.