-- (C) Copyright International Business Machines Corporation 16 September
-- 1991.  All Rights Reserved.
--
-- See the file USERAGREEMENT distributed with this software for full
-- terms and conditions of use.
-- SCCS Info: @(#)chdescriptors	1.3 3/2/92

using (predefined, chdescriptors, common, interpform)

-- atomic operation macros

empty : empty := ;

comma : template_operation := 'char' : ',';
semicolon : template_operation := 'char' : ';';
leftparen : template_operation := 'char' : '(';
rightparen : template_operation := 'char' : ')';
space : template_operation := 'char' : ' ';

qualifier : template_operation := 'qualifier' : empty;
newline : template_operation := 'line' : {'true', 0};
assign : template_operation := 'string' : " = ";
assign_bottom : template_operation := 'string' : " = & dr_bottom;";
assign_boolean_tsdr : template_operation := 'string' : " = & dr_boolean;";
assign_integer_tsdr : template_operation := 'string' : " = & dr_integer;";
case_error : template_operation := 'string' : " goto ch_case_error;";
depletion : template_operation := 'string' : " goto ch_depletion;";
dividebyzero : template_operation := 'string' : " goto ch_dividebyzero;";
range_error : template_operation := 'string' : " goto ch_range_error;";
notfound : template_operation := 'string' : " goto ch_notfound;";
raise_exception : template_operation := 'string' : " goto ch_raise_exception;";

destination : template_operation := 'operand' : {'VALCELL', 0};
destination_address : template_operation := 'operand' : {'ADDRESS', 0};
destination_object : template_operation := 'operand' : {'OBJECT', 0};
destination_tsdr : template_operation := 'operand' : {'TSDR', 0};
source1 : template_operation := 'operand' : {'VALCELL', 1};
source1_address : template_operation := 'operand' : {'ADDRESS', 1};
source1_object : template_operation := 'operand' : {'OBJECT', 1};
source1_scalar : template_operation := 'operand' : {'SCALAR', 1};
source1_tsdr : template_operation := 'operand' : {'TSDR', 1};
source2 : template_operation := 'operand' : {'VALCELL', 2};
source2_address : template_operation := 'operand' : {'ADDRESS', 2};
source2_scalar : template_operation := 'operand' : {'SCALAR', 2};
integer_value : template_operation := 'parameter' : 'value';

-- deepest code generator sub-programs

continue : template_operations := {
     'variable' : 'increment',
     newline,
     'iterate' : empty
};

continue_choice : template_operation :=
     'choice' : {{"continue", continue},
		 {"finished", new}};

discard_unknown : template_operations := {
     newline,
     'string' : "(*(",
     destination_tsdr,
     'string' : ")->finalize)(",
     destination,
     'string' : ",F_DISCARD,sched);"
};

discard_other : template_operation :=
     'nest' : {'null', discard_unknown};

indexed_qualifier : template_operation :=
     'nest' : {'null', {'string' : "QUAL(", qualifier, rightparen}};

-- deep code generator sub-programs

all_arguments : template_operations := {
     'string' : "arguments[",
     'variable' : 'counter',
     'string' : "] = ",
     destination_address,
     comma,
     continue_choice
};

assign_dst_tsdr : template_operations := {
     newline,
     destination_tsdr,
     'string' : " = & dr_",
     'parameter' : 'tsdr',
     semicolon
};

binary_operation : template_operations := {
     source1_scalar,
     'parameter' : 'operator',
     source2_scalar
};

bottom_tsdr_destination : template_operations :=
    {newline, destination_tsdr, assign_bottom};


branch_execute : template_operations := {
     'string' : " goto c",
     'variable' : 'target_ccode',
     semicolon
};

branch_interpret : template_operations := {
     'string' : "{current->ip = ",
     'variable' : 'target_statement',
     'string' : "; return;}"
};

compare_unknown : template_operations := {
    leftparen,     -- "("
    source1_tsdr,
    'string' : "->equal)"
};

compare_eq_Name : template_operations := {
    'string' : "eq_",
    'parameter' : 'tsdr'
};

compare_other : template_operations := {
     'parameter' : 'modifier',
     'choice' : {{"unknown", compare_unknown},
		 {"known", compare_eq_Name}},
     leftparen,
     source1,
     comma,
     source2,
     rightparen
};

compare_boolean : template_operations := {
     'parameter' : 'modifier',
     source1_scalar,
     'string' : " ? ",
     source2_scalar,
     'string' : " : ! ",
     source2_scalar
};

copy_scalar : template_operations := {
     destination_object,
     assign,
     source1_object,
     semicolon
};

copy_unknown : template_operations := {
     leftparen,    -- "("
     source1_tsdr,
     'string' : "->copy)"
};

copy_cp_Name : template_operations := {
     'string' : "cp_",
     'parameter' : 'tsdr'
};

copy_other : template_operations := {
     'string' : "if((ch_returncode = ",
     'choice' : {{"unknown", copy_unknown},
		 {"known", copy_cp_Name}},
     'string' : "(& ch_val, ",
     source1,
     'string' : ")) != Normal)",
     raise_exception,
     discard_other,
     newline,
     destination, 'string' : " = ch_val;",
     newline,
     destination_tsdr,
     'choice' : {{"unknown", {'string' : " = datarepmap[",
			      source1_tsdr,
			      'string' : "->number];"}},
		 {"known", {'string' : " = & dr_",
			    'parameter' : 'tsdr',
			     semicolon}}}
};

divide_by_0_unknown : template_operations := {
     'string' : "if (",
     source2_scalar,
    'string' : " == 0)",
     dividebyzero,
     newline
};

divide_by_0_test : template_operation := 
     'choice' : {{"negative", new},
		 {"zero", {dividebyzero}},
		 {"positive", new},
		 {"unknown", divide_by_0_unknown}};

do_return : template_operations := {
     'string' : "if (ch_caller = do_return(",
     destination,
     'string' : ")) {",
     'line' : {'true', 2}
};

enter_table_at : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     destination_address,
     comma,
     source1_address,
     'string' : ",TRUE, ",
     integer_value,
     'string' : ")) != Normal)",
     raise_exception
};

function1_schedule : template_operation :=
     'nest' : {'null', {'string' : "if ((ch_returncode = ",
			'parameter' : 'function',
			destination_address,
			comma,
			source1_address,
			'string' : ",sched)) != Normal)"}};

key_arguments : template_operations := {
     'string' : "arguments[",
     'variable' : 'counter',
     'string' : "] = ",
     source2_address,
     comma,
     continue_choice
};

lookup_at_check : template_operations := {
     integer_value,
     'string' : " >= (ch_t = ",
     source1,
     'string' : ".table)->size)"
};

