21 impl_function_definition_break =
25 impl_function_definition_continue =
30 afw_compile_parse_list_of_statements(
45 args = afw_compile_args_create(parser);
46 was_expression_value =
false;
47 was_expression = (can_be_single_return_expression)
48 ? &was_expression_value
52 afw_compile_save_cursor(start_offset);
55 block = afw_compile_parse_link_new_value_block(parser, start_offset);
60 afw_compile_get_token();
61 if (end_is_close_brace) {
62 if (afw_compile_token_is(close_bracket) ||
63 afw_compile_token_is(close_brace))
67 else if afw_compile_token_is(end) {
71 else if (afw_compile_token_is(end)) {
74 afw_compile_reuse_token();
76 if (was_expression_value) {
78 "Expression can not be followed by Statement");
81 statement = afw_compile_parse_Statement(parser, was_expression);
83 if (was_expression_value) {
89 afw_compile_create_contextual_to_cursor(start_offset),
90 1, argv, parser->p, parser->xctx);
92 was_expression = NULL;
95 afw_compile_args_add_value(args, statement);
100 afw_compile_args_finalize(args, &argc, &argv);
105 afw_compile_parse_pop_value_block(parser);
125 afw_compile_parse_AssignmentExpression(
130 result = afw_compile_parse_Expression(parser);
145 afw_compile_parse_OptionalDefineTarget(
152 assignment_type = afw_compile_assignment_type_assign_only;
153 afw_compile_get_token();
154 if (afw_compile_token_is_name(&afw_s_loc)) {
155 assignment_type = afw_compile_assignment_type_loc;
157 else if afw_compile_token_is_name(&afw_s_const) {
158 assignment_type = afw_compile_assignment_type_const;
161 afw_compile_reuse_token();
165 result = afw_compile_parse_AssignmentTarget(parser, assignment_type);
180 afw_compile_parse_OptionalDefineAssignment(
189 if (afw_compile_token_is_name(&afw_s_loc)) {
190 assignment_type = afw_compile_assignment_type_loc;
193 else if afw_compile_token_is_name(&afw_s_const) {
194 assignment_type = afw_compile_assignment_type_const;
200 return afw_compile_parse_Assignment(parser, NULL);
209 argv[1] = afw_compile_parse_AssignmentTarget(parser, assignment_type);
213 afw_compile_get_token();
214 if (!afw_compile_token_is(equal)) {
217 argv[2] = afw_compile_parse_Expression(parser);
220 afw_compile_create_contextual_to_cursor(
221 parser->token->token_source_offset),
222 3, argv, parser->p, parser->xctx);
241 afw_compile_parse_Assignment(
252 if (was_expression) {
253 *was_expression =
false;
255 just_expression_okay =
false;
257 if (afw_compile_token_is(open_bracket) ||
258 afw_compile_token_is(open_brace) ||
259 afw_compile_token_is(open_angle_bracket))
261 afw_compile_reuse_token();
262 target = afw_compile_parse_AssignmentTarget(parser,
263 afw_compile_assignment_type_assign_only);
266 afw_compile_reuse_token();
267 target = afw_compile_parse_Evaluation(parser);
268 if (!target && was_expression) {
269 target = afw_compile_parse_Expression(parser);
274 if (was_expression) {
275 just_expression_okay =
true;
279 afw_compile_get_token();
280 switch (parser->token->type) {
281 case afw_compile_token_type_equal:
285 case afw_compile_token_type_plus_equal:
289 case afw_compile_token_type_minus_equal:
293 case afw_compile_token_type_multiply_equal:
297 case afw_compile_token_type_divide_equal:
301 case afw_compile_token_type_modulus_equal:
305 case afw_compile_token_type_exponentiation_equal:
309 case afw_compile_token_type_and_equal:
313 case afw_compile_token_type_or_equal:
317 case afw_compile_token_type_nullish_equal:
323 if (just_expression_okay) {
324 afw_compile_reuse_token();
325 *was_expression =
true;
334 result = afw_compile_parse_Expression(parser);
342 afw_compile_create_contextual_to_cursor(
343 parser->token->token_source_offset),
344 2, argv, parser->p, parser->xctx);
347 result = afw_compile_parse_Expression(parser);
357 afw_compile_create_contextual_to_cursor(
358 parser->token->token_source_offset),
359 2, argv, parser->p, parser->xctx);
377 afw_compile_parse_AssignmentStatement(
388 is_object_destructuring =
false;
389 if (afw_compile_token_is(open_parenthesis)) {
390 afw_compile_get_token();
391 if afw_compile_token_is(open_brace) {
392 is_object_destructuring =
true;
395 afw_compile_reuse_token();
399 result = afw_compile_parse_Assignment(parser,
400 is_object_destructuring ? NULL : was_expression);
403 if (is_object_destructuring) {
404 afw_compile_get_token();
405 if (!afw_compile_token_is(close_parenthesis)) {
410 if (!was_expression || !*was_expression) {
411 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
432 afw_compile_create_contextual_to_cursor(
433 parser->token->token_source_offset),
434 0, &impl_function_definition_break, parser->p, parser->xctx);
436 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
460 argv[1] = afw_compile_parse_AssignmentTarget(parser,
461 afw_compile_assignment_type_const);
465 afw_compile_get_token();
466 if (!afw_compile_token_is(equal)) {
469 argv[2] = afw_compile_parse_Expression(parser);
470 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
473 afw_compile_create_contextual_to_cursor(
474 parser->token->token_source_offset),
475 3, argv, parser->p, parser->xctx);
538 afw_compile_create_contextual_to_cursor(
539 parser->token->token_source_offset),
540 0, &impl_function_definition_continue, parser->p, parser->xctx);
542 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
573 afw_compile_save_cursor(start_offset);
577 argv[2] = afw_compile_parse_Statement(parser, NULL);
579 afw_compile_get_token();
580 if (!afw_compile_token_is_name(&afw_s_while)) {
586 afw_compile_get_token();
587 if (!afw_compile_token_is(open_parenthesis)) {
590 argv[1] = afw_compile_parse_Expression(parser);
591 afw_compile_get_token();
592 if (!afw_compile_token_is(close_parenthesis)) {
596 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
599 afw_compile_create_contextual_to_cursor(start_offset),
600 2, argv, parser->p, parser->xctx);
628 afw_compile_save_cursor(start_offset);
633 afw_compile_get_token();
634 if (!afw_compile_token_is(open_parenthesis)) {
639 afw_compile_get_token();
641 if (!afw_compile_token_is(semicolon)) {
645 if (afw_compile_token_is_name(&afw_s_loc) ||
646 afw_compile_token_is_name(&afw_s_const))
649 block = afw_compile_parse_link_new_value_block(
650 parser, start_offset);
652 value = afw_compile_parse_OptionalDefineAssignment(parser);
655 value = afw_compile_parse_Assignment(parser, NULL);
661 afw_compile_get_token();
662 if (afw_compile_token_is(semicolon)) {
665 if (!afw_compile_token_is(comma)) {
668 afw_compile_get_token();
678 afw_compile_get_token();
679 if (!afw_compile_token_is(semicolon)) {
680 afw_compile_reuse_token();
681 argv[2] = afw_compile_parse_Expression(parser);
682 afw_compile_get_token();
683 if (!afw_compile_token_is(semicolon)) {
689 afw_compile_get_token();
691 if (!afw_compile_token_is(close_parenthesis)) {
693 value = afw_compile_parse_Assignment(parser, NULL);
698 afw_compile_get_token();
699 if (afw_compile_token_is(close_parenthesis)) {
702 if (!afw_compile_token_is(comma)) {
705 afw_compile_get_token();
713 argv[4] = afw_compile_parse_Statement(parser, NULL);
716 afw_compile_create_contextual_to_cursor(start_offset),
717 4, argv, parser->p, parser->xctx);
746 afw_compile_save_cursor(start_offset);
750 argv[1] = afw_compile_parse_OptionalDefineTarget(parser);
752 afw_compile_get_token();
753 if (!afw_compile_token_is_name(&afw_s_of))
758 argv[2] = afw_compile_parse_Expression(parser);
759 argv[3] = afw_compile_parse_Statement(parser, NULL);
762 afw_compile_create_contextual_to_cursor(start_offset),
763 3, argv, parser->p, parser->xctx);
786 afw_compile_save_cursor(start_offset);
787 afw_compile_get_token();
788 if (!afw_compile_token_is_unqualified_identifier()) {
789 afw_compile_reuse_token();
793 if (afw_compile_is_reserved_word(parser, parser->token->identifier_name))
798 afw_compile_parse_add_symbol_entry(parser,
799 parser->token->identifier_name);
804 parser->p, parser->xctx);
805 argv[2] = afw_compile_parse_FunctionSignatureAndBody(parser);
809 afw_compile_create_contextual_to_cursor(start_offset),
810 3, argv, parser->p, parser->xctx);
833 afw_compile_save_cursor(start_offset);
836 afw_compile_get_token();
837 if (!afw_compile_token_is(open_parenthesis)) {
840 condition = afw_compile_parse_Expression(parser);
841 afw_compile_get_token();
842 if (!afw_compile_token_is(close_parenthesis)) {
847 then = afw_compile_parse_Statement(parser, NULL);
850 afw_compile_get_token();
851 if (afw_compile_token_is_unqualified_identifier()) {
854 otherwise = afw_compile_parse_Statement(parser, NULL);
857 afw_compile_reuse_token();
861 afw_compile_reuse_token();
865 argc = otherwise ? 3 : 2;
876 afw_compile_create_contextual_to_cursor(start_offset),
877 argc, argv, parser->p, parser->xctx);
900 argv[1] = afw_compile_parse_AssignmentTarget(parser,
901 afw_compile_assignment_type_loc);
905 afw_compile_get_token();
906 if (!afw_compile_token_is(semicolon)) {
907 if (!afw_compile_token_is(equal)) {
910 argv[2] = afw_compile_parse_Expression(parser);
911 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
915 afw_compile_create_contextual_to_cursor(
916 parser->token->token_source_offset),
917 3, argv, parser->p, parser->xctx);
936 afw_compile_save_cursor(start_offset);
942 afw_compile_get_token();
943 if (!afw_compile_token_is(semicolon)) {
944 afw_compile_reuse_token();
945 argv[1] = afw_compile_parse_Expression(parser);
946 AFW_COMPILE_ASSERT_NEXT_TOKEN_IS_SEMICOLON;
950 afw_compile_create_contextual_to_cursor(start_offset),
951 1, argv, parser->p, parser->xctx);
969 afw_compile_save_cursor(start_offset);
975 afw_compile_get_token();
976 if (!afw_compile_token_is(open_parenthesis)) {
979 argv[1] = afw_compile_parse_Expression(parser);
980 afw_compile_get_token();
981 if (!afw_compile_token_is(close_parenthesis)) {
985 argv[2] = afw_compile_parse_Statement(parser, NULL);
988 afw_compile_create_contextual_to_cursor(start_offset),
989 2, argv, parser->p, parser->xctx);
1029 afw_compile_parse_Statement(
1037 if (was_expression) {
1038 *was_expression =
false;
1042 afw_compile_get_token();
1045 if (afw_compile_token_is(open_brace)) {
1046 result = afw_compile_parse_list_of_statements(parser,
true,
false);
1052 if (afw_compile_token_is(identifier) &&
1053 !parser->token->identifier_qualifier)
1058 result = impl_parse_LocStatement(parser);
1063 result = impl_parse_ConstStatement(parser);
1068 result = impl_parse_BreakStatement(parser);
1073 result = impl_parse_ContinueStatement(parser);
1078 result = impl_parse_DoWhileStatement(parser);
1083 result = impl_parse_ForStatement(parser);
1088 result = impl_parse_ForeachStatement(parser);
1093 result = impl_parse_IfStatement(parser);
1098 result = impl_parse_ReturnStatement(parser);
1103 result = impl_parse_WhileStatement(parser);
1108 result = impl_parse_FunctionStatement(parser);
1113 result = impl_parse_InterfaceStatement(parser);
1118 result = impl_parse_TypeStatement(parser);
1123 result = impl_parse_DeclareStatement(parser);
1148 if (afw_compile_token_is(semicolon)) {
1151 was_assignment_expression =
false;
1152 result = afw_compile_parse_AssignmentStatement(parser,
1153 &was_assignment_expression);
1154 if (was_assignment_expression)
1157 afw_compile_get_token();
1158 if (afw_compile_token_is(semicolon)) {
1159 was_assignment_expression =
false;
1162 afw_compile_reuse_token();
1166 if (was_assignment_expression) {
1167 if (was_expression) {
1168 *was_expression = was_assignment_expression;
1199 afw_compile_parse_Script(
1209 if (afw_compile_next_raw_starts_with_z(
"#!")) {
1210 afw_compile_get_raw_line(&line);
1215 "Shebang line must contain afw to be recognized as an "
1216 "adaptive script in a hybrid value");
1221 return afw_compile_parse_TestScript(parser);
1226 result = afw_compile_parse_list_of_statements(parser,
false,
true);
1232 impl_test_script_get_next_key_value(
1247 afw_compile_save_cursor(*string_offset);
1249 for (*key = NULL, *
string = NULL;;) {
1251 afw_compile_get_raw_line(&line);
1252 if (afw_compile_is_at_eof()) {
1264 end = line.s + line.len;
1286 if (*c ==
':' || *c ==
' ') {
1288 parser->p, parser->xctx);
1304 else if (*c !=
' ') {
1320 remaining.s = start;
1321 remaining.len = end - start;
1325 afw_compile_save_cursor(start_cursor);
1326 afw_compile_save_cursor(*string_offset);
1328 afw_compile_save_cursor(end_cursor);
1329 afw_compile_get_raw_line(&line);
1331 *string_length = end_cursor - start_cursor;
1333 parser->full_source->s + start_cursor,
1334 *string_length, parser->p, parser->xctx);
1338 afw_compile_restore_cursor(end_cursor);
1340 *string_length = end_cursor - start_cursor - 1;
1342 parser->full_source->s + start_cursor,
1343 *string_length, parser->p, parser->xctx);
1355 *string_offset = start - parser->full_source->s;
1356 for (c = end - 1; c > start && *c ==
' '; c--);
1357 *string_length = c - start + 1;
1359 parser->p, parser->xctx);
1380 (*string)->len > afw_s_error.len &&
1381 *((*string)->s + afw_s_error.len) !=
':')
1384 "Must be \"error\" by itself or \"error:\" immediately "
1385 "followed by the exact error message expected");
1456 afw_compile_parse_TestScript(
1482 afw_compile_save_cursor(start_offset);
1485 if (afw_compile_next_raw_starts_with_z(
"#!")) {
1486 afw_compile_get_raw_line(&line);
1493 "Shebang line must contain afw and -s[yntax] test_script to "
1494 "be recognized as an adaptive test script");
1500 parser->p, parser->xctx);
1502 &afw_s_tests, test_list, parser->xctx);
1505 for (global_source_type = NULL, test_script_id = NULL;;)
1507 impl_test_script_get_next_key_value(parser,
1508 &key, &
string, &string_offset, &string_length);
1510 test_script_id = string;
1512 else if (!test_script_id) {
1514 "test_script: must be specified first");
1526 "skip: must be true or false");
1532 AFW_COMPILE_THROW_ERROR_FZ(
1537 global_source_type = string;
1540 key,
string, parser->xctx);
1543 if (!global_source_type) {
1544 global_source_type = &afw_s_script;
1546 &afw_s_sourceType, global_source_type, parser->xctx);
1550 for (test_object = NULL; ;) {
1555 &afw_s_source, parser->xctx))
1560 &afw_s_expect, parser->xctx))
1573 &afw_s_test,
string, parser->xctx);
1583 "skip: must be true or false");
1589 AFW_COMPILE_THROW_ERROR_FZ(
1594 key,
string, parser->xctx);
1599 &source_line, &source_column,
1600 parser->full_source,
1601 string_offset, 4, parser->xctx);
1607 string_offset, source_line, source_column);
1609 &afw_s_expectLocation, expect_location, parser->xctx);
1611 &afw_s_expectLineNumberInTestScript,
1615 &afw_s_expectColumnNumberInTestScript,
1619 &afw_s_expectCodepointOffsetInTestScript,
1623 &afw_s_expectCodepointLengthInTestScript,
1627 &afw_s_expectUTF8OctetOffsetInTestScript,
1631 &afw_s_expectUTF8OctetLengthInTestScript,
1638 &source_line, &source_column,
1639 parser->full_source,
1640 string_offset, 4, parser->xctx);
1646 string_offset, source_line, source_column);
1648 &afw_s_sourceLocation, source_location, parser->xctx);
1650 &afw_s_sourceLineNumberInTestScript,
1654 &afw_s_sourceColumnNumberInTestScript,
1658 &afw_s_sourceCodepointOffsetInTestScript,
1662 &afw_s_sourceCodepointLengthInTestScript,
1666 &afw_s_sourceUTF8OctetOffsetInTestScript,
1670 &afw_s_sourceUTF8OctetLengthInTestScript,
1675 impl_test_script_get_next_key_value(parser,
1676 &key, &
string, &string_offset, &string_length);
1680 parser->full_source->s, parser->full_source->len,
1681 parser->p, parser->xctx);
1683 &afw_s_source,
string, parser->xctx);
1691 parser->p, parser->xctx);
1693 afw_compile_create_contextual_to_cursor(start_offset),
1694 1, argv, parser->p, parser->xctx);
#define AFW_DEFINE_INTERNAL(type)
Define an internal function for /src/afw/ source*.c files.
Adaptive Framework Core Internal.
afw_object_set_property_as_integer(const afw_object_t *object, const afw_utf8_t *property_name, afw_integer_t internal, afw_xctx_t *xctx)
Set property function for data type integer values.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
afw_object_set_property_as_list(const afw_object_t *object, const afw_utf8_t *property_name, const afw_list_t *internal, afw_xctx_t *xctx)
Set property function for data type list values.
afw_data_type_object
Data type struct for object.
afw_value_create_object(const afw_object_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type object value.
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.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
struct afw_compile_internal_args_s afw_compile_args_t
apr_size_t afw_size_t
size_t.
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
afw_compile_internal_assignment_type_t
Enum for assignment types.
#define AFW_COMPILE_THROW_ERROR_Z(message_z)
afw_function_definition_test_script_runtime_support
Function definition test_script_runtime_support.
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_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_mod
Adaptive Function min
afw_function_definition_add
Adaptive Function abs
afw_function_definition_subtract
Adaptive Function substring
afw_function_definition_foreach
Function definition foreach.
afw_function_definition_if
Adaptive Function gt<script>
afw_function_definition_while
Adaptive Function script
afw_function_definition_loc
Adaptive Function le<script>
afw_function_definition_const
Function definition const.
afw_function_definition_continue
Function definition continue.
afw_function_definition_for
Function definition for.
afw_function_definition_assign
Function definition assign.
afw_function_definition_do_while
Function definition do_while.
afw_function_definition_break
Adaptive Function bag_size<script>
afw_function_definition_return
Adaptive Function nex<script>
#define afw_list_create_generic(p, xctx)
Create an value list in memory.
afw_list_add_value(const afw_list_t *instance, const afw_value_t *value, afw_xctx_t *xctx)
Call method add_value of interface afw_list_setter.
#define afw_list_of_create(data_type, p, xctx)
Create an list of a specific data type in memory.
#define afw_object_has_property(instance, property_name, xctx)
Call method has_property of interface afw_object.
#define afw_object_create(p, xctx)
Create an empty unmanaged object in memory.
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
afw_integer_t afw_safe_cast_size_to_integer(afw_size_t size, afw_xctx_t *xctx)
Safely cast afw_size_t to afw_integer_t.
#define afw_utf8_create_copy(s, len, p, xctx)
Make a utf-8 sting from chars in pool specified.
afw_boolean_t afw_utf8_starts_with_z(const afw_utf8_t *string, const afw_utf8_z_t *starts_with_z)
Check to see if a string starts with a utf8_z string.
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.
afw_utf8_line_column_of_offset(afw_size_t *line_number, afw_size_t *column_number, const afw_utf8_t *s, afw_size_t offset, int tab_size, afw_xctx_t *xctx)
Determine the line and column of an offset in a string.
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
afw_utf8_contains(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string contains another string.
afw_boolean_t afw_utf8_starts_with(const afw_utf8_t *string, const afw_utf8_t *starts_with)
Check to see if a string starts with another string.
const afw_value_t * afw_value_block_finalize(const afw_value_block_t *block, afw_size_t argc, const afw_value_t *const *argv, afw_xctx_t *xctx)
Create and link a new block.
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.
afw_value_null
Adaptive value null.
#define afw_value_is_any_call(A_VALUE)
Macro to determine if value is a call.
afw_value_true
Adaptive value true.
Interface afw_list public struct.
Interface afw_object public struct.
NFC normalized UTF-8 string.
struct for afw_value_block_t
Interface afw_value public struct.