Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_compile_parse_expression.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Compiler Parser
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 /*ebnf>>>
18  *
19  *# The objectId of any /afw/_AdaptiveDataType_/ objects.
20  *
21  *# This production only applies if ':' occurs before the end of current line.
22  * ColonBeforeEndOfLine ::= ':'
23  *
24  * DataType ::=
25  * 'any' |
26  * 'anyURI' |
27  * 'base64Binary' |
28  * 'boolean' |
29  * 'date' |
30  * 'dataTimeDuration' |
31  * 'dnsName' |
32  * 'double' |
33  * 'expression' |
34  * 'function' |
35  * 'hexBinary' |
36  * 'hybrid' |
37  * 'ia5String' |
38  * 'implied' |
39  * 'integer' |
40  * 'ipAddress' |
41  * 'list' |
42  * 'null' |
43  * 'object' |
44  * 'objectId' |
45  * 'objectPath' |
46  * 'password' |
47  * 'rfc822Name' |
48  * 'string' |
49  * 'template' |
50  * 'time' |
51  * 'unevaluated' |
52  * 'x500Name' |
53  * 'xpathExpression' |
54  * 'yearMonthDuration'
55  *
56  *# ObjectType should be in quoted string since some may not conform to
57  *# Identifier and consistency is desired.
58  * ObjectType ::= String
59  *
60  * Category ::= Identifier
61  *
62  * FunctionName ::= ( 'fn' '::')? Identifier ( '<' DataType '>' )?
63  *
64  * MethodName ::= ( ('fn' | Category | Qualifier) '::')? Identifier
65  *
66  * ParameterName ::= Identifier - ReservedWords
67  *
68  * PropertyName ::= Identifier
69  *
70  * Qualifier ::= Identifier
71  *
72  * VariableName ::= Identifier - ReservedWords
73  *
74  * VariableReference ::= ( Qualifier '::' Identifier) || VariableName
75  *
76  *<<<ebnf*/
77 
78 
79 
80 /*ebnf>>>
81  *
82  *# Reference is any Evaluation that evaluates to a value inf id of
83  *# reference_by_key, qualified_variable_reference, or variable_reference.
84  *
85  * Reference ::= Evaluation
86  *
87  *<<<ebnf*/
88 /* Parse Reference. Returns NULL if not an evaluation. */
90 afw_compile_parse_Reference(afw_compile_parser_t *parser)
91 {
92  const afw_value_t *result;
93 
94  result = afw_compile_parse_Evaluation(parser);
95 
96  if (result &&
100  {
101  AFW_COMPILE_THROW_ERROR_Z("Expecting property name or index");
102  }
103 
104  return result;
105 }
106 
107 
108 
109 /*ebnf>>>
110  *
111  * EntryFunctionLambdaOrVariableReference ::=
112  * (
113  * FunctionName |
114  * Lambda |
115  * VariableReference
116  * )
117  *
118  *<<<ebnf*/
120 afw_compile_parse_EntryFunctionLambdaOrVariableReference(
121  afw_compile_parser_t *parser)
122 {
123  const afw_value_t *result;
124  afw_size_t start_offset;
125  afw_value_block_symbol_t *symbol;
126  const afw_value_function_definition_t *function;
127  const afw_utf8_t *type_id, *untyped_function_id;
128 
129  afw_compile_save_offset(start_offset);
130  result = afw_compile_parse_Lambda(parser);
131  if (!result) {
132  afw_compile_get_token();
133  if (afw_compile_token_is(identifier)) {
134 
135  /* First check to see if identifier is a variable symbol. */
136  if (!parser->token->identifier_qualifier) {
137  symbol = afw_compile_parse_get_symbol_entry(parser,
138  parser->token->identifier_name);
139  if (symbol) {
141  afw_compile_create_contextual_to_cursor(start_offset),
142  symbol, parser->p, parser->xctx);
143  }
144  }
145 
146  /* Next check to see if this is a function. */
147  if (!result) {
148  if (!parser->token->identifier_qualifier ||
149  afw_utf8_equal(parser->token->identifier_qualifier,
150  &afw_s_fn))
151  {
152  untyped_function_id = parser->token->identifier_name;
154  NULL,
155  untyped_function_id,
156  parser->xctx);
157  if (function && function->polymorphic) {
158  afw_compile_get_token();
159  if (afw_compile_token_is(open_angle_bracket)) {
160  afw_compile_get_token();
161  if (!afw_compile_token_is_unqualified_identifier())
162  {
163  AFW_COMPILE_THROW_ERROR_Z("Expecting dataType");
164  }
165  type_id = parser->token->identifier;
166  afw_compile_get_token();
167  if (!afw_compile_token_is(close_angle_bracket)) {
168  AFW_COMPILE_THROW_ERROR_Z("Expecting '>'");
169  }
171  type_id, untyped_function_id, parser->xctx);
172  if (!function) {
173  AFW_COMPILE_THROW_ERROR_FZ(
174  "Unknown built-in function %" AFW_UTF8_FMT
175  "<%" AFW_UTF8_FMT ">",
176  AFW_UTF8_FMT_ARG(untyped_function_id),
177  AFW_UTF8_FMT_ARG(type_id));
178  }
179  }
180  else {
181  afw_compile_reuse_token();
182  }
183  }
184  if (!function) {
185  AFW_COMPILE_THROW_ERROR_FZ(
186  "Unknown built-in function %" AFW_UTF8_FMT,
187  AFW_UTF8_FMT_ARG(untyped_function_id));
188  }
189  result = (const afw_value_t *)function;
190  }
191 
192  /* Last, this must be a qualified variable. */
193  else {
194  if (!parser->token->identifier_qualifier) {
195  AFW_COMPILE_THROW_ERROR_FZ(
196  "Undeclared variable %" AFW_UTF8_FMT,
197  AFW_UTF8_FMT_ARG(parser->token->identifier));
198  }
199  result =
201  afw_compile_create_contextual_to_cursor(start_offset),
202  parser->token->identifier_qualifier,
203  parser->token->identifier_name,
204  parser->p, parser->xctx);
205  }
206  }
207  }
208  else {
209  afw_compile_reuse_token();
210  return NULL;
211  }
212  }
213 
214  return result;
215 }
216 
217 
218 
219 /*ebnf>>>
220  *#
221  *# Evaluation can call a FunctionName, call a Lambda defined inline, call a
222  *# function in a variable, access a local variable, or access qualified a
223  *# =variable.
224  *#
225  *# '->' calls EntryFunctionLambdaOrVariableReference with the first parameter
226  *# as the value to the left of the '->' followed by the remaining parameters
227  *# in ParametersExceptFirst. This acts like a function called as a method.
228  *#
229  *# '?->' is the same as '->' except it will return undefined if
230  *# EntryFunctionLambdaOrVariableReference does not exist or contains a nullish
231  *# value. A syntax error will still be produced for a unqualified name that
232  *# is not a declared variable or the name of a built-in function.
233  *#
234  * Evaluation ::=
235  * EntryFunctionLambdaOrVariableReference ( '?.'? Parameters )?
236  * (
237  * ( '?.'? ParametersExceptFirst ) |
238  * (
239  * ( '?.'? '[' Expression ']' ) |
240  * ( ( '.' | '?.' ) PropertyName )
241  * ) |
242  * (
243  * ( '->' | '?->' )
244  * EntryFunctionLambdaOrVariableReference
245  * '?.'? ParametersExceptFirst
246  * )
247  * )*
248  *
249  *<<<ebnf*/
250 /* Parse Evaluation. Returns NULL if not an evaluation. */
252 afw_compile_parse_Evaluation(afw_compile_parser_t *parser)
253 {
254  const afw_compile_value_contextual_t *contextual;
255  const afw_value_t *result;
256  const afw_value_t *use_function_self;
257  const afw_value_t *optional_chaining_arg0;
258  afw_compile_args_t *args;
259  const afw_value_t **argv;
260  const afw_value_t *key;
261  afw_size_t argc;
262  afw_size_t start_offset;
263 
264  afw_compile_save_offset(start_offset);
265  result = afw_compile_parse_EntryFunctionLambdaOrVariableReference(parser);
266  if (!result) {
267  return NULL;
268  }
269 
270  /* Parse rest of expression */
271  for (use_function_self = NULL;;)
272  {
273  afw_compile_save_offset(start_offset);
274  afw_compile_get_token();
275 
276  /* '?.'? */
277  optional_chaining_arg0 = NULL;
278  if (afw_compile_token_is(optional_chaining)) {
279  optional_chaining_arg0 = result;
280  afw_compile_next_identifier_is_not_special_literal();
281  afw_compile_get_token();
282  }
283 
284  /* '?.'? Parameters */
285  if (afw_compile_token_is(open_parenthesis)) {
286  afw_compile_reuse_token();
287  args = afw_compile_args_create(parser);
288  afw_compile_args_add_value(args, result); /* Function argv[0] */
289  if (use_function_self) {
290  afw_compile_args_add_value(args, use_function_self);
291  }
292  afw_compile_parse_Parameters(parser, args);
293  afw_compile_args_finalize(args, &argc, &argv);
294  contextual = afw_compile_create_contextual_to_cursor(start_offset);
295  result = afw_value_call_create(contextual, argc - 1, argv,
296  parser->p, parser->xctx);
297  use_function_self = NULL;
298  }
299 
300  /* If required parameters from previous loop, fuss. */
301  else if (use_function_self) {
302  AFW_COMPILE_THROW_ERROR_Z("Expecting parameters");
303  }
304 
305  /* '?.'? '[' Expression ']' ) */
306  else if (afw_compile_token_is(open_bracket)) {
307  key = afw_compile_parse_Expression(parser);
308  afw_compile_get_token();
309  if (!afw_compile_token_is(close_bracket)) {
310  AFW_COMPILE_THROW_ERROR_Z("Expecting ']'");
311  }
313  afw_compile_create_contextual_to_cursor(start_offset),
314  result, key, parser->p, parser->xctx);
315  }
316 
317  /* ( ( '.' | '?.' ) PropertyName ) */
318  else if (optional_chaining_arg0 || afw_compile_token_is(period))
319  {
320  if (!optional_chaining_arg0) {
321  afw_compile_next_identifier_is_not_special_literal();
322  afw_compile_get_token();
323  }
324  if (afw_compile_token_is(identifier)) {
325  if (parser->token->identifier_qualifier) {
327  "Qualifier not allowed");
328  }
330  parser->token->identifier_name,
331  parser->p, parser->xctx);
333  afw_compile_create_contextual_to_cursor(start_offset),
334  result, key, parser->p, parser->xctx);
335  }
336  else {
337  AFW_COMPILE_THROW_ERROR_Z("Expecting PropertyName");
338  }
339  }
340 
341  /*
342  * (
343  * ( '->' | '?->' )
344  * EntryFunctionLambdaOrVariableReference
345  * '?.'? ParametersExceptFirst
346  * )
347  */
348  else if (afw_compile_token_is(thin_arrow) ||
349  afw_compile_token_is(optional_chaining_thin_arrow))
350  {
351  if (optional_chaining_arg0) {
352  AFW_COMPILE_THROW_ERROR_Z("Unexpected '?.'");
353  }
354  //if (afw_compile_token_is(optional_chaining_thin_arrow)) {
355  // optional_chaining_arg0 = result;
356  //}
357  use_function_self = result;
358  result =
359  afw_compile_parse_EntryFunctionLambdaOrVariableReference(parser);
360  if (!result) {
362  "Expecting FunctionName, Lambda, Property, or "
363  "VariableReference");
364  }
365  }
366 
367  else {
368  afw_compile_reuse_token();
369  break;
370  }
371 
372  /* Do optional chaining. */
373  if (optional_chaining_arg0) {
374  argv = afw_pool_malloc(parser->p,
375  sizeof(afw_value_t *) * 3,
376  parser->xctx);
377  argv[0] = (const afw_value_t *)
379  argv[1] = optional_chaining_arg0;
380  argv[2] = result;
382  afw_compile_create_contextual_to_cursor(
383  parser->token->token_source_offset),
384  2, argv, parser->p, parser->xctx);
385  }
386  }
387 
388  /* Return value. */
389  return result;
390 }
391 
392 
393 
394 /*ebnf>>>
395  *
396  * ParameterList ::=
397  * (
398  * (
399  * ( RequiredParameterList | OptionalParameterList )
400  * ( ',' OptionalParameterList )*
401  * ( ',' EllipsisParameter )?
402  * ) |
403  * EllipsisParameter
404  * )
405  *
406  * RequiredParameterList ::=
407  * ParameterName OptionalType
408  * (',' ParameterName OptionalType)*
409  *
410  * OptionalParameterList ::=
411  * ( ParameterName '?'? OptionalType ( '=' Literal )? )
412  * (
413  * ','
414  * ( ParameterName '?'? OptionalType ( '=' Literal )? )
415  * )*
416  *
417  * EllipsisParameter ::=
418  * '...' ParameterName OptionalType
419  *
420  *#
421  *# An object with object type _AdaptiveFunctionDeclaration_
422  *#
423  * FunctionDeclarationObject ::= object
424  *
425  * FunctionSignature ::= '(' ParameterList ')' OptionalReturnType
426  *
427  *<<<ebnf*/
429 afw_compile_parse_FunctionSignature(
430  afw_compile_parser_t *parser,
431  const afw_value_block_t * *block)
432 {
433  apr_array_header_t *params;
435  afw_size_t start_offset;
437  afw_boolean_t optional_encountered;
438  afw_boolean_t question_this_time;
439 
440  optional_encountered = false;
441  signature = afw_pool_calloc_type(parser->p,
443 
444  afw_compile_save_offset(start_offset);
445 
446  /* Parse parameters. */
447  params = apr_array_make(parser->apr_p, 5,
449 
450  afw_compile_get_token();
451  if (!afw_compile_token_is(open_parenthesis)) {
452  AFW_COMPILE_THROW_ERROR_Z("Expecting '('");
453  }
454 
455  afw_compile_get_token();
456  if (!afw_compile_token_is(close_parenthesis)) {
457  afw_compile_reuse_token();
458  do {
459  param = afw_pool_calloc_type(parser->p,
461 
462  /* If ellipsis, this is a rest parameter. */
463  afw_compile_get_token();
464  if (afw_compile_token_is(ellipsis)) {
465  param->is_rest = true;
466  }
467  else {
468  afw_compile_reuse_token();
469  }
470 
471  /* Next should be name. */
472  afw_compile_get_token();
473  if (!afw_compile_token_is_unqualified_identifier()) {
474  AFW_COMPILE_THROW_ERROR_Z("Expecting parameter name");
475  }
476  param->name = parser->token->identifier_name;
477  if (afw_compile_is_reserved_word(parser, param->name)) {
479  "Parameter name can not be a reserved word");
480  }
481 
482  /* '?' */
483  afw_compile_get_token();
484  if (afw_compile_token_is(question_mark)) {
485  question_this_time = true;
486  param->is_optional = true;
487  optional_encountered = true;
488  }
489  else {
490  question_this_time = false;
491  afw_compile_reuse_token();
492  }
493 
494  /* Next is optional type. */
495  param->type = afw_compile_parse_OptionalType(parser, false);
496 
497  /* Push parm on parms stack. */
498  APR_ARRAY_PUSH(params, afw_value_script_function_parameter_t *) =
499  param;
500 
501  /* Create block if first parameter and add symbol. */
502  if (!*block) {
503  *block = afw_compile_parse_link_new_value_block(parser,
504  start_offset);
505  }
506  afw_compile_parse_add_symbol_entry(parser, param->name);
507 
508  /* Get next token. */
509  afw_compile_get_token();
510 
511  /* If this is rest parameter, this token must be close parenthesis. */
512  if (param->is_rest) {
513  if (afw_compile_token_is(close_parenthesis)) {
514  break;
515  }
516  AFW_COMPILE_THROW_ERROR_Z("Expecting ')'");
517  }
518 
519  /* '=' Literal */
520  else if (afw_compile_token_is(equal)) {
521  param->default_value = afw_compile_parse_Literal(parser,
522  NULL, true, false);
523  optional_encountered = true;
524  afw_compile_get_token();
525  }
526 
527  else if (optional_encountered && !question_this_time) {
528  AFW_COMPILE_THROW_ERROR_Z("Expecting '?' or '='");
529  }
530 
531  /* Break if ')' */
532  if (afw_compile_token_is(close_parenthesis)) {
533  break;
534  }
535 
536  /* Should be comma. */
537  if (!afw_compile_token_is(comma)) {
538  AFW_COMPILE_THROW_ERROR_Z("Expecting ',' or ')'");
539  }
540 
541  } while (1);
542  }
543 
544  /* Parse optional type and return completed signature. */
545  signature->returns = afw_compile_parse_OptionalType(parser, true);
546  signature->count = params->nelts;
547  signature->parameters =
548  (const afw_value_script_function_parameter_t **)params->elts;
549  return signature;
550 }
551 
552 
553 
554 /*ebnf>>>
555  *
556  *#
557  *# If Expression is an object literal it must be enclosed with parentheses.
558  *#
559  * FunctionSignatureAndBody ::= FunctionSignature FunctionBody
560  *
561  * FunctionBody ::= ( '{' Script '}' ) | Expression
562  *
563  *<<<ebnf*/
564 /*FIXME This has not been modified to match ebnf. */
566 afw_compile_parse_FunctionSignatureAndBody(afw_compile_parser_t *parser)
567 {
568  const afw_value_t *body;
569  const afw_value_block_t *block;
570  const afw_value_script_function_signature_t *signature;
571  afw_size_t start_offset;
572 
573  block = NULL;
574  afw_compile_save_offset(start_offset);
575 
576  /* Parse signature. */
577  signature = afw_compile_parse_FunctionSignature(parser, &block);
578 
579  /* Parse body. */
580  afw_compile_get_token();
581  if (afw_compile_token_is(open_brace)) {
582  body = afw_compile_parse_list_of_statements(parser, true, false);
583  }
584  else {
585  afw_compile_reuse_token();
586  body = afw_compile_parse_Expression(parser);
587  }
588 
589  /* If there were parameters, pop block. */
590  if (block) {
591  afw_compile_parse_pop_value_block(parser);
592  }
593 
594  /* Return lambda function value. */
596  afw_compile_create_contextual_to_cursor(start_offset),
597  signature->returns, signature->count, signature->parameters,
598  body, parser->p, parser->xctx);
599 }
600 
601 
602 
603 /*ebnf>>>
604  *
605  *# 'function' is a reserved variable/function name.
606  *
607  * Lambda ::= 'lambda::'? 'function' FunctionSignatureAndBody
608  *
609  *<<<ebnf*/
610 
611 /*
612  * Parse Lambda. Returns NULL if not a Lambda function.
613  *
614  * Returns an a lambda definition value.
615  *
616  *FIXME Change this to recognize arrow functions as well as function keyword.
617  */
619 afw_compile_parse_Lambda(afw_compile_parser_t *parser)
620 {
621  afw_compile_get_token();
622 
623  /* Return NULL if this is not a lambda function. */
624  if (!afw_compile_token_is(identifier)) {
625  afw_compile_reuse_token();
626  return NULL;
627  }
628  if (afw_utf8_equal(parser->token->identifier_qualifier, &afw_s_lambda)) {
629  if (!afw_utf8_equal(parser->token->identifier_name, &afw_s_function))
630  {
631  AFW_COMPILE_THROW_ERROR_Z("Must be lambda::function");
632  }
633  }
634  else if (afw_compile_token_is_name(&afw_s_function)) {
635  afw_compile_get_token();
636  if (!afw_compile_token_is(open_parenthesis) &&
637  !afw_compile_token_is(identifier))
638  {
639  afw_compile_reuse_token();
640  return NULL;
641  }
642  afw_compile_reuse_token();
643  }
644  else {
645  afw_compile_reuse_token();
646  return NULL;
647  }
648 
649  /* Return lambda definition. */
650  return afw_compile_parse_FunctionSignatureAndBody(parser);
651 }
652 
653 
654 
655 /*ebnf>>>
656  *
657  * Parameters ::= '(' Expression (',' Expression)*')'
658  *
659  *#
660  *# Denotes a parameter list without first parameter (method style call).
661  *#
662  * ParametersExceptFirst ::= Parameters
663  *
664  *<<<ebnf*/
666 afw_compile_parse_Parameters(
667  afw_compile_parser_t *parser,
668  afw_compile_args_t *args)
669 {
670  const afw_value_t *value;
671  afw_boolean_t had_value;
672 
673  /* Starts with '('. */
674  afw_compile_get_token();
675  if (!afw_compile_token_is(open_parenthesis)) {
676  AFW_COMPILE_THROW_ERROR_Z( "Expecting '('");
677  }
678 
679  /* Loop processing parameters. */
680  for (had_value = false;;) {
681  afw_compile_get_token();
682 
683  if (afw_compile_token_is(close_parenthesis)) {
684  break;
685  }
686 
687  if (afw_compile_token_is(comma)) {
688  if (!had_value) {
689  afw_compile_args_add_value(args, NULL);
690  }
691  had_value = false;
692  continue;
693  }
694 
695  afw_compile_reuse_token();
696 
697  value = afw_compile_parse_Expression(parser);
698  afw_compile_args_add_value(args, value);
699 
700  had_value = true;
701  }
702 }
703 
704 
705 /*ebnf>>>
706  *
707  * ParenthesizedExpression ::= '(' Expression ')'
708  *
709  *<<<ebnf*/
711 afw_compile_parse_ParenthesizedExpression(afw_compile_parser_t *parser)
712 {
713  const afw_value_t *result;
714 
715  /* Parse ( expression ) */
716  afw_compile_get_token();
717  if (!afw_compile_token_is(open_parenthesis)) {
718  AFW_COMPILE_THROW_ERROR_Z("Expecting '('");
719  }
720  result = afw_compile_parse_Expression(parser);
721  afw_compile_get_token();
722  if (!afw_compile_token_is(close_parenthesis)) {
723  AFW_COMPILE_THROW_ERROR_Z("Expecting ')'");
724  }
725 
726  return result;
727 }
728 
729 
730 /*
731  * Parse Lambda parameter type.
732  *
733  *FIXME
734  */
735 /*ebnf>>>
736  *
737  *# See RFC https://tools.ietf.org/html/rfc2616#section-3.7
738  *# This is media-type in a quoted string
739  * MediaType ::= String
740  *
741  * ListOf ::= ( 'of' 'list' )* ( 'of' Type )
742  *
743  * DataTypeWithParameter ::= '('
744  * ( ( 'base64Binary' | 'hexBinary' | 'string' ) MediaType ) |
745  * ( ( 'expression' | 'hybrid' | 'script' | 'template' ) ReturnType ) |
746  * ( 'function' FunctionSignature ) |
747  * ( 'list' ListOf ) |
748  * ( ( 'object' | 'objectId' ) ObjectType ) |
749  * ( 'unevaluated' Type ) |
750  * ')'
751  *
752  * TypeName ::= DataType | TypeVariableName | InterfaceName
753  *
754  * TypeObject ::=
755  * '{'
756  * PropertyName '?'? ':' Type
757  * ( ',' PropertyName '?'? ':' Type )*
758  * ','?
759  * '}' ';'
760  *
761  *# An object type _AdaptiveValueMeta_ object.
762  * ValueMeta ::= 'meta' Object
763  *
764  * Type ::= DataTypeWithParameter | TypeName | TypeObject | ValueMeta
765  *
766  *<<<ebnf*/
768 afw_compile_parse_Type(afw_compile_parser_t *parser)
769 {
770  const afw_utf8_t* dataType;
771  afw_value_type_list_t *list_type;
772  afw_boolean_t enclosed;
773  afw_value_type_t *type;
774  afw_size_t cursor_start_of_data_type_parameters;
775 
776  /* Can optionally begin with a '('. */
777  afw_compile_get_token();
778  enclosed = false;
779  if (afw_compile_token_is(open_parenthesis)) {
780  enclosed = true;
781  afw_compile_get_token();
782  }
783 
784  /* 'any' or DataType and optional parameters. */
785  type = afw_pool_calloc_type(parser->p, afw_value_type_t, parser->xctx);
786  if (afw_compile_token_is_unqualified_identifier()) {
787 
788  /* Get data_type and optional parameters.*/
789  dataType = parser->token->identifier_name;
790  type->data_type = afw_environment_get_data_type(dataType,
791  parser->xctx);
792  if (!type->data_type) {
793  AFW_COMPILE_THROW_ERROR_FZ(
794  "Unknown data type %" AFW_UTF8_FMT,
795  AFW_UTF8_FMT_ARG(dataType));
796  }
797 
798  /* Get optional data type parameters. */
799  if (enclosed && !afw_compile_token_is(close_parenthesis)) {
800  afw_compile_get_token();
801  cursor_start_of_data_type_parameters =
802  parser->token->token_source_offset;
803  for (list_type = NULL;
804  !afw_compile_token_is(close_parenthesis);
805  afw_compile_get_token())
806  {
807  /* MediaType */
808  if (afw_utf8_equal(dataType, &afw_s_string) ||
809  afw_utf8_equal(dataType, &afw_s_base64Binary) ||
810  afw_utf8_equal(dataType, &afw_s_hexBinary))
811  {
812  if (!afw_compile_token_is(utf8_string)) {
813  AFW_COMPILE_THROW_ERROR_Z("Expecting quoted string");
814  }
815  type->media_type = parser->token->string;
816  }
817 
818  /* ReturnType */
819  else if (
820  afw_utf8_equal(dataType, &afw_s_expression) ||
821  afw_utf8_equal(dataType, &afw_s_hybrid) ||
822  afw_utf8_equal(dataType, &afw_s_script) ||
823  afw_utf8_equal(dataType, &afw_s_template))
824  {
825  if (!afw_compile_token_is_name(&afw_s_void)) {
826  afw_compile_reuse_token();
827  type->return_type = afw_compile_parse_Type(parser);
828  }
829  }
830 
831  /* FunctionSignature */
832  else if (afw_utf8_equal(dataType, &afw_s_function))
833  {
834  afw_compile_reuse_token();
835  type->function_signature =
836  afw_compile_parse_FunctionSignature(parser, NULL);
837  }
838 
839  /* ListOf */
840  else if (afw_utf8_equal(dataType, &afw_s_list))
841  {
842  if (!afw_compile_token_is_name_z("of")) {
844  "Expecting \"of\"");
845  }
846  if (!list_type) {
847  list_type = afw_pool_calloc_type(
848  parser->p, afw_value_type_list_t, parser->xctx);
849  list_type->dimension = 1;
850  type->list_type = list_type;
851  }
852  afw_compile_get_token();
853  if (!afw_compile_token_is_name(&afw_s_list)) {
854  list_type->dimension++;
855  }
856  else {
857  if (list_type->cell_type) {
859  "Only \"of list\" can be specified except for "
860  "final \"of\"");
861  }
862  afw_compile_reuse_token();
863  list_type->cell_type = afw_compile_parse_Type(parser);
864  }
865  }
866 
867  /* ObjectType */
868  else if (afw_utf8_equal(dataType, &afw_s_object) ||
869  afw_utf8_equal(dataType, &afw_s_objectId))
870  {
871  if (!afw_compile_token_is(utf8_string)) {
872  AFW_COMPILE_THROW_ERROR_Z("Expecting quoted string");
873  }
874  type->object_type_id = parser->token->string;
875  }
876 
877  /* Type */
878  else if (afw_utf8_equal(dataType, &afw_s_unevaluated))
879  {
880  afw_compile_reuse_token();
881  type->type = afw_compile_parse_Type(parser);
882  }
883 
884  /* Parameters not allowed. */
885  else {
887  "Parameters are not allowed for this data type");
888  }
889  }
890 
891  /* Create contextual for data type parameters */
893  afw_compile_create_contextual(parser,
894  cursor_start_of_data_type_parameters,
895  parser->token->token_source_offset -
896  cursor_start_of_data_type_parameters);
897  }
898  }
899 
900  /* ValueMetaObject. */
901  else if (afw_compile_token_is(open_brace)) {
902  afw_compile_reuse_token();
903  AFW_COMPILE_THROW_ERROR_Z("Not implemented");
904  }
905 
906  /* Expecting Type. */
907  else {
908  AFW_COMPILE_THROW_ERROR_Z("Expecting Type");
909  }
910 
911  /* If enclosed, next should be ')' */
912  if (enclosed && !afw_compile_token_is(close_parenthesis)) {
913  AFW_COMPILE_THROW_ERROR_Z("Expecting ')'");
914  }
915 
916  return type;
917 }
918 
919 
920 /*ebnf>>>
921  *
922  *# If Type is not specified, default is any.
923  * OptionalType ::= ( ':' Type )?
924  *
925  * OptionalReturnType ::= ( ':' ( 'void' | Type ) )?
926  *
927  * *<<<ebnf*/
930  afw_compile_parser_t *parser,
931  afw_boolean_t is_return)
932 {
933  afw_value_type_t *type;
934 
935  /* If next is ':', parse Type. */
936  afw_compile_get_token();
937  if (afw_compile_token_is(colon)) {
938  if (is_return) {
939  afw_compile_get_token();
940  if (afw_compile_token_is_name(&afw_s_void)) {
941  return NULL;
942  }
943  afw_compile_reuse_token();
944  }
945  return afw_compile_parse_Type(parser);
946  }
947 
948  /* If next is not ':', return value type for any. */
950  afw_compile_reuse_token();
951  type = afw_pool_calloc_type(parser->p, afw_value_type_t, parser->xctx);
953 
954  return type;
955 }
956 
957 
958 
959 /*ebnf>>>
960  *
961  * NullishCoalescing ::= LogicalExpression ( '??' LogicalExpression )*
962  *
963  *<<<ebnf*/
965 afw_compile_parse_NullishCoalescing(afw_compile_parser_t *parser)
966 {
967  const afw_value_t *result;
968  afw_compile_args_t *args;
969  afw_size_t argc;
970  const afw_value_t **argv;
971  afw_size_t start_offset;
972 
973  start_offset = parser->token->token_source_offset;
974  result = afw_compile_parse_LogicalExpression(parser);
975 
976  afw_compile_next_can_be_operator();
977  afw_compile_get_token_and_save_offset(start_offset);
978  if (!afw_compile_token_is(nullish_coalescing)) {
979  afw_compile_reuse_token();
980  return result;
981  }
982 
983  args = afw_compile_args_create(parser);
984  afw_compile_args_add_value(args,
986  afw_compile_args_add_value(args, result);
987 
988  for (;;)
989  {
990  result = afw_compile_parse_LogicalExpression(parser);
991  afw_compile_args_add_value(args, result);
992  afw_compile_next_can_be_operator();
993  afw_compile_get_token();
994  if (!afw_compile_token_is(nullish_coalescing)) {
995  afw_compile_reuse_token();
996  break;
997  }
998  }
999 
1000  afw_compile_args_finalize(args, &argc, &argv);
1002  afw_compile_create_contextual_to_cursor(start_offset),
1003  argc - 1, argv, parser->p, parser->xctx);
1004 
1005  return result;
1006 }
1007 
1008 
1009 
1010 /*ebnf>>>
1011  *
1012  * LogicalExpression ::= LogicalAnd ( '||' LogicalAnd )*
1013  *
1014  *<<<ebnf*/
1016 afw_compile_parse_LogicalExpression(afw_compile_parser_t *parser)
1017 {
1018  const afw_value_t *result;
1019  afw_compile_args_t *args;
1020  const afw_value_t **argv;
1021  afw_size_t argc;
1022  afw_size_t start_offset;
1023 
1024  result = afw_compile_parse_LogicalAnd(parser);
1025 
1026  afw_compile_next_can_be_operator();
1027  afw_compile_get_token_and_save_offset(start_offset);
1028  if (!afw_compile_token_is(or)) {
1029  afw_compile_reuse_token();
1030  return result;
1031  }
1032 
1033  args = afw_compile_args_create(parser);
1034  afw_compile_args_add_value(args,
1036  afw_compile_args_add_value(args, result);
1037 
1038  for (;;) {
1039  result = afw_compile_parse_LogicalAnd(parser);
1040  afw_compile_args_add_value(args, result);
1041  afw_compile_next_can_be_operator();
1042  afw_compile_get_token();
1043  if (!afw_compile_token_is(or)) {
1044  afw_compile_reuse_token();
1045  break;
1046  }
1047  }
1048 
1049  afw_compile_args_finalize(args, &argc, &argv);
1051  afw_compile_create_contextual_to_cursor(start_offset),
1052  argc - 1, argv, parser->p, parser->xctx);
1053 
1054  return result;
1055 }
1056 
1057 
1058 /*ebnf>>>
1059  *
1060  * LogicalAnd ::= Equality ( '&&' Equality )*
1061  *
1062  *<<<ebnf*/
1064 afw_compile_parse_LogicalAnd(afw_compile_parser_t *parser)
1065 {
1066  const afw_value_t *result;
1067  afw_compile_args_t *args;
1068  const afw_value_t **argv;
1069  afw_size_t argc;
1070  afw_size_t start_offset;
1071 
1072  result = afw_compile_parse_Equality(parser);
1073 
1074  afw_compile_next_can_be_operator();
1075  afw_compile_get_token_and_save_offset(start_offset);
1076  if (!afw_compile_token_is(and )) {
1077  afw_compile_reuse_token();
1078  return result;
1079  }
1080 
1081  args = afw_compile_args_create(parser);
1082  afw_compile_args_add_value(args,
1084  afw_compile_args_add_value(args, result);
1085 
1086  for (;;) {
1087  result = afw_compile_parse_Equality(parser);
1088  afw_compile_args_add_value(args, result);
1089  afw_compile_next_can_be_operator();
1090  afw_compile_get_token();
1091  if (!afw_compile_token_is(and )) {
1092  afw_compile_reuse_token();
1093  break;
1094  }
1095  }
1096 
1097  afw_compile_args_finalize(args, &argc, &argv);
1099  afw_compile_create_contextual_to_cursor(start_offset),
1100  argc - 1, argv, parser->p, parser->xctx);
1101 
1102  return result;
1103 }
1104 
1105 
1106 /*ebnf>>>
1107  *
1108  * Equality ::= Comparison
1109  * ( ('==' | '===' | '!=' | '!==' ) Comparison )*
1110  *
1111  *<<<ebnf*/
1113 afw_compile_parse_Equality(afw_compile_parser_t *parser)
1114 {
1115  const afw_value_t *result;
1116  const afw_value_t **argv;
1117  const afw_value_t *function;
1118  afw_size_t start_offset;
1119 
1120  result = afw_compile_parse_Comparison(parser);
1121 
1122  afw_compile_next_can_be_operator();
1123  afw_compile_get_token_and_save_offset(start_offset);
1124  function = NULL;
1125 
1126  switch (parser->token->type) {
1127 
1128  case afw_compile_token_type_equal_to:
1129  function = (const afw_value_t *)&afw_function_definition_eq;
1130  break;
1131 
1132  case afw_compile_token_type_equal_value_and_type:
1133  function = (const afw_value_t *)&afw_function_definition_eqx;
1134  break;
1135 
1136  case afw_compile_token_type_not_equal_to:
1137  function = (const afw_value_t *)&afw_function_definition_ne;
1138  break;
1139 
1140  case afw_compile_token_type_not_equal_value_and_type:
1141  function = (const afw_value_t *)&afw_function_definition_nex;
1142  break;
1143 
1144  default:
1145  afw_compile_reuse_token();
1146  return result;
1147  }
1148 
1149  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 3, parser->xctx);
1150  argv[0] = function;
1151  argv[1] = result;
1152  argv[2] = afw_compile_parse_Comparison(parser);;
1153 
1155  afw_compile_create_contextual_to_cursor(start_offset),
1156  2, argv, parser->p, parser->xctx);
1157 
1158  return result;
1159 }
1160 
1161 
1162 /*ebnf>>>
1163  *
1164  * Comparison ::= Factor ( ('<' | '<=' | '>' | '>=' ) Factor )*
1165  *
1166  *<<<ebnf*/
1168 afw_compile_parse_Comparison(afw_compile_parser_t *parser)
1169 {
1170  const afw_value_t *result;
1171  const afw_value_t **argv;
1172  const afw_value_function_definition_t *function;
1173  afw_size_t start_offset;
1174 
1175  result = afw_compile_parse_Factor(parser);
1176 
1177  afw_compile_next_can_be_operator();
1178  afw_compile_get_token_and_save_offset(start_offset);
1179 
1180  switch (parser->token->type) {
1181 
1182  case afw_compile_token_type_less_than:
1183  function = &afw_function_definition_lt;
1184  break;
1185 
1186  case afw_compile_token_type_less_than_or_equal_to:
1187  function = &afw_function_definition_le;
1188  break;
1189 
1190  case afw_compile_token_type_greater_than:
1191  function = &afw_function_definition_gt;
1192  break;
1193 
1194  case afw_compile_token_type_greater_than_or_equal_to:
1195  function = &afw_function_definition_ge;
1196  break;
1197 
1198  default:
1199  afw_compile_reuse_token();
1200  return result;
1201  }
1202 
1203  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 3, parser->xctx);
1204  argv[0] = (const afw_value_t *)function;
1205  argv[1] = result;
1206  argv[2] = afw_compile_parse_Factor(parser);
1207 
1209  afw_compile_create_contextual_to_cursor(start_offset),
1210  2, argv, parser->p, parser->xctx);
1211 
1212  return result;
1213 }
1214 
1215 
1216 
1217 static const afw_value_t *
1218 impl_parse_subtract(
1219  afw_compile_parser_t *parser,
1220  const afw_value_t *value)
1221 {
1222  const afw_value_t *result;
1223  const afw_value_t **argv;
1224  afw_size_t start_offset;
1225 
1226  start_offset = parser->token->token_source_offset;
1227  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 3, parser->xctx);
1228  argv[0] = (const afw_value_t *)&afw_function_definition_subtract;
1229  argv[1] = value;
1230  argv[2] = afw_compile_parse_Term(parser);
1232  afw_compile_create_contextual_to_cursor(start_offset),
1233  2, argv, parser->p, parser->xctx);
1234 
1235  afw_compile_next_can_be_operator();
1236  afw_compile_get_token();
1237  if (afw_compile_token_is(subtract)) {
1238  result = impl_parse_subtract(parser, result);
1239  }
1240  else {
1241  afw_compile_reuse_token();
1242  }
1243  return result;
1244 }
1245 
1246 
1247 
1248 /*ebnf>>>
1249  *
1250  * Factor ::= Term ( ('+' | '-' ) Term )*
1251  *
1252  *<<<ebnf*/
1254 afw_compile_parse_Factor(afw_compile_parser_t *parser)
1255 {
1256  const afw_value_t *result;
1257  const afw_value_t *value;
1258  afw_compile_args_t *args;
1259  afw_size_t argc;
1260  const afw_value_t **argv;
1261  afw_size_t start_offset;
1262 
1263  start_offset = parser->token->token_source_offset;
1264  result = afw_compile_parse_Term(parser);
1265 
1266  for (args = NULL;;) {
1267 
1268  afw_compile_next_can_be_operator();
1269  afw_compile_get_token();
1270 
1271  switch (parser->token->type) {
1272 
1273  case afw_compile_token_type_add:
1274  if (!args) {
1275  args = afw_compile_args_create(parser);
1276  afw_compile_args_add_value(args,
1278  afw_compile_args_add_value(args, result);
1279  }
1280  value = afw_compile_parse_Term(parser);
1281  afw_compile_args_add_value(args, value);
1282  break;
1283 
1284  case afw_compile_token_type_subtract:
1285  if (args) {
1286  afw_compile_args_finalize(args, &argc, &argv);
1287  args = NULL;
1288  result = afw_value_call_create(
1289  afw_compile_create_contextual_to_cursor(start_offset),
1290  argc - 1, argv, parser->p, parser->xctx);
1291  start_offset = parser->token->token_source_offset;
1292  }
1293  result = impl_parse_subtract(parser, result);
1294  break;
1295 
1296  default:
1297  afw_compile_reuse_token();
1298  if (args) {
1299  afw_compile_args_finalize(args, &argc, &argv);
1300  result = afw_value_call_create(
1301  afw_compile_create_contextual_to_cursor(start_offset),
1302  argc - 1, argv, parser->p, parser->xctx);
1303  }
1304  return result;
1305  }
1306  }
1307 }
1308 
1309 
1310 
1311 static const afw_value_t *
1312 impl_parse_divide_or_mod(
1313  afw_compile_parser_t *parser,
1314  const afw_value_t *value)
1315 {
1316  const afw_value_t *result;
1317  const afw_value_t **argv;
1318  const afw_value_t *function;
1319  afw_size_t start_offset;
1320 
1321  function = (parser->token->type == afw_compile_token_type_divide)
1324 
1325  start_offset = parser->token->token_source_offset;
1326  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 3, parser->xctx);
1327  argv[0] = function;
1328  argv[1] = value;
1329  argv[2] = afw_compile_parse_Exponentiation(parser);
1331  afw_compile_create_contextual_to_cursor(start_offset),
1332  2, argv, parser->p, parser->xctx);
1333  afw_compile_next_can_be_operator();
1334  afw_compile_get_token();
1335  if (afw_compile_token_is(divide) || afw_compile_token_is(modulus))
1336  {
1337  result = impl_parse_divide_or_mod(parser, result);
1338  }
1339  else {
1340  afw_compile_reuse_token();
1341  }
1342  return result;
1343 }
1344 
1345 
1346 
1347 /*ebnf>>>
1348  *
1349  * Term ::= Exponentiation ( ('*' | '/' | '%') Exponentiation )*
1350  *
1351  *<<<ebnf*/
1353 afw_compile_parse_Term(afw_compile_parser_t *parser)
1354 {
1355  const afw_value_t *result;
1356  const afw_value_t *value;
1357  afw_compile_args_t *args;
1358  afw_size_t argc;
1359  const afw_value_t **argv;
1360  afw_size_t start_offset;
1361 
1362  start_offset = parser->token->token_source_offset;
1363  result = afw_compile_parse_Exponentiation(parser);
1364 
1365  for (args = NULL;;) {
1366 
1367  afw_compile_next_can_be_operator();
1368  afw_compile_get_token();
1369 
1370  switch (parser->token->type) {
1371 
1372  case afw_compile_token_type_multiply:
1373  if (!args) {
1374  args = afw_compile_args_create(parser);
1375  afw_compile_args_add_value(args,
1377  afw_compile_args_add_value(args, result);
1378  }
1379  value = afw_compile_parse_Exponentiation(parser);
1380  afw_compile_args_add_value(args, value);
1381  break;
1382 
1383  case afw_compile_token_type_divide:
1384  case afw_compile_token_type_modulus:
1385  if (args) {
1386  afw_compile_args_finalize(args, &argc, &argv);
1387  args = NULL;
1389  afw_compile_create_contextual_to_cursor(start_offset),
1390  argc - 1, argv, parser->p, parser->xctx);
1391  start_offset = parser->token->token_source_offset;
1392  }
1393  result = impl_parse_divide_or_mod(parser, result);
1394  break;
1395 
1396  default:
1397  afw_compile_reuse_token();
1398  if (args) {
1399  afw_compile_args_finalize(args, &argc, &argv);
1400  result = afw_value_call_create(
1401  afw_compile_create_contextual_to_cursor(start_offset),
1402  argc - 1, argv, parser->p, parser->xctx);
1403  }
1404  return result;
1405  }
1406  }
1407 }
1408 
1409 
1410 /*ebnf>>>
1411  *
1412  * Exponentiation ::= Prefixed ( '**' Prefixed )*
1413  *
1414  *<<<ebnf*/
1416 afw_compile_parse_Exponentiation(afw_compile_parser_t *parser)
1417 {
1418  const afw_value_t *result;
1419  const afw_value_t *value;
1420  afw_compile_args_t *args;
1421  afw_size_t argc;
1422  const afw_value_t **argv;
1423  afw_size_t start_offset;
1424 
1425  start_offset = parser->token->token_source_offset;
1426  result = afw_compile_parse_Prefixed(parser);
1427 
1428  for (args = NULL;;) {
1429  afw_compile_next_can_be_operator();
1430  afw_compile_get_token();
1431 
1432  if (afw_compile_token_is(exponentiation)) {
1433  if (!args) {
1434  args = afw_compile_args_create(parser);
1435  afw_compile_args_add_value(args,
1437  afw_compile_args_add_value(args, result);
1438  }
1439  value = afw_compile_parse_Prefixed(parser);
1440  afw_compile_args_add_value(args, value);
1441  }
1442  else {
1443  afw_compile_reuse_token();
1444  if (args) {
1445  afw_compile_args_finalize(args, &argc, &argv);
1446  result = afw_value_call_create(
1447  afw_compile_create_contextual_to_cursor(start_offset),
1448  argc - 1, argv, parser->p, parser->xctx);
1449  }
1450  break;
1451  }
1452  }
1453 
1454  return result;
1455 }
1456 
1457 
1458 
1459 /*ebnf>>>
1460  *
1461  * Prefixed ::= ( ( '+' | '-' | '!' ) Value ) | Value
1462  *
1463  *<<<ebnf*/
1465 afw_compile_parse_Prefixed(afw_compile_parser_t *parser)
1466 {
1467  const afw_value_t *result;
1468  const afw_value_t **argv;
1469  afw_size_t start_offset;
1470 
1471  afw_compile_get_token_and_save_offset(start_offset);
1472 
1473  switch (parser->token->type) {
1474 
1475  case afw_compile_token_type_unary_plus:
1476  result = afw_compile_parse_Value(parser);
1477  break;
1478 
1479  case afw_compile_token_type_unary_minus:
1480  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 2,
1481  parser->xctx);
1482  argv[0] = (const afw_value_t *)&afw_function_definition_negative;
1483  argv[1] = afw_compile_parse_Value(parser);
1485  afw_compile_create_contextual_to_cursor(start_offset),
1486  1, argv, parser->p, parser->xctx);
1487  break;
1488 
1489  case afw_compile_token_type_unary_not:
1490  argv = afw_pool_malloc(parser->p, sizeof(afw_value_t *) * 2,
1491  parser->xctx);
1492  argv[0] = (const afw_value_t *)&afw_function_definition_not;
1493  argv[1] = afw_compile_parse_Value(parser);
1495  afw_compile_create_contextual_to_cursor(start_offset),
1496  1, argv, parser->p, parser->xctx);
1497  break;
1498 
1499  default:
1500  afw_compile_reuse_token();
1501  result = afw_compile_parse_Value(parser);
1502  }
1503 
1504  return result;
1505 }
1506 
1507 
1508 
1509 /*ebnf>>>
1510  *
1511  * Expression ::= NullishCoalescing ( '?' Expression ':' Expression )?
1512  *
1513  *<<<ebnf*/
1515 afw_compile_parse_Expression(afw_compile_parser_t *parser)
1516 {
1517  const afw_value_t *result;
1518  const afw_value_t **argv;
1519  afw_size_t start_offset;
1520 
1521  result = afw_compile_parse_NullishCoalescing(parser);
1522  afw_compile_get_token_and_save_offset(start_offset);
1523 
1524  if (afw_compile_token_is(question_mark)) {
1525  argv = afw_pool_malloc(parser->p,
1526  sizeof(afw_value_t *) * 4, parser->xctx);
1527  argv[0] = (const afw_value_t *)&afw_function_definition_if;
1528  argv[1] = result;
1529  argv[2] = afw_compile_parse_Expression(parser);
1530 
1531  afw_compile_get_token();
1532  if (!afw_compile_token_is(colon)) {
1533  AFW_COMPILE_THROW_ERROR_Z("Expecting ':'");
1534  }
1535  argv[3] = afw_compile_parse_Expression(parser);
1536 
1538  afw_compile_create_contextual_to_cursor(start_offset),
1539  3, argv, parser->p, parser->xctx);
1540  }
1541 
1542  else {
1543  afw_compile_reuse_token();
1544  }
1545 
1546  return result;
1547 }
#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_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_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
struct afw_compile_internal_args_s afw_compile_args_t
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
afw_compile_parse_OptionalType(afw_compile_parser_t *parser, afw_boolean_t is_return)
#define AFW_COMPILE_THROW_ERROR_Z(message_z)
afw_environment_get_qualified_function(const afw_utf8_t *qualifier, const afw_utf8_t *name, afw_xctx_t *xctx)
Get the qualified function instance.
const afw_data_type_t * afw_environment_get_data_type(const afw_utf8_t *type, afw_xctx_t *xctx)
Get the data_type associated with configuration entry type.
afw_function_definition_not
Function definition not.
afw_function_definition_and
Function definition and.
afw_function_definition_or
Function definition or.
afw_function_definition_nullish_coalescing
Function definition nullish_coalescing.
afw_function_definition_optional_chaining
Function definition optional_chaining.
afw_function_definition_pow
Adaptive Function one_and_only
afw_function_definition_multiply
Adaptive Function mod
afw_function_definition_divide
Adaptive Function decode_to_string
afw_function_definition_ge
Adaptive Function floor
afw_function_definition_le
Adaptive Function last_index_of
afw_function_definition_gt
Adaptive Function ge
afw_function_definition_lt
Adaptive Function length
afw_function_definition_nex
Adaptive Function negative
afw_function_definition_mod
Adaptive Function min
afw_function_definition_add
Adaptive Function abs
afw_function_definition_negative
Adaptive Function ne
afw_function_definition_eqx
Adaptive Function eq_ignore_case
afw_function_definition_eq
Adaptive Function ends_with
afw_function_definition_subtract
Adaptive Function substring
afw_function_definition_ne
Adaptive Function multiply
afw_function_definition_if
Adaptive Function gt<script>
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
#define afw_value_is_variable_reference(A_VALUE)
Macro to determine if value is a variable reference.
Definition: afw_value.h:718
#define afw_value_is_reference_by_key(A_VALUE)
Macro to determine if value is a access property by index.
Definition: afw_value.h:692
const afw_value_t * afw_value_script_function_definition_create(const afw_compile_value_contextual_t *contextual, const afw_value_type_t *returns, afw_size_t count, const afw_value_script_function_parameter_t **parameters, const afw_value_t *body, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for lambda definition value.
const afw_value_t * afw_value_variable_reference_create(const afw_compile_value_contextual_t *contextual, const afw_value_block_symbol_t *symbol, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for variable reference value.
const afw_value_t * afw_value_call_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 value.
const afw_value_t * 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_value_is_qualified_variable_reference(A_VALUE)
Macro to determine if value is a qualified variable reference.
Definition: afw_value.h:679
const afw_value_t * afw_value_reference_by_key_create(const afw_compile_value_contextual_t *contextual, const afw_value_t *aggregate_value, const afw_value_t *key, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for reference_by_key value.
const afw_value_t * afw_value_qualified_variable_reference_create(const afw_compile_value_contextual_t *contextual, const afw_utf8_t *qualifier, const afw_utf8_t *name, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for variable reference value.
Contextual information provided in some values.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for afw_value_block_t
struct for afw_value_block_symbol_t
Struct for function value.
Definition: afw_value.h:102
Interface afw_value public struct.
Struct for script function parameter.
afw_size_t dimension
Number of subscripts needed to access cell.
const afw_value_type_t * cell_type
Cell type. If NULL, cell is untyped.
Type meta (data type, data type parameters, and value meta object.
const afw_value_type_list_t * list_type
list type (If NULL, 1 dimension with untyped cells).
const afw_utf8_t * media_type
string, base64Binary, hexBinary.
const afw_utf8_t * object_type_id
object and objectId.
const afw_value_type_t * type
unevaluated.
const afw_data_type_t * data_type
data type or NULL.
const afw_value_type_t * return_type
expression, hybrid, script and template.
const afw_compile_value_contextual_t * data_type_parameter_contextual
contextual for data type parameter or NULL.
const afw_value_script_function_signature_t * function_signature
function.