lookup_at : template_operations := {
     discard_other,
     newline,
     'string' : "(*(ch_t->tbls[ORDER_TBL].des->lookup_at))",
     newline,
     'string' : "  (ch_t, ORDER_TBL, & ",
     destination,
     comma,
     integer_value,
     'string' : ");",
     newline,
     destination_tsdr,
     'string' : " = qdatarepmap[ch_t->tsdr->number];"
};

newreal : template_operations := {
     'string' : "if ((ch_real = (dfd_real *) new(dfd_real)) == nil)",
     depletion,
     newline,
     destination,
     'string' : ".real = ch_real;",
     newline,
     destination_tsdr,
     'string' : " = & dr_real;"
};

-- im'pure' code generator sub-programs

binary_inline : template_operations := {
     destination,
     'char' : '.',
     'parameter' : 'tag',
     assign,
     'nest' : {'null', binary_operation},
     semicolon,
     'nest' : {'null', assign_dst_tsdr}
};

branch : template_operation :=
    'choice' : {{"interpret", branch_interpret},
		{"execute", branch_execute}};

branch_choice : template_operation :=
    'nest' : {'branch', {branch}};

compare_assign : template_operations := {
     destination,
     'string' : ".boolean = (",
     'choice' : {{"scalar", binary_operation},
		 {"boolean", compare_boolean},
		 {"other", compare_other}},
     'string' : ");",
     newline,
     destination_tsdr,
     assign_boolean_tsdr
};

compare_branch : template_operations := {
     'string' : "if ( ",
     'choice' : {{"scalar", binary_operation},
		 {"boolean", compare_boolean},
		 {"other", compare_other}},
     'string' : " )",
     branch_choice
};

compare : template_operations := {
     'choice' : {{"assign", compare_assign},
		 {"branch", compare_branch}}
};

conditional_branch : template_operations := {
     'string' : "if ( ",
     'parameter' : 'modifier',
     destination,
     'string' : ".boolean )",
     branch
};

conditional_branches : template_operations := {
     'nest' : {'branch', conditional_branch},
     continue_choice
};

enter_table_at_check : template_operations := {
     destination,
     'string' : ".table->size < ",
     integer_value,
     rightparen,
     range_error,
     newline,
     'nest' : {'null', enter_table_at}
};

enter_table_at_known : template_operations := {
     'string' : "if (",
     'nest' : {'null', enter_table_at_check}
};

enter_table_at_unknown : template_operations := {
     'string' : "ch_i = ",
     'operand' :{'VALCELL', 2},
     'string' : ".integer;",
     newline,
     'string' : "if (ch_i < 0 || ",
     'nest' : {'null', enter_table_at_check}
};

enter_table_at_choice : template_operations := {
     'choice' : {{"negative", {range_error}},
		 {"zero", enter_table_at},
		 {"positive", enter_table_at_known},
		 {"unknown", enter_table_at_unknown}}
};

finder : template_operations := {
     'string' : "if (findfunc(",
     destination_address,
     comma,
     source1_address,
     'string' : ",(",
     'line' : {'true', 8},
     'nest' : {'multiple', key_arguments},
     'string' : "& arguments[0]),sched,",
     'variable' : 'int_one',
     'string' : ") == FAILURE)"
};

function1_schedule_raise : template_operations := {
     function1_schedule,
     raise_exception
};

finder_start : template_operation :=
     'nest' : {'null', finder};

literal : template_operations := {
     destination,
     'char' : '.',
     'parameter' : 'tag',
     assign,
     qualifier,
     semicolon,
     'nest' : {'null', assign_dst_tsdr}
};

lookup_at_check_0 : template_operations := {
     'string' : "if ( !((ch_t = ",
     source1,
     'string' : ".table)->size) )"
};

lookup_at_check_known : template_operations := {
     'string' : "if (",
     'nest' : {'null', lookup_at_check}
};

lookup_at_check_unknown : template_operations := {
     'string' : "if((ch_i = ",
     source2,
     'string' : ".integer) < 0 || ",
     'nest' : {'null', lookup_at_check}
};

lookup_at_0_or_err : template_operations := {
     'nest' : {'null', lookup_at_check_0},
     notfound,
     'nest' : {'null', lookup_at}
};

lookup_at_known_or_err : template_operations := {
     'nest' : {'null', lookup_at_check_known},
     notfound,
     'nest' : {'null', lookup_at}
};

lookup_at_unknown_or_err : template_operations := {
     'nest' : {'null', lookup_at_check_unknown},
     notfound,
     'nest' : {'null', lookup_at}
};

lookup_at_0_or_goto : template_operations := {
     'nest' : {'null', lookup_at_check_0},
     branch_choice,
     'nest' : {'null', lookup_at}
};

lookup_at_known_or_goto : template_operations := {
     'nest' : {'null', lookup_at_check_known},
     branch_choice,
     'nest' : {'null', lookup_at}
};

lookup_at_unknown_or_goto : template_operations := {
     'nest' : {'null', lookup_at_check_unknown},
     branch_choice,
     'nest' : {'null', lookup_at}
};

multiple_qualify_schedule : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     leftparen,
     'line' : {'true', 8},
     'nest' : {'multiple', all_arguments},
     newline,
     'string' : "arguments[",
     'variable' : 'counter',
     'string' : "+1] = nil,& arguments[0]),",
     indexed_qualifier,
     'string' : ",sched)) != Normal)",
     'line' : {'true', -6},
     newline,
     raise_exception
};

relation_assign : template_operations := {
     destination,
     'string' : ".boolean = (",
     'nest' : {'null', binary_operation},
     'string' : ");"
};   

relation_branch : template_operations := {
     'string' : "if ( ",
     'nest' : {'null', binary_operation},
     'string' : " )",
     branch_choice
};

relation : template_operations := {
     'choice' : {{"assign", relation_assign},
		 {"branch", relation_branch}}
};
     
select_branches : template_operations := {
     'nest' : {'select', conditional_branches}
};

unary_inline : template_operations := {
     destination,
     'char' : '.',
     'parameter' : 'tag',
     assign,
     'parameter' : 'operator',
     source1_scalar,
     semicolon,
     'nest' : {'null', assign_dst_tsdr}
};

-- 'pure' code generator sub-programs

binary_function : template_operations := {
     'string' : "if (!",
     'parameter' : 'function',
     destination_address,
     comma,
     source1_scalar,
     comma,
     source2_scalar,
     'string' : "))",
     depletion
};

convert_to_integer : template_operations := {
     destination,
     'string' : ".integer = ",
     source1_scalar,
     semicolon,
     newline,
     destination_tsdr,
     'string' : " = & dr_integer;"
};

convert_to_ordered_enumeration : template_operations := {
     'string' : "if (",
     source1_scalar,
     'string' : " < 0 || ",
     source1_scalar,
     'string' : " >= ",
     qualifier,
     rightparen,-- ")"
     range_error,
     newline,
     destination,
     'string' : ".ord_enum = ",
     source1_scalar,
     semicolon,
     newline,
     destination_tsdr,
     'string' : " = & dr_ord_enumeration;"
};

