?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Function Manager' ??
MODULE clm$f_function_manager;

{
{ PURPOSE:
{   This module contains the procedures that support the scanning and evaluation of "built-in" functions.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$value
*copyc cle$ecc_function_processing
*copyc clt$argument_descriptor_table
*copyc clt$argument_value_table
*copyc clt$command_line_index
*copyc clt$command_line_size
*copyc clt$function
*copyc clt$name
*copyc oss$job_paged_literal
*copyc ost$status
?? POP ??
*copyc clp$append_status_parse_state
*copyc clp$delete_current_format_token
*copyc clp$f_scan_expression
*copyc clp$f_scan_token
*copyc clp$initialize_parse_state
*copyc clp$insert_format_marker
*copyc clp$isolate_balanced_text
*copyc clp$recognize_format_tokens
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal

?? TITLE := 'clp$f_scan_argument_list', EJECT ??
*copyc clh$scan_argument_list

  PROCEDURE [XDCL, #GATE] clp$f_scan_argument_list
    (    function_name: clt$name;
         argument_list: string ( * );
     VAR status: ost$status);

    VAR
      spaces_before_not_part_of_token: [STATIC, READ, oss$job_paged_literal] set of clt$lexical_unit_kind :=
            [clc$lex_unknown, clc$lex_dot, clc$lex_colon, clc$lex_left_parenthesis, clc$lex_query,
            clc$lex_add, clc$lex_subtract, clc$lex_string, clc$lex_name, clc$lex_unsigned_decimal,
            clc$lex_alpha_number];

    VAR
      local_status: ost$status,
      scratch_value: clt$value,
      scratch_vks: clt$value_kind_specifier,
      parse: clt$parse_state,
      argument_list_index: clt$command_line_index,
      argument_index: clt$command_line_index,
      argument_size: clt$command_line_size,
      argument_number: 1 .. clc$max_arguments,
      argument_count: 0 .. clc$max_arguments;


    status.normal := TRUE;
    local_status.normal := TRUE;
    IF local_status.normal THEN
      argument_number := 1;
      clp$initialize_parse_state (^argument_list, NIL, parse);
      clp$recognize_format_tokens (FALSE);
      clp$f_scan_token (clc$slu_non_space, parse);
      clp$recognize_format_tokens (TRUE);
      IF parse.unit.kind = clc$lex_end_of_line THEN
        argument_index := parse.index;
      ELSE
        argument_index := parse.unit_index;
      IFEND;

    /scan_arguments/
      WHILE argument_index <= STRLENGTH (argument_list) DO
        clp$isolate_balanced_text (argument_list, argument_index, argument_list_index);
        argument_size := argument_list_index - argument_index;
        scratch_vks.kind := clc$any_value;
        clp$insert_format_marker (clc$parameter_begin, 0);
        clp$f_scan_expression (argument_list (argument_index, argument_size), scratch_vks, scratch_value,
              local_status);
        IF NOT local_status.normal THEN
          IF (clc$min_ecc_expression_result <= local_status.condition) AND
                (local_status.condition <= clc$max_ecc_expression_result) THEN
            osp$append_status_parameter (osc$status_parameter_delimiter, ' for argument', local_status);
            osp$append_status_integer (' ', argument_number, 10, FALSE, local_status);
            osp$append_status_parameter (' ', 'of function', local_status);
            osp$append_status_parameter (' ', function_name.value, local_status);
          IFEND;
          EXIT /scan_arguments/;
        IFEND;
        clp$insert_format_marker (clc$parameter_end, 0);
        parse.index := argument_list_index;
        clp$f_scan_token (clc$slu_non_space, parse);
        CASE parse.unit.kind OF
        = clc$lex_comma =
          clp$f_scan_token (clc$slu_non_space, parse);
        = clc$lex_end_of_line =
          EXIT /scan_arguments/;
        ELSE
          IF NOT (parse.previous_unit_is_space AND (parse.unit.kind IN spaces_before_not_part_of_token)) THEN
            osp$set_status_abnormal ('CL', cle$expecting_argument_term, '', local_status);
            clp$append_status_parse_state (osc$status_parameter_delimiter, parse, local_status);
            osp$append_status_integer (osc$status_parameter_delimiter, argument_number, 10, FALSE,
                  local_status);
            osp$append_status_parameter (osc$status_parameter_delimiter, function_name.value, local_status);
            EXIT /scan_arguments/;
          IFEND;
        CASEND;
        clp$delete_current_format_token;
        argument_number := argument_number + 1;
        argument_index := parse.unit_index;
      WHILEND /scan_arguments/;
    IFEND;
    status := local_status;

  PROCEND clp$f_scan_argument_list;

MODEND clm$f_function_manager;
