Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_function.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * AFW runtime functions support
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
15 #include "afw_internal.h"
16 
18 afw_function_internal_prepare_environment(afw_xctx_t *xctx)
19 {
21 
23  ((afw_environment_t *)xctx->env)->function_environment = e;
24 
26  afw_environment_get_function(&afw_s_add, xctx);
27 
29  afw_environment_get_function(&afw_s_subtract, xctx);
30 
32  afw_environment_get_function(&afw_s_multiply, xctx);
33 
35  afw_environment_get_function(&afw_s_divide, xctx);
36 
38  afw_environment_get_function(&afw_s_mod, xctx);
39 
41  afw_environment_get_function(&afw_s_pow, xctx);
42 
44  afw_environment_get_function(&afw_s_negative, xctx);
45 
47  afw_environment_get_function(&afw_s_and, xctx);
48 
50  afw_environment_get_function(&afw_s_or, xctx);
51 
53  afw_environment_get_function(&afw_s_not, xctx);
54 
56  afw_environment_get_function(&afw_s_eq, xctx);
57 
59  afw_environment_get_function(&afw_s_ne, xctx);
60 
62  afw_environment_get_function(&afw_s_lt, xctx);
63 
65  afw_environment_get_function(&afw_s_le, xctx);
66 
68  afw_environment_get_function(&afw_s_gt, xctx);
69 
71  afw_environment_get_function(&afw_s_ge, xctx);
72 }
73 
74 
75 
76 /* Adaptive function: convert arg to <datatype> */
77 const afw_value_t *
80 {
81  const afw_value_t *result;
82  afw_xctx_t *xctx = x->xctx;
83 
84  result = afw_function_evaluate_required_parameter(x, 1, NULL);
85 
87  result = afw_value_convert(result,
88  x->function->returns->data_type, false, x->p, xctx);
90 
91  return result;
92 }
93 
94 
95 
96 /* Evaluate function parameter. */
97 /* Note: only called by higher_order_list at the moment */
98 AFW_DEFINE(const afw_value_t *)
99 afw_function_evaluate_function_parameter(
100  const afw_value_t *function_arg,
101  const afw_pool_t *p,
102  afw_xctx_t *xctx)
103 {
104  const afw_value_t *result;
105  afw_utf8_t qualifier;
106  afw_utf8_t name;
107 
108  result = afw_value_evaluate(function_arg, p, xctx);
109 
110  /* Strings are looked up dynamically. Note: this may become deprecated. */
111  if (afw_value_is_string(result)) {
113  &((const afw_value_string_t *)result)->internal,
114  &qualifier, &name, xctx);
115 
116  /* Built-in function */
117  result = (const afw_value_t *)
119  &qualifier, &name, xctx);
120  }
121 
122  return result;
123 }
124 
125 
126 
127 /* Evaluate a value and cast if necessary without throwing error. */
128 AFW_DEFINE(const afw_value_t *)
131  afw_size_t parameter_number,
132  const afw_data_type_t *data_type)
133 {
134  afw_xctx_t *xctx = x->xctx;
135  const afw_value_t *result;
136  const afw_data_type_t *result_data_type;
137  const afw_value_function_parameter_t *parameter;
138 
139  /* Push parameter number on evaluation stack. */
140  afw_xctx_evaluation_stack_push_parameter_number(parameter_number, xctx);
141 
142  /* Get function parameter from function definition. */
143  parameter = x->function->parameters[
144  (
145  (parameter_number <= x->function->parameters_count)
146  ? parameter_number
147  : x->function->parameters_count
148  )
149  - 1
150  ];
151 
152  /* Get possibly unevaluated result from argv. */
153  result = ((parameter_number <= x->argc) ? x->argv[parameter_number] : NULL);
154 
155  /* Evaluate result if needed. */
156  if (!afw_value_is_defined_and_evaluated(result)) {
157  result = afw_value_evaluate(result, x->p, xctx);
158  }
159 
160  /* If result is undefined, return NULL. Fuss if required. */
161  if (afw_value_is_undefined(result)) {
162  if (
163  parameter_number <= x->function->numberOfRequiredParameters &&
164  !parameter->optional &&
165  !parameter->canBeUndefined)
166  {
167  AFW_THROW_ERROR_FZ(general, xctx,
168  "Parameter %" AFW_SIZE_T_FMT
169  " of function %" AFW_UTF8_FMT
170  " can not be undefined",
171  parameter_number,
172  AFW_UTF8_FMT_ARG(&x->function->functionId));
173  }
175  return result;
176  }
177 
178  /* Get result's data type. */
179  result_data_type = afw_value_get_data_type(result, xctx);
180 
181  /* Error if result data type doesn't match parameter's defined data type. */
182  if (parameter->data_type && result_data_type) {
183  if (parameter->data_type != afw_data_type_list && //@fixme don't require
184  (parameter->data_type != result_data_type))
185  {
186  AFW_THROW_ERROR_FZ(general, xctx,
187  "Parameter %" AFW_SIZE_T_FMT
188  " of function %" AFW_UTF8_FMT
189  " must evaluate to data type %" AFW_UTF8_FMT
190  " but evaluated to be %" AFW_UTF8_FMT,
191  parameter_number,
192  AFW_UTF8_FMT_ARG(&x->function->functionId),
193  AFW_UTF8_FMT_ARG(&parameter->data_type->data_type_id),
194  AFW_UTF8_FMT_ARG(&result_data_type->data_type_id));
195  }
196  }
197 
198  /* Convert to requested data type if needed. */
199  if (data_type && result_data_type && result_data_type != data_type)
200  {
201  result = afw_value_convert(result, data_type, false, x->p, xctx);
202  }
203 
204  /* Pop parameter number from evaluation stack and return result. */
206  return result;
207 }
208 
209 
210 
211 /* Evaluate a value and cast if necessary without throwing error. */
212 AFW_DEFINE(const afw_value_t *)
215  afw_size_t parameter_number,
216  const afw_data_type_t *data_type)
217 {
218  afw_xctx_t *xctx = x->xctx;
219  const afw_value_t *result;
220 
221  /* Evaluate parameter. */
222  result = afw_function_evaluate_parameter(x, parameter_number, data_type);
223 
224  /* If result is NULL, throw error with parameter # on evaluation stack. */
225  if (!result) {
227  parameter_number, xctx);
228  AFW_THROW_ERROR_FZ(undefined, xctx,
229  "Parameter %" AFW_SIZE_T_FMT " is undefined value",
230  parameter_number);
232  }
233 
234  /* Return result that will not be NULL. */
235  return result;
236 }
237 
238 
239 
240 /* Evaluate a parameter with dataTypeParameter. */
241 /* Note: This is only called by impl_call_script_function at the moment. */
242 AFW_DEFINE(const afw_value_t*)
244  const afw_value_t* value,
245  afw_size_t parameter_number,
246  const afw_value_type_t *type,
247  const afw_pool_t *p, afw_xctx_t *xctx)
248 {
249  const afw_value_t *result;
250 
251  /* Make sure value is undecorated. */
252  AFW_VALUE_UNDECORATE(value);
253 
256  /* Just return if no evaluation or conversion needed. */
258  (!type || !type->data_type || type->data_type == afw_data_type_any ||
259  afw_value_get_data_type(value, xctx) == type->data_type))
260  {
261  return value;
262  }
263 
264  /* Push parameter number on evaluation stack. */
265  afw_xctx_evaluation_stack_push_parameter_number(parameter_number, xctx);
266 
267  /* Evaluate value. */
268  result = afw_value_evaluate(value, p, xctx);
269 
270  /* Convert to requested data type if needed. */
271  if (result && type && type->data_type &&
272  afw_value_get_data_type(value, xctx) != type->data_type)
273  {
274  result = afw_value_convert(result, type->data_type, true, p, xctx);
275  }
276 
277  /* Pop parameter number from evaluation stack and return result. */
279  return result;
280 }
281 
AFW_DEFINE(const afw_object_t *)
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
Adaptive Framework Core Internal.
afw_data_type_any
Data type struct for any.
afw_data_type_list
Data type struct for list.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
Definition: afw_common.h:341
afw_compile_split_qualified_name(const afw_utf8_t *qualified_name, afw_utf8_t *qualifier, afw_utf8_t *name, afw_xctx_t *xctx)
Split name with optional qualifier.
Definition: afw_compile.c:548
const afw_value_function_definition_t * afw_environment_get_function(const afw_utf8_t *function_id, afw_xctx_t *xctx)
Get the function instance associated with function id.
afw_environment_get_qualified_function(const afw_utf8_t *qualifier, const afw_utf8_t *name, afw_xctx_t *xctx)
Get the qualified function instance.
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
afw_function_evaluate_required_parameter(afw_function_execute_t *x, afw_size_t parameter_number, const afw_data_type_t *data_type)
Evaluate an required parameter and convert if necessary.
Definition: afw_function.c:213
afw_function_evaluate_parameter_with_type(const afw_value_t *value, afw_size_t parameter_number, const afw_value_type_t *type, const afw_pool_t *p, afw_xctx_t *xctx)
Evaluate a parameter with dataTypeParameter.
Definition: afw_function.c:243
afw_function_evaluate_parameter(afw_function_execute_t *x, afw_size_t parameter_number, const afw_data_type_t *data_type)
Evaluate a parameter and convert if necessary.
Definition: afw_function.c:129
const afw_value_t * afw_function_execute_convert(afw_function_execute_t *x)
Function implementation function afw_function_execute_convert.
Definition: afw_function.c:78
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
#define AFW_VALUE_UNDECORATE(a_value)
Undecorated value in place.
Definition: afw_value.h:375
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
#define afw_value_is_defined_and_evaluated(A_VALUE)
Macro to determine if value is defined and evaluated.
Definition: afw_value.h:481
afw_value_convert(const afw_value_t *value, const afw_data_type_t *to_data_type, afw_boolean_t required, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a value to a value/data type.
Definition: afw_value.c:584
#define afw_value_is_undefined(A_VALUE)
Determine if value is undefined.
Definition: afw_value.h:438
#define afw_xctx_evaluation_stack_pop_parameter_number(xctx)
Pop top PARAMETER_NUMBER off execution stack.
Definition: afw_xctx.h:124
#define afw_xctx_evaluation_stack_push_parameter_number(PARAMETER_NUMBER, xctx)
Push PARAMETER_NUMBER onto execution stack.
Definition: afw_xctx.h:88
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Definition: afw_xctx.h:199
Interface afw_data_type public struct.
Struct for typedef afw_environment_t defined in afw_common.h.
Definition: afw_common.h:1383
const afw_value_function_definition_t * divide_operator_function
Divide operator function.
Definition: afw_function.h:107
const afw_value_function_definition_t * or_operator_function
Or operator function.
Definition: afw_function.h:122
const afw_value_function_definition_t * less_than_or_equal_to_function
Less than or equal to operator function.
Definition: afw_function.h:137
const afw_value_function_definition_t * modulus_operator_function
Modulus operator function.
Definition: afw_function.h:110
const afw_value_function_definition_t * multiply_operator_function
Multiply operator function.
Definition: afw_function.h:104
const afw_value_function_definition_t * add_operator_function
Add operator function.
Definition: afw_function.h:98
const afw_value_function_definition_t * unary_not_operator_function
Not operator function.
Definition: afw_function.h:125
const afw_value_function_definition_t * exponentiation_operator_function
Exponentiation operator function.
Definition: afw_function.h:113
const afw_value_function_definition_t * subtract_operator_function
Subtract operator function.
Definition: afw_function.h:101
const afw_value_function_definition_t * less_than_operator_function
Less than operator function.
Definition: afw_function.h:134
const afw_value_function_definition_t * negative_operator_function
Negative operator function.
Definition: afw_function.h:116
const afw_value_function_definition_t * not_equal_to_operator_function
Not equal to operator function.
Definition: afw_function.h:131
const afw_value_function_definition_t * and_operator_function
And operator function.
Definition: afw_function.h:119
const afw_value_function_definition_t * greater_than_operator_function
Greater than operator function.
Definition: afw_function.h:140
const afw_value_function_definition_t * greater_than_or_equal_to_function
Greater than or equal to operator function.
Definition: afw_function.h:143
const afw_value_function_definition_t * equal_to_operator_function
Equal to operator function.
Definition: afw_function.h:128
Function execute parameter.
Definition: afw_function.h:53
afw_xctx_t * xctx
The execution context (xctx) of caller.
Definition: afw_function.h:62
const afw_value_function_definition_t * function
The evaluated function definition.
Definition: afw_function.h:71
const afw_pool_t * p
Pool for result.
Definition: afw_function.h:59
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
const afw_value_function_parameter_t * returns
Function returns.
Definition: afw_value.h:163
Struct for adaptive function parameter.
Definition: afw_value.h:68
Interface afw_value public struct.
struct for data type string values.
Type meta (data type, data type parameters, and value meta object.
Interface afw_xctx public struct.