dummy : template_operations := {'string' : "..."};

end_selector : template_operations := {
    'string' : "end_selector(",
    destination_address,
    comma,
    source1_address,
    'parameter' : 'tag'
};

enter_table : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     destination_address,
     comma,
     source1_address,
     'string' : ",FALSE,0)) != Normal)",
     raise_exception
};

function2_schedule_raise : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     destination_address,
     comma,
     source1_address,
     comma,
     source2_address,
     'string' : ",sched)) != Normal)",
     raise_exception
};

function0_qualify_schedule_raise : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     destination_address,
     comma,
     indexed_qualifier,
     'string' : ",sched)) != Normal) ",
     raise_exception
};

function1_qualify_schedule_raise : template_operations := {
     'string' : "if ((ch_returncode = ",
     'parameter' : 'function',
     destination_address,
     comma,
     source1_address,
     comma,
     indexed_qualifier,
     'string' : ",sched)) != Normal)",
     raise_exception
};

-- hermes code descriptors

ch_and : statement_descriptor := {
    'and', 'continue', 'ccode', 'assigned',
    {'boolean'}, 'eliminate2', 'null',
    binary_inline,
    {{'opcode', "and"}, {'operator', "&"},
     {'tag', "boolean"}, {'tsdr', "boolean"}}
};

ch_attributename : statement_descriptor := {
    'attributename', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'null', 'null',
    function0_qualify_schedule_raise,
    {{'opcode', "attributename"}, {'function', "che_attributename("}}
};
      
ch_assert : statement_descriptor := {
    'assert', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'null', 'null',
    dummy,
    {{'opcode', "assert"}}
};
      
ch_block : statement_descriptor := {
    'block', 'frame', 'ccode', 'referenced',
    new, 'null', 'null',
    {'string' : "if((ch_returncode = che_block(QUAL(",
     qualifier,
     'string' : "),sched)) != Normal)",
     raise_exception},
    {{'opcode', "block"}}
};
      
ch_boolean : statement_descriptor := {
    'boolean', 'continue', 'ccode', 'assigned',
    {'boolean'}, 'literal', 'null',
    literal,
    {{'opcode', "boolean"}, {'tag', "boolean"}, {'tsdr', "boolean"}}
};
      
ch_branch : statement_descriptor := {
    'branch', 'branch', 'ccode', 'referenced',
    new, 'null', 'branch',
    {branch},
    {{'opcode', "branch"}}
};
      
ch_branch_false : statement_descriptor := {
    'branch_false', 'branch', 'ccode', 'referenced',
    {'boolean'}, 'cbranch', 'branch',
    conditional_branch,
    {{'opcode', "branch_false"}, {'modifier', "!"}}
};
      
ch_branch_true : statement_descriptor := {
    'branch_true', 'branch', 'ccode', 'referenced',
    {'boolean'}, 'cbranch', 'branch',
    conditional_branch,
    {{'opcode', "branch_true"}, {'modifier', ""}}
};
      
ch_call : statement_descriptor := {
    'call', 'continue', 'block', 'referenced',
    {'outport', 'unknown'}, 'null', 'null',
    multiple_qualify_schedule,
    {{'opcode', "call"}, {'function', "che_call("}}
};
      
ch_case : statement_descriptor := {
    'case', 'continue', 'ccode', 'assigned',
    {'enumeration', 'variant'}, 'null', 'pure',
    {destination,
     'string' : ".enumeration = ",
     source1_scalar,
     'string' : "->info.variant_case;",
     newline,
     destination_tsdr,
     'string' : " = & dr_enumeration;"},
    {{'opcode', "case"}, {'tag', "variant"}}
};
      
ch_ord_case : statement_descriptor := {
    'ord_case', 'continue', 'ccode', 'assigned',
    {'ordered_enumeration', 'variant'}, 'null', 'pure',
    {destination,
     'string' : ".ord_enum = ",
     source1_scalar,
     'string' : "->info.variant_case;",
     newline,
     destination_tsdr,
     'string' : " = & dr_ord_enumeration;"},
    {{'opcode', "ord_case"}, {'tag', "variant"}}
};

ch_checkdefinitions : statement_descriptor := {
    'checkdefinitions', 'continue', 'ccode', 'modified',
    {'record', 'table'}, 'null', 'null',
    dummy,
    {{'opcode', "checkdefinitions"}}
};
      
ch_chs_lit : statement_descriptor := {
    'chs_lit', 'continue', 'ccode', 'assigned',
    {'string'}, 'literal', 'pure',
    {'string' : "if( !chs_lit(",
     destination_address,
     comma,
     qualifier,
     'string' : ") )",
     depletion},
    {{'opcode', "chs_lit"}}
};
      
ch_concat : statement_descriptor := {
    'concat', 'continue', 'ccode', 'assigned',
    {'table'}, 'null', 'pure',
    function2_schedule_raise,
    {{'opcode', "concat"}, {'function', "che_concat("}}
};
      
ch_connect : statement_descriptor := {
    'connect', 'continue', 'ccode', 'assigned',
    {'outport', 'inport'}, 'null', 'null',
    {'string' : "if (",
     source1,
     'string' : ".inport->refcount == MAXCOUNTER)",
     depletion,
     discard_other,
     newline,
     source1,
     'string' : ".inport->refcount++;",
     newline,
     destination,
     'string' : ".outport = ",
     source1,
     'string' : ".inport;",
     newline,
     destination_tsdr,
     'string' : " = & dr_outport;"},
    {{'opcode', "connect"}}
};
      
ch_copy : statement_descriptor := {
    'copy', 'ubiquitous', 'ccode', 'assigned',
    {'unknown'}, 'null', 'ubiquitous',
    {'choice' : {{"scalar", copy_scalar},
		 {"other", copy_other}}},
    {{'opcode', "copy"}}
};
      
ch_create : statement_descriptor := {
    'create', 'continue', 'ccode', 'assigned',
    {'outport', 'program'}, 'null', 'null',
    function1_qualify_schedule_raise,
    {{'opcode', "create"}, {'function', "che_create("}}
};
      
ch_currentprogram : statement_descriptor := {
    'currentprogram', 'continue', 'ccode', 'assigned',
    {'program'}, 'null', 'null',
    {'string' :
	"if ((ch_val.program = make_pgm_copy(sched->ready->prog)) == nil)",
     depletion,
     newline,
     discard_other,
     newline,
     destination,
     'string' : " = ch_val; ",
     destination_tsdr,
     'string' : " = & dr_program;"},
    {{'opcode', "currentprogram"}}
};
      
ch_discard : statement_descriptor := {
    'discard', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'discard', 'ubiquitous',
    {'choice' : {{"scalar", new},
		 {"other", discard_unknown}},
     newline,
     'nest' : {'null', bottom_tsdr_destination}},
    {{'opcode', "discard"}}
};
      
