Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_value_call_built_in_function.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Interface afw_value Implementation for call_built_in_function
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw_internal.h"
16 
17 
18 #define impl_afw_value_optional_release NULL
19 #define impl_afw_value_get_reference NULL
20 
21 
22 
23 #define impl_afw_value_get_evaluated_meta \
24  afw_value_internal_get_evaluated_meta_default
25 
26 #define impl_afw_value_get_evaluated_metas \
27  afw_value_internal_get_evaluated_metas_default
28 
29 /* Declares and rti/inf defines for interface afw_value */
30 #define AFW_IMPLEMENTATION_ID "call_built_in_function"
31 #define AFW_IMPLEMENTATION_INF_SPECIFIER AFW_DEFINE_CONST_DATA
32 #define AFW_IMPLEMENTATION_INF_LABEL afw_value_call_built_in_function_inf
34 
35 
36 
37 /* Create function for call value. */
38 AFW_DEFINE(const afw_value_t *)
40  const afw_compile_value_contextual_t *contextual,
41  afw_size_t argc,
42  const afw_value_t * const *argv,
43  const afw_pool_t *p,
44  afw_xctx_t *xctx)
45 {
47 
48  if (!afw_value_is_function_definition(argv[0])) {
49  AFW_THROW_ERROR_Z(general,
50  "afw_value_call_built_in_function_create() argv[0] must be "
51  "function definition", xctx);
52  }
53 
56  result->function = (const afw_value_function_definition_t *)argv[0];
57  result->args.contextual = contextual;
58  result->args.argc = argc;
59  result->args.argv = argv;
60 
61  return (const afw_value_t *)result;
62 }
63 
64 
66 afw_value_call_built_in_function(
67  const afw_compile_value_contextual_t *contextual,
68  const afw_value_function_definition_t *function,
69  afw_size_t argc,
70  const afw_value_t * const *argv,
71  const afw_pool_t *p,
72  afw_xctx_t *xctx)
73 {
74  const afw_value_t *value;
75 
77  contextual, argc, argv, p, xctx);
78  return impl_afw_value_optional_evaluate(value, p, xctx);
79 }
80 
81 
82 
83 /*
84  * Implementation of method optional_evaluate for interface afw_value.
85  */
86 const afw_value_t *
88  const afw_value_t * instance,
89  const afw_pool_t * p,
90  afw_xctx_t *xctx)
91 {
93  (const afw_value_call_built_in_function_t *)instance;
94  const afw_compile_value_contextual_t *saved_contextual;
95  const afw_value_t *result;
97 
98  /* Push value on evaluation stack. */
100  saved_contextual = xctx->error->contextual;
101  xctx->error->contextual = self->args.contextual;
102 
103  /* Make function execute struct to pass to function. */
104  x.self = self;
105  x.p = p;
106  x.xctx = xctx;
107  x.function = self->function;
108  x.data_type = self->function->data_type;
109  x.first_arg = NULL;
110  x.argv = self->args.argv;
111  x.argc = self->args.argc;
112 
113  /* Make there are at least the required number of parameters. */
115  AFW_THROW_ERROR_FZ(general, xctx,
116  "%" AFW_UTF8_FMT
117  " expects %" AFW_SIZE_T_FMT " required parameters",
120  }
121 
122  /* Make there are at least the required number of parameters. */
123  if (x.function->maximumNumberOfParameters != -1 &&
125  {
126  AFW_THROW_ERROR_FZ(general, xctx,
127  "%" AFW_UTF8_FMT
128  " expects no more than %" AFW_SIZE_T_FMT " parameters",
131  }
132 
133  /*
134  * If function AFW_FUNCTION_EXECUTE_STANDARD_POLYMORPHIC_FUNCTION_HANDLING
135  * (NULL), process it here and call correct <dataType> function. This is the
136  * only place a NULL execute function is handled.
137  *
138  * This will determine the correct function->execute to use based on the
139  * <dataType> of the first parameter.
140  */
141  if (self->function->execute ==
143  {
145  if (!x.first_arg) {
146  AFW_THROW_ERROR_FZ(arg_error, xctx,
147  "Polymorphic function %" AFW_UTF8_FMT
148  " requires first parameter not be undefined",
149  AFW_UTF8_FMT_ARG(&self->function->functionId));
150  }
154  if (!x.function) {
155  AFW_THROW_ERROR_FZ(arg_error, xctx,
156  "%" AFW_UTF8_FMT " is not a method of data type %" AFW_UTF8_FMT,
157  AFW_UTF8_FMT_ARG(&self->function->functionId),
158  AFW_UTF8_FMT_ARG(&x.data_type->data_type_id));
159  }
160  }
161 
162  /*
163  * If <dataType> function, evaluate it's first parameter if there is one.
164  * afw_function_evaluate_parameter() will throw an error if
165  * one is actually required. This insures that the first parameter has
166  * been evaluated for <dataType> functions called directly or
167  * polymorphically.
168  */
169  else if (x.data_type) {
171  }
172 
173  /* Call function implementation. */
174  result = x.function->execute(&x);
175 
176  /* Pop value from evaluation stack and return result. */
178  xctx->error->contextual = saved_contextual;
179  return result;
180 }
181 
182 
183 /*
184  * Implementation of method get_data_type for interface afw_value.
185  */
186 const afw_data_type_t *
187 impl_afw_value_get_data_type(
188  const afw_value_t * instance,
189  afw_xctx_t *xctx)
190 {
191  return NULL;
192 }
193 
194 /*
195  * Implementation of method get_evaluated_data_type for interface afw_value.
196  */
197 const afw_data_type_t *
198 impl_afw_value_get_evaluated_data_type(
199  const afw_value_t * instance,
200  afw_xctx_t *xctx)
201 {
202  return NULL;
203 }
204 
205 /*
206  * Implementation of method get_evaluated_data_type_parameter for interface
207  * afw_value.
208  */
209 const afw_utf8_t *
210 impl_afw_value_get_evaluated_data_type_parameter(
211  const afw_value_t * instance,
212  afw_xctx_t *xctx)
213 {
214  return NULL;
215 }
216 
217 
218 
219 /*
220  * Implementation of method decompile for interface afw_value.
221  */
222 void
223 impl_afw_value_produce_compiler_listing(
224  const afw_value_t *instance,
225  const afw_writer_t *writer,
226  afw_xctx_t *xctx)
227 {
229  (const afw_value_call_built_in_function_t *)instance;
230 
231  afw_value_compiler_listing_begin_value(writer, instance,
232  self->args.contextual, xctx);
233  afw_writer_write_z(writer, ": [", xctx);
234  afw_writer_write_eol(writer, xctx);
235  afw_writer_increment_indent(writer, xctx);
236 
237  afw_value_compiler_listing_call_args(writer, &self->args, xctx);
238 
239  afw_writer_decrement_indent(writer, xctx);
240  afw_writer_write_z(writer, "]", xctx);
241  afw_writer_write_eol(writer, xctx);
242 }
243 
244 
245 
246 /*
247  * Implementation of method decompile for interface afw_value.
248  */
249 void
250 impl_afw_value_decompile(
251  const afw_value_t * instance,
252  const afw_writer_t * writer,
253  afw_xctx_t *xctx)
254 {
255  /*FIXME
256 
257  const afw_value_call_built_in_function_t *self =
258  (const afw_value_call_built_in_function_t *)instance;
259 
260  if (self->qualifier.len > 0) {
261  afw_writer_write_utf8(writer, &self->qualifier, xctx);
262  afw_writer_write_z(writer, "::", xctx);
263  }
264  afw_writer_write_utf8(writer, &self->name, xctx);
265  afw_value_decompile_call_args(writer, 0, &self->args, xctx);
266  */
267 }
268 
269 
270 /*
271  * Implementation of method get_info for interface afw_value.
272  */
273 void
274 impl_afw_value_get_info(
275  const afw_value_t *instance,
276  afw_value_info_t *info,
277  const afw_pool_t *p,
278  afw_xctx_t *xctx)
279 {
281  (const afw_value_call_built_in_function_t *)instance;
282 
283  afw_memory_clear(info);
284  info->detail = &self->function->functionId;
285  info->value_inf_id = &instance->inf->rti.implementation_id;
286  info->contextual = self->args.contextual;
287 }
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.
Interface afw_interface implementation declares.
#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_environment_registry_get_data_type_method(const afw_data_type_t *data_type, afw_integer_t dataTypeMethodNumber, afw_xctx_t *xctx)
Get the function associated with a data type method.
#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
#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_EXECUTE_STANDARD_POLYMORPHIC_FUNCTION_HANDLING
Function execute is handled by standard polymorphic function handling.
Definition: afw_function.h:44
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
#define afw_memory_clear(to)
Clear preallocated memory for sizeof(*(to)).
Definition: afw_memory.h:47
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_value_t * impl_afw_value_optional_evaluate(const afw_value_t *instance, const afw_pool_t *p, afw_xctx_t *xctx)
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
afw_value_call_built_in_function_inf
Value call inf.
Definition: afw_value.h:243
#define afw_value_is_function_definition(A_VALUE)
Macro to determine if value is a function definition.
Definition: afw_value.h:614
afw_value_call_built_in_function_create(const afw_compile_value_contextual_t *contextual, afw_size_t argc, const afw_value_t *const *argv, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for call_built_in_function value.
#define afw_writer_increment_indent(instance, xctx)
Call method increment_indent of interface afw_writer.
#define afw_writer_write_eol(instance, xctx)
Call method write_eol of interface afw_writer.
#define afw_writer_decrement_indent(instance, xctx)
Call method decrement_indent of interface afw_writer.
#define afw_writer_write_z(writer, s_z, xctx)
Call afw_writer_write() with zero terminated string.
Definition: afw_writer.h:35
#define afw_xctx_evaluation_stack_push_value(VALUE, xctx)
Push VALUE onto execution stack.
Definition: afw_xctx.h:78
#define afw_xctx_evaluation_stack_pop_value(xctx)
Pop top VALUE off execution stack.
Definition: afw_xctx.h:113
Contextual information provided in some values.
Interface afw_data_type public struct.
const afw_compile_value_contextual_t * contextual
Contextual information or NULL.
Definition: afw_error.h:83
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_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
const afw_data_type_t * data_type
This is the <dataType> for data type functions or NULL.
Definition: afw_function.h:74
const afw_value_call_built_in_function_t * self
self of call_built_in_function.
Definition: afw_function.h:56
afw_size_t argc
This is the argv count not counting argv[0].
Definition: afw_function.h:89
const afw_value_t * first_arg
This is the evaluated first parameter if data type function.
Definition: afw_function.h:77
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
const afw_value_t *const * argv
const afw_compile_value_contextual_t * contextual
Struct for function value.
Definition: afw_value.h:102
afw_integer_t numberOfRequiredParameters
The number of required parameters.
Definition: afw_value.h:151
afw_function_execute_cb_t execute
Function called to execute this Adaptive function.
Definition: afw_value.h:145
afw_integer_t dataTypeMethodNumber
Data type member number.
Definition: afw_value.h:190
afw_utf8_t functionId
Function id of function.
Definition: afw_value.h:112
afw_integer_t maximumNumberOfParameters
The maximum number of required parameters or -1 is no max.
Definition: afw_value.h:154
Filled in by afw_value get_info method.
Definition: afw_value.h:49
Interface afw_value public struct.
Interface afw_writer public struct.
Interface afw_xctx public struct.