ch_dissolve : statement_descriptor := {
    'dissolve', 'continue', 'ccode', 'assigned',
    {'unknown', 'variant'}, 'null', 'null',
    {discard_other,
     newline,
     destination_object, assign, source1,
     'string' : ".variant->data[VARIANT_COMPONENT];",
     newline,
     'string' : "{ freedotmain(",
     source1,
     'string' : ".variant, VARIANT_SIZE); }",
     newline,
     source1_tsdr, assign_bottom},
    {{'opcode', "dissolve"}}
};
    
ch_drop : statement_descriptor := {
    'drop', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'null', 'null',
    dummy,
    {{'opcode', "drop"}}
};
      
ch_empty : statement_descriptor := {
    'empty', 'continue', 'ccode', 'assigned',
    {'boolean', 'inport'}, 'null', 'pure',
    {destination,
     'string' : ".boolean = (",
     source1,
     'string' : ".inport->info.inport.queue == nil);",
     newline,
     destination_tsdr,
     assign_boolean_tsdr},
    {{'opcode', "empty"}}
};
      
ch_endblock : statement_descriptor := {
    'endblock', 'continue', 'ccode', 'referenced',
    new, 'null', 'pure',
    {'string' : "che_endblock(sched);"},
    {{'opcode', "endblock"}}
};
      
ch_endget : statement_descriptor := {
    'endget', 'continue', 'ccode', 'referenced',
    {'unknown', 'table'}, 'null', 'pure',
    end_selector,
    {{'opcode', "endget"}, {'tag', ",sched,GET);"}}
};
      
ch_endidxfind : statement_descriptor := {
    'endidxfind', 'continue', 'ccode', 'referenced',
    {'unknown', 'table'}, 'null', 'pure',
    end_selector,
    {{'opcode', "endidxfind"}, {'tag', ",sched,FIND);"}}
};
      
ch_endinspect_poly : statement_descriptor := {
    'endinspect_poly', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'null', 'pure',
    {destination_tsdr, assign_bottom},
    {{'opcode', "endinspect_poly"}}
};
      
ch_endprocess : statement_descriptor := {
    'endprocess', 'emerge', 'ccode', 'referenced',
    new, 'null', 'null',
    {'string' : "che_endprocess(sched); return;"},
    {{'opcode', "endprocess"}}
};
      
ch_enum_lit : statement_descriptor := {
    'enum_lit', 'continue', 'ccode', 'assigned',
    {'enumeration'}, 'literal', 'null',
    literal,
    {{'opcode', "enum_lit"}, {'tag', "enumeration"}, {'tsdr', "enumeration"}}
};
      
ch_equal : statement_descriptor := {
    'equal', 'ubiquitous', 'ccode', 'assigned',
    {'boolean', 'unknown'}, 'eliminate2', 'compare',
    compare,
    {{'opcode', "equal"}, {'modifier', ""}, {'operator', " == "}}
};
      
ch_escape : statement_descriptor := {
    'escape', 'emerge', 'ccode', 'referenced',
    new, 'null', 'null',
    dummy,
    {{'opcode', "escape"}}
};
      
ch_exit : statement_descriptor := {
    'exit', 'emerge', 'ccode', 'referenced',
    new, 'null', 'null',
    {'string' : "ch_e = handler_type__exit; ch_val = ",
     indexed_qualifier,
     semicolon,
     'string' : " goto ch_exception;"},
    {{'opcode', "exit"}}
};
      
ch_find : statement_descriptor := {
    'find', 'continue', 'ccode', 'assigned',
    {'unknown', 'table', 'unknown'}, 'null', 'null',
    {finder_start,
     notfound},
    {{'opcode', "find"}}
};
      
ch_find_or_goto : statement_descriptor := {
    'find_or_goto', 'branch', 'ccode', 'assigned',
    {'unknown', 'table', 'unknown'}, 'null', 'null',
    {finder_start,
     branch_choice},
    {{'opcode', "find_or_goto"}}
};
      
ch_fremove : statement_descriptor := {
    'fremove', 'continue', 'ccode', 'assigned',
    {'unknown', 'unknown', 'table'}, 'null', 'pure',
    {'string' : "if ((ch_returncode = removefunc(",
     destination_address,
     comma,
     source1_address,
     comma,
     source2_address,
     'string' : ",sched,",
     qualifier,
     'string' : ",NO_TBL,(position *) nil)) != Normal)",
     raise_exception},    
    {{'opcode', "fremove"}}
};
      
ch_get_or_err : statement_descriptor := {
    'get_or_err', 'continue', 'ccode', 'modified',
    {'unknown', 'table'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "get_or_err"}, {'function', "get_selected_object("}}
};
      
ch_get_or_goto : statement_descriptor := {
    'get_or_goto', 'branch', 'ccode', 'modified',
    {'unknown', 'table'}, 'null', 'null',
    {function1_schedule,
     branch_choice},
    {{'opcode', "get_or_goto"}, {'function', "get_selected_object("}}
};
      
ch_hide : statement_descriptor := {
    'hide', 'continue', 'omit', 'referenced',
    {'variant'}, 'null', 'null',
    new,
    {{'opcode', "hide"}}
};
      
ch_iadd : statement_descriptor := {
    'iadd', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "iadd"}, {'tag', "integer"}, {'function', "chf_iadd("}}
};
      
ch_icvt_enum : statement_descriptor := {
    'icvt_enum', 'continue', 'ccode', 'assigned',
    {'ordered_enumeration', 'integer'}, 'convert', 'pure',
    convert_to_ordered_enumeration,
    {{'opcode', "icvt_enum"}, {'tag', "integer"}}
};
      
ch_icvt_real : statement_descriptor := {
    'icvt_real', 'continue', 'ccode', 'assigned',
    {'real', 'integer'}, 'convert', 'null',
    {'nest' : {'null', newreal},
     'string' : "*ch_real = ",
     source1_scalar,
     semicolon},
    {{'opcode', "icvt_real"}, {'tag', "integer"}}
};
      
ch_idivide : statement_descriptor := {
    'idivide', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'zero_test',
    {divide_by_0_test,
     'nest' : {'null', binary_inline}},
    {{'opcode', "idivide"}, {'operator', "/"},
     {'tag', "integer"}, {'tsdr', "integer"}}
};
      
ch_idxfind_or_err : statement_descriptor := {
    'idxfind_or_err', 'continue', 'ccode', 'modified',
    {'unknown', 'table'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "idxfind_or_err"}}
};
      
ch_idxfind_or_goto : statement_descriptor := {
    'idxfind_or_goto', 'branch', 'ccode', 'modified',
    {'unknown', 'table'}, 'null', 'null',
    {function1_schedule,
     'line' : {'true', 2},
     'string' : "if (ch_returncode = NotFound)",
     branch_choice,
     newline,
     'string' : " else goto ch_raise_exception;"},
    {{'opcode', "idxfind_or_goto"}}
};
      
ch_ige : statement_descriptor := {
    'ige', 'continue', 'ccode', 'assigned',
    {'boolean', 'integer'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "ige"}, {'tag', "integer"}, {'operator', " >= "}}
};
      
ch_igt : statement_descriptor := {
    'igt', 'continue', 'ccode', 'assigned',
    {'boolean', 'integer'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "igt"}, {'tag', "integer"}, {'operator', " > "}}
};
      
ch_ile : statement_descriptor := {
    'ile', 'continue', 'ccode', 'assigned',
    {'boolean', 'integer'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "ile"}, {'tag', "integer"}, {'operator', " <= "}}
};
      
ch_ilit : statement_descriptor := {
    'ilit', 'continue', 'ccode', 'assigned',
    {'integer'}, 'literal', 'null',
    literal,
    {{'opcode', "ilit"}, {'tag', "integer"}, {'tsdr', "integer"}}
};
      
ch_ilt : statement_descriptor := {
    'ilt', 'continue', 'ccode', 'assigned',
    {'boolean', 'integer'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "ilt"}, {'tag', "integer"}, {'operator', " < "}}
};
      
ch_imod : statement_descriptor := {
    'imod', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'zero_test',
    {divide_by_0_test,
     'nest' : {'null', binary_function}},
    {{'opcode', "imod"}, {'function', "chf_imod("},
     {'tag', "integer"}, {'tsdr', "integer"}}
};
      
ch_imultiply : statement_descriptor := {
    'imultiply', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "imultiply"}, {'tag', "integer"},
     {'function', "chf_imultiply("}}
};
      
ch_inegate : statement_descriptor := {
    'inegate', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate1', 'null',
    unary_inline,
    {{'opcode', "inegate"}, {'operator', "-"}, {'tag', "integer"},
     {'tsdr', "integer"}}
};
      
ch_initget : statement_descriptor := {
    'initget', 'continue', 'ccode', 'referenced',
    {'unknown', 'table'}, 'null', 'null',
    {discard_other,
     newline,
     'string' : "if ((ch_returncode = init_selector(",
     destination_address,
     comma,
     source1_address,
     'string' : ",nil,sched,GET,",
     qualifier,
     'string' : ")) != Normal)",
     raise_exception},
    {{'opcode', "initget"}}
};
      
ch_initidxfind : statement_descriptor := {
    'initidxfind', 'continue', 'ccode', 'referenced',
    {'unknown', 'table', 'unknown'}, 'null', 'null',
    {discard_other,
     'string' : "if ((ch_returncode = init_selector(",
     destination_address,
     comma,
     source1_address,
     'string' : ",(",
     'line' : {'true', 8},
     'nest' : {'multiple', key_arguments},
     'string' : "& arguments[0]),sched,FIND,(",
     source1,
     comma,
     'string' : ".table->ordered ? (",
     qualifier,
     'string' : "+1) : ",
     qualifier,
     'string' : "),0)) != Normal)",
     'line' : {'true', -6},
     raise_exception},
    {{'opcode', "initidxfind"}}
};

ch_insert : statement_descriptor := {
    'insert', 'continue', 'ccode', 'modified',
    {'table', 'unknown'}, 'null', 'pure',
    enter_table,
    {{'opcode', "insert"}, {'function', "insertfunc("}}
};

ch_insert_at : statement_descriptor := {
    'insert_at', 'continue', 'ccode', 'modified',
    {'table', 'unknown', 'integer'}, 'eliminate2', 'zero_test',
    enter_table_at_choice,
    {{'opcode', "insert_at"}, {'function', "insertfunc("}}
};
      
ch_inspect_poly : statement_descriptor := {
    'inspect_poly', 'continue', 'ccode', 'assigned',
    {'unknown', 'polymorph'}, 'null', 'null',
    function1_qualify_schedule_raise,
    {{'opcode', "inspect_poly"}, {'function', "che_inspect_poly("}}
};
      
ch_irem : statement_descriptor := {
    'irem', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'zero_test',
    {divide_by_0_test,
     'nest' : {'null', binary_function}},
    {{'opcode', "irem"}, {'function', "chf_irem("},
     {'tag', "integer"}, {'tsdr', "integer"}}
};
      
ch_isubtract : statement_descriptor := {
    'isubtract', 'continue', 'ccode', 'assigned',
    {'integer'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "isubtract"}, {'tag', "integer"},
     {'function', "chf_isubtract("}}
};
      
ch_jumpselect : statement_descriptor := {
    'jumpselect', 'branch', 'interpret', 'referenced',
    {'integer'}, 'null', 'null',
    new,	-- replace by switch generation (note end-of-switch (label?))
    {{'opcode', "jumpselect"}}
};
      
ch_lookup_at : statement_descriptor := {
    'lookup_at', 'continue', 'ccode', 'modified',
    {'unknown', 'table', 'integer'}, 'eliminate2', 'zero_test',
    {'choice' : {{"negative", {notfound}},
		 {"zero", lookup_at_0_or_err},
		 {"positive", lookup_at_known_or_err},
		 {"unknown", lookup_at_unknown_or_err}}},
    {{'opcode', "lookup_at"}}
};
      
ch_lookup_at_or_goto : statement_descriptor := {
    'lookup_at_or_goto', 'branch', 'ccode', 'modified',
    {'unknown', 'table', 'integer'}, 'eliminate2', 'zero_test',
    {'choice' : {{"negative", {branch}},
		 {"zero", lookup_at_0_or_goto},
		 {"positive", lookup_at_known_or_goto},
		 {"unknown", lookup_at_unknown_or_goto}}},
    {{'opcode', "lookup_at_or_goto"}}
};
      
ch_merge : statement_descriptor := {
    'merge', 'continue', 'ccode', 'modified',
    {'table'}, 'null', 'pure',
    enter_table,
    {{'opcode', "merge"}, {'function', "mergefunc("}}
};
      
ch_merge_at : statement_descriptor := {
    'merge_at', 'continue', 'ccode', 'modified',
    {'table', 'table', 'integer'}, 'eliminate2', 'zero_test',
    enter_table_at_choice,
    {{'opcode', "merge_at"}, {'function', "mergefunc("}}
};
     
ch_move : statement_descriptor := {
    'move', 'ubiquitous', 'ccode', 'assigned',
    {'unknown'}, 'move', 'ubiquitous',
    {'choice' : {{"scalar", new},
		 {"other", discard_unknown}},
     newline,
     destination_object, assign, source1_object, semicolon,
     newline,
     source1_tsdr, assign_bottom},
    {{'opcode', "move"}}
};
      
ch_new_inport : statement_descriptor := {
    'new_inport', 'continue', 'ccode', 'assigned',
    {'inport'}, 'null', 'null',
    {'string' : "if ((ch_val.inport = make_inport()) == nil)",
     depletion,
     discard_other,
     newline,
     destination,
     'string' : " = ch_val; ",
     destination_tsdr,
     'string' : " = & dr_inport;"},
    {{'opcode', "new_inport"}}
};
      
ch_new_program : statement_descriptor := {
    'new_program', 'continue', 'ccode', 'assigned',
    {'program'}, 'null', 'pure',
    {'string' : 
      "if ((ch_val.program = (pd_program *) new_record(PROGRAM_SIZE)) == nil)",
     depletion,
     newline,
     'string' : "ch_val.program->info.program_refcount = 1;",
     newline,
     discard_other,
     newline,
     destination,
     'string' : " = ch_val; ",
     destination_tsdr,
     'string' : " = & dr_program;"},
    {{'opcode', "new_program"}}
};
      
ch_new_record : statement_descriptor := {
    'new_record', 'continue', 'ccode', 'assigned',
    {'record'}, 'null', 'null',
    {'string' : "if ((ch_val.record = new_record(",
     qualifier,
     'string' : ")) == nil)",
     depletion,
     discard_other,
     newline,
     destination,
     'string' : " = ch_val; ",
     destination_tsdr,
     'string' : " = & dr_record;"},
    {{'opcode', "new_record"}}
};
      
ch_new_table : statement_descriptor := {
    'new_table', 'continue', 'ccode', 'assigned',
    {'table'}, 'null', 'null',
    function0_qualify_schedule_raise,
    {{'opcode', "new_table"}, {'function', "che_new_table("}}
};
     
ch_noop : statement_descriptor := {
    'noop', 'continue', 'omit', 'referenced',
    new, 'null', 'null',
    new,
    {{'opcode', "noop"}}
};
      
ch_not : statement_descriptor := {
    'not', 'continue', 'ccode', 'assigned',
    {'boolean'}, 'eliminate1', 'null',
    unary_inline,
    {{'opcode', "not"}, {'operator', "!"},
     {'tag', "boolean"}, {'tsdr', "boolean"}}
};
      
ch_notequal : statement_descriptor := {
    'notequal', 'ubiquitous', 'ccode', 'assigned',
    {'boolean', 'unknown'}, 'eliminate2', 'compare',
    compare,
    {{'opcode', "notequal"}, {'modifier', "!"}, {'operator', " != "}}
};
      
ch_oecvt_int : statement_descriptor := {
    'oecvt_int', 'continue', 'ccode', 'assigned',
    {'integer', 'ordered_enumeration'}, 'convert', 'pure',
    convert_to_integer,
    {{'opcode', "oecvt_int"}, {'tag', "ord_enum"}}
};
      
ch_oecvt_real : statement_descriptor := {
    'oecvt_real', 'continue', 'ccode', 'assigned',
    {'real', 'ordered_enumeration'}, 'convert', 'null',
    {'nest' : {'null', newreal},
     'string' : "*ch_real = ",
     source1_scalar,
     semicolon},
    {{'opcode', "oecvt_real"}, {'tag', "ord_enum"}}
};
      
ch_oege : statement_descriptor := {
    'oege', 'continue', 'ccode', 'assigned',
    {'boolean', 'ordered_enumeration'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "oege"}, {'tag', "ord_enum"}, {'operator', " >= "}}
};
      
ch_oegt : statement_descriptor := {
    'oegt', 'continue', 'ccode', 'assigned',
    {'boolean', 'ordered_enumeration'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "oegt"}, {'tag', "ord_enum"}, {'operator', " > "}}
};
      
ch_oeinitloop : statement_descriptor := {
    'oeinitloop', 'continue', 'ccode', 'assigned',
    {'ordered_enumeration'}, 'null', 'null',
    {destination,
     'string' : ".ord_enum = 0;",
     destination_tsdr,
     'string' : " = & dr_enumeration;"},
    {{'opcode', "oeinitloop"}}
};
      
ch_oele : statement_descriptor := {
    'oele', 'continue', 'ccode', 'assigned',
    {'boolean', 'ordered_enumeration'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "oele"}, {'tag', "ord_enum"}, {'operator', " <= "}}
};
      
ch_oeloop : statement_descriptor := {
    'oeloop', 'branch', 'ccode', 'modified',
    {'ordered_enumeration'}, 'null', 'branch',
    {leftparen,       -- "("
     destination,
     'string' : ".ord_enum)++; if (",
     destination,
     'string' : ".integer < ",
     'variable' : 'int_two',
     rightparen,
     branch},
    {{'opcode', "oeloop"}}
};
      
ch_oelt : statement_descriptor := {
    'oelt', 'continue', 'ccode', 'assigned',
    {'boolean', 'ordered_enumeration'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "oelt"}, {'tag', "ord_enum"}, {'operator', " < "}}
};
      
ch_or : statement_descriptor := {
    'or', 'continue', 'ccode', 'assigned',
    {'boolean'}, 'eliminate2', 'null',
    binary_inline,
    {{'opcode', "or"}, {'operator', "|"},
     {'tag', "boolean"}, {'tsdr', "boolean"}}
};
      
ch_ordenum_lit : statement_descriptor := {
    'ordenum_lit', 'continue', 'ccode', 'assigned',
    {'ordered_enumeration'}, 'literal', 'null',
    literal,
    {{'opcode', "ordenum_lit"},
     {'tag', "ord_enum"}, {'tsdr', "ord_enumeration"}}
};
      
ch_position : statement_descriptor := {
    'position', 'continue', 'ccode', 'assigned',
    {'integer', 'unknown'}, 'null', 'pure',
    {'string' : "ch_frame = get_selector_frame(",
     source1_address,
     'string' : ",sched);",
     newline,
     'string' : "ch_t = ch_frame->inspectee->value.table;",
     newline,
     destination,
     'string' : ".integer = ch_frame->rmvcount +",
     'string' : "(*(ch_t->tbls[ORDER_TBL].des->position_of))",
     'string' : "(ch_t,ORDER_TBL,ch_frame->pos);",
     newline,
     destination_tsdr,
     'string' : " = &dr_integer;"},
    {{'opcode', "position"}}
};
      
ch_print : statement_descriptor := {
    'print', 'continue', 'ccode', 'referenced',
    {'unknown'}, 'null', 'pure',
    {'string' : "re_print(stderr, 0, ",
     destination_address,
     'string' : "); fflush(stderr);"},
    {{'opcode', "print"}}
};
      
ch_privatize : statement_descriptor := {
    'privatize', 'continue', 'ccode', 'referenced',
    {'table'}, 'null', 'pure',
    {'string' : "if (",
     destination,
     'string' : ".table->refcount != 1)",
     'line' : {'true', 2},
     'string' : "if ((ch_returncode = doCopyOnWrite(",
     destination_address,
     'string' : ")) != Normal)",
     raise_exception},
    {{'opcode', "privatize"}}
};
      
ch_procedure : statement_descriptor := {
    'procedure', 'continue', 'ccode', 'assigned',
    {'outport', 'program'}, 'null', 'null',
    function1_qualify_schedule_raise,
    {{'opcode', "procedure"}, {'function', "che_procedure("}}
};
      
ch_prog_lit : statement_descriptor := {
    'prog_lit', 'continue', 'ccode', 'assigned',
    {'program'}, 'null', 'null',
    function0_qualify_schedule_raise,
    {{'opcode', "prog_lit"}, {'function', "che_prog_lit("}}
};
      
ch_radd : statement_descriptor := {
    'radd', 'continue', 'ccode', 'assigned',
    {'real'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "radd"}, {'tag', "real"}, {'function', "chf_radd("}}
};
      
ch_raise : statement_descriptor := {
    'raise', 'emerge', 'ccode', 'referenced',
    new, 'null', 'pure',
    {'string' : "ch_returncode = ",
     qualifier,
     semicolon,
     raise_exception},
    {{'opcode', "raise"}}
};
      
ch_rcvt_int : statement_descriptor := {
    'rcvt_int', 'continue', 'ccode', 'assigned',
    {'integer', 'real'}, 'convert', 'null',
    {'string' : "if (",
     source1_scalar,
     'string' : " >= (MAXINT+1.0) || ",
     source1_scalar,
     'string' : " <= (MININT-1.0))",
     range_error,
     newline,
     'nest' : {'null', convert_to_integer}},
    {{'opcode', "rcvt_int"}, {'tag', "real"}}
};
      
ch_rcvt_enum : statement_descriptor := {
    'rcvt_enum', 'continue', 'ccode', 'assigned',
    {'ordered_enumeration', 'real'}, 'convert', 'pure',
    convert_to_ordered_enumeration,
    {{'opcode', "rcvt_enum"}, {'tag', "real"}}
};

ch_rdivide : statement_descriptor := {
    'rdivide', 'continue', 'ccode', 'assigned',
    {'real'}, 'eliminate2', 'zero_test',
    {divide_by_0_test,
     'nest' : {'null', binary_function}},
    {{'opcode', "rdivide"}, {'tag', "real"}, {'function', "chf_rdivide("}}
};
      
ch_read : statement_descriptor := {
    'read', 'continue', 'ccode', 'assigned',
    {'unknown', 'string'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "read"}, {'function', "che_read("}}
};
      
ch_receive : statement_descriptor := {
    'receive', 'continue', 'block', 'assigned',
    {'unknown', 'inport'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "receive"}, {'function', "che_receive("}}
};

ch_remove : statement_descriptor := {
    'remove', 'continue', 'ccode', 'assigned',
    {'unknown', 'unknown', 'table'}, 'null', 'pure',
    function2_schedule_raise,
    {{'opcode', "remove"}, {'function', "che_remove("}}
};
      
ch_remove_at : statement_descriptor := {
    'remove_at', 'continue', 'ccode', 'assigned',
    {'unknown', 'table', 'integer'}, 'eliminate2', 'pure',
    {'string' : "if ((ch_returncode = remove_at_func(",
     destination_address,
     comma,
     source1_address,
     comma,
     source2_scalar,
     'string' : ")) != Normal)",
     raise_exception},
    {{'opcode', "remove_at"}, {'tag', "integer"}}
};
      
ch_return : statement_descriptor := {
    'return', 'continue', 'ccode', 'referenced',
    {'callmessage'}, 'null', 'null',
    {'nest' : {'null', do_return},
     'string' : "if (ch_caller->type < CProcess) ch_caller->ip++;",
     'string' : "sched->wakeup_proc(sched, ch_caller);}",
     'line' : {'true', -2},
     'string' : "else rem_return(",
     destination,
     'string' : ");",
     'nest' : {'null', bottom_tsdr_destination}},
    {{'opcode', "return"}}
};
      
ch_return_exception : statement_descriptor := {
    'return_exception', 'continue', 'ccode', 'referenced',
    {'callmessage'}, 'null', 'null',
    {'nest' : {'null', do_return},
     'string' : "raise_user(",
     indexed_qualifier,
     'string' : ",ch_caller); ",
     newline,
     'string' : "sched->wakeup_proc(sched,ch_caller);}",
     'line' : {'true', -2},
     'string' : "else rem_return_exception(",
     destination_address,
     comma,
     indexed_qualifier,
     'string' : ");",
     'nest' : {'null', bottom_tsdr_destination}},
    {{'opcode', "return_exception"}}
};
      
ch_reveal : statement_descriptor := {
    'reveal', 'continue', 'ccode', 'referenced',
    {'variant'}, 'null', 'pure',
    {'string' : "if (",
     qualifier,
     'string' : " != ",
     destination,
     'string' : ".variant->info.variant_case)",
     case_error},
    {{'opcode', "reveal"}}
};

ch_rge : statement_descriptor := {
    'rge', 'continue', 'ccode', 'assigned',
    {'boolean', 'real'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "rge"}, {'tag', "real"}, {'operator', " >= "}}
};
      
ch_rgt : statement_descriptor := {
    'rgt', 'continue', 'ccode', 'assigned',
    {'boolean', 'real'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "rgt"}, {'tag', "real"}, {'operator', " > "}}
};
      
ch_rle : statement_descriptor := {
    'rle', 'continue', 'ccode', 'assigned',
    {'boolean', 'real'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "rle"}, {'tag', "real"}, {'operator', " <= "}}
};
      
ch_rlit : statement_descriptor := {
    'rlit', 'continue', 'ccode', 'assigned',
    {'real'}, 'literal', 'null',
    {'nest' : {'null', newreal},
     'string' : "*ch_real = ",
     qualifier,
     semicolon},
    {{'opcode', "rlit"}, {'tag', "real"}, {'tsdr', "real"}}
};
      
ch_rlt : statement_descriptor := {
    'rlt', 'continue', 'ccode', 'assigned',
    {'boolean', 'real'}, 'eliminate2', 'compare',
    relation,
    {{'opcode', "rlt"}, {'tag', "real"}, {'operator', " < "}}
};
      
ch_rmultiply : statement_descriptor := {
    'rmultiply', 'continue', 'ccode', 'assigned',
    {'real'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "rmultiply"}, {'tag', "real"}, {'function', "chf_rmultiply("}}
};
      
ch_rnegate : statement_descriptor := {
    'rnegate', 'continue', 'ccode', 'assigned',
    {'real'}, 'eliminate1', 'null',
    {'nest' : {'null', newreal},
     'string' : "*ch_real = - ",
     source1_scalar,
     semicolon},
    {{'opcode', "rnegate"}, {'tag', "real"}, {'tsdr', "real"}}
};
      
ch_rsubtract : statement_descriptor := {
    'rsubtract', 'continue', 'ccode', 'assigned',
    {'real'}, 'eliminate2', 'pure',
    binary_function,
    {{'opcode', "rsubtract"}, {'tag', "real"}, {'function', "chf_rsubtract("}}
};
      
ch_scan_position : statement_descriptor := {
    'scan_position', 'continue', 'ccode', 'modified',
    {'integer', 'unknown', 'table'}, 'null', 'pure',
    {'string' : "ch_t = ",
     source2,
     'string' : ".table;",
     newline,
     'string' : "(*(ch_t->tbls[ORDER_TBL].des->foreach))",
     'string' : "(ch_t,ORDER_TBL,do_table_position,& ch_ctr,CONT_FOREACH,",
     source1,
     'string' : ");",
     newline,
     destination,
     'string' : ".integer = (dfd_integer) ch_ctr;",
     newline,
     destination_tsdr,
     'string' : " = & dr_integer;"},
    {{'opcode', "scan_position"}}
};
      
ch_select : statement_descriptor := {
    'select', 'branch', 'ccode', 'referenced',
    new, 'select', 'select',
    {'choice' : {{"block", multiple_qualify_schedule},
		 {"proceed", select_branches}}},
    {{'opcode', "select"}, {'modifier', ""}, {'function', "che_select("}}
};
      
ch_send : statement_descriptor := {
    'send', 'continue', 'ccode', 'referenced',
    {'outport', 'unknown'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "send"}, {'function', "che_send("}}
};
      
ch_size : statement_descriptor := {
    'size', 'continue', 'ccode', 'assigned',
    {'integer', 'table'}, 'null', 'pure',
    {destination,
     'string' : ".integer = ",
     source1,
     'string' : ".table->size;",
     newline,
     destination_tsdr,
     assign_integer_tsdr},
    {{'opcode', "size"}}
};
      
ch_trace : statement_descriptor := {
    'trace', 'continue', 'ccode', 'referenced',
    new, 'null', 'pure',
    {'string' : "set_trace_level(",
     qualifier,
     'string' : ");"},
    {{'opcode', "trace"}}
};
      
ch_type_of : statement_descriptor := {
    'type_of', 'continue', 'ccode', 'assigned',
    {'unknown', 'polymorph'}, 'null', 'null',
    dummy,
    {{'opcode', "type_of"}}
};
      
ch_typename : statement_descriptor := {
    'typename', 'continue', 'ccode', 'assigned',
    {'unknown'}, 'null', 'null',
    function0_qualify_schedule_raise,
    {{'opcode', "typename"}, {'function', "che_typename("}}
};
      
ch_typestate_of : statement_descriptor := {
    'typestate_of', 'continue', 'ccode', 'assigned',
    {'unknown', 'polymorph'}, 'null', 'null',
    dummy,
    {{'opcode', "typestate_of"}}
};
      
ch_unique : statement_descriptor := {
    'unique', 'continue', 'ccode', 'assigned',
    {'nominal'}, 'null', 'pure',
    {'string' : "if ((ch_returncode = che_unique(",
     destination_address,
     'string' : ",sched)) != Normal)",
     raise_exception},
    {{'opcode', "unique"}}
};
      
ch_unite : statement_descriptor := {
    'unite', 'continue', 'ccode', 'assigned',
    {'variant', 'unknown'}, 'null', 'pure',
    {'string' : "if ((ch_returncode = che_unite(",
     destination_address,
     comma,
     source1_address,
     'string' : ",sched,",
     qualifier,
     'string' : ")) != Normal)",
     raise_exception},
    {{'opcode', "unite"}}
};
      
ch_unwrap : statement_descriptor := {
    'unwrap', 'continue', 'ccode', 'assigned',
    {'unknown', 'polymorph'}, 'null', 'null',
    function1_qualify_schedule_raise,
    {{'opcode', "unwrap"}, {'function', "che_unwrap("}}
};
      
ch_wrap : statement_descriptor := {
    'wrap', 'continue', 'ccode', 'assigned',
    {'polymorph', 'unknown'}, 'null', 'null',
    function1_qualify_schedule_raise,
    {{'opcode', "wrap"}, {'function', "che_wrap("}}
};
      
ch_write : statement_descriptor := {
    'write', 'continue', 'ccode', 'referenced',
    {'unknown', 'string'}, 'null', 'null',
    function1_schedule_raise,
    {{'opcode', "write"}, {'function', "che_write("}}
};
      
chdescriptors : statement_descriptors := {
    ch_move, ch_copy, ch_discard, ch_equal, 
    ch_notequal, ch_unique, ch_boolean, ch_and, ch_or,
    ch_not, ch_ilit, ch_iadd, ch_isubtract, 
    ch_imultiply, ch_idivide, ch_irem, ch_imod, ch_igt, 
    ch_ilt, ch_ige, ch_ile, ch_inegate, 
    ch_icvt_enum, ch_icvt_real, ch_rlit, ch_radd, ch_rsubtract, 
    ch_rmultiply, ch_rdivide, ch_rgt, ch_rlt, 
    ch_rge, ch_rle, ch_rnegate, ch_rcvt_int, ch_rcvt_enum, 
    ch_enum_lit, ch_ordenum_lit, ch_oegt, ch_oelt, 
    ch_oege, ch_oele, ch_oecvt_int, ch_oecvt_real, ch_oeinitloop, 
    ch_oeloop, ch_new_record, ch_unite, ch_dissolve, 
    ch_reveal, ch_hide, ch_case, ch_ord_case, ch_size, ch_new_table,
    ch_insert, ch_merge, ch_initget, ch_endget, 
    ch_get_or_err, ch_get_or_goto, ch_remove, ch_privatize, ch_insert_at, 
    ch_merge_at, ch_concat, ch_position, ch_scan_position, 
    ch_remove_at, ch_lookup_at, ch_lookup_at_or_goto, ch_find, ch_find_or_goto,
    ch_fremove, ch_initidxfind, ch_idxfind_or_err, ch_idxfind_or_goto, 
    ch_endidxfind, ch_chs_lit, ch_wrap, ch_unwrap, ch_inspect_poly, 
    ch_endinspect_poly, ch_type_of, ch_typestate_of, ch_new_inport, 
    ch_connect, ch_send, ch_receive, ch_empty, ch_call, 
    ch_return, ch_return_exception, ch_create, ch_procedure, 
    ch_endprocess, ch_new_program, ch_currentprogram, ch_prog_lit, 
    ch_checkdefinitions, ch_typename, ch_attributename, ch_assert, 
    ch_drop, ch_block, ch_endblock, ch_exit, ch_select, 
    ch_jumpselect, ch_branch, ch_branch_false, ch_branch_true, 
    ch_raise, ch_noop, ch_print, ch_write, ch_read, 
    ch_trace, ch_escape
};
    
end
