📄 parse.c
字号:
low_bound = expr; high_bound = NULL_TREE; } build_loop_iterator (loop_counter, low_bound, NULL_TREE, high_bound, going_down, 1, 0); } }}/* Matches: '(' <event list> ')' ':'. Or; returns NULL_EXPR. */static treeparse_delay_case_event_list (){ tree event_list = NULL_TREE; tree event; if (! check_token (LPRN)) return NULL_TREE; event = parse_expression (); if (PEEK_TOKEN () == ')' && PEEK_TOKEN1 () != ':') { /* Oops. */ require (RPRN); pushback_paren_expr (event); return NULL_TREE; } for (;;) { if (! ignoring) event_list = tree_cons (NULL_TREE, event, event_list); if (! check_token (COMMA)) break; event = parse_expression (); } expect (RPRN, "missing ')'"); expect (COLON, "missing ':'"); return ignoring ? error_mark_node : event_list;}static voidparse_delay_case_action (label) tree label;{ tree label_cnt = NULL_TREE, set_location, priority; tree combined_event_list = NULL_TREE; require (DELAY); require (CASE); PUSH_ACTION; pushlevel (1); expand_exit_needed = 0; if (check_token (SET)) { set_location = parse_expression (); parse_semi_colon (); } else set_location = NULL_TREE; if (check_token (PRIORITY)) { priority = parse_expression (); parse_semi_colon (); } else priority = NULL_TREE; if (! ignoring) label_cnt = build_delay_case_start (set_location, priority); for (;;) { tree event_list = parse_delay_case_event_list (); if (event_list) { if (! ignoring ) { int if_or_elseif = combined_event_list == NULL_TREE; build_delay_case_label (event_list, if_or_elseif); combined_event_list = chainon (combined_event_list, event_list); } } else if (parse_action ()) { if (! ignoring) { expand_exit_needed = 1; if (combined_event_list == NULL_TREE) error ("missing DELAY CASE alternative"); } } else break; } expect (ESAC, "missing 'ESAC' in DELAY CASE'"); if (! ignoring) build_delay_case_end (combined_event_list); possibly_define_exit_label (label); poplevel (0, 0, 0); }static voidparse_do_action (label) tree label;{ tree condition; int token; require (DO); if (check_token (WITH)) { tree list = NULL_TREE; for (;;) { tree name = parse_primval (); if (! ignoring && TREE_CODE (name) != ERROR_MARK) { if (TREE_CODE (TREE_TYPE (name)) == REFERENCE_TYPE) name = convert (TREE_TYPE (TREE_TYPE (name)), name); else { int is_loc = chill_location (name); if (is_loc == 1) /* This is probably not possible */ warning ("non-referable location in DO WITH"); if (is_loc > 1) name = build_chill_arrow_expr (name, 1); name = decl_temp1 (get_identifier ("__with_element"), TREE_TYPE (name), 0, name, 0, 0); if (is_loc > 1) name = build_chill_indirect_ref (name, NULL_TREE, 0); } if (TREE_CODE (TREE_TYPE (name)) != RECORD_TYPE) error ("WITH element must be of STRUCT mode"); else list = tree_cons (NULL_TREE, name, list); } if (! check_token (COMMA)) break; } pushlevel (1); push_action (); for (list = nreverse (list); list != NULL_TREE; list = TREE_CHAIN (list)) shadow_record_fields (TREE_VALUE (list)); parse_semi_colon (); parse_opt_actions (); expect (OD, "missing 'OD' in 'DO WITH'"); if (! ignoring) emit_line_note (input_filename, lineno); possibly_define_exit_label (label); parse_opt_handler (); parse_opt_end_label_semi_colon (label); poplevel (0, 0, 0); return; } token = PEEK_TOKEN(); if (token != FOR && token != WHILE) { push_handler (); parse_opt_actions (); expect (OD, "Missing 'OD' after 'DO'"); parse_opt_handler (); parse_opt_end_label_semi_colon (label); return; } if (! ignoring) emit_line_note (input_filename, lineno); push_loop_block (); if (check_token (FOR)) { if (check_token (EVER)) { if (!ignoring) build_loop_iterator (NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, 0, 0, 1); } else { parse_iteration (); while (check_token (COMMA)) parse_iteration (); } } else if (!ignoring) build_loop_iterator (NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, 0, 0, 1); begin_loop_scope (); if (! ignoring) build_loop_start (label); condition = check_token (WHILE) ? parse_expression () : NULL_TREE; if (! ignoring) top_loop_end_check (condition); parse_semi_colon (); parse_opt_actions (); if (! ignoring) build_loop_end (); expect (OD, "Missing 'OD' after 'DO'"); /* Note that the handler is inside the reach of the DO. */ parse_opt_handler (); end_loop_scope (label); pop_loop_block (); parse_opt_end_label_semi_colon (label);}/* Matches: '(' <signal name> [ 'IN' <defining occurrence list> ']' ')' ':' or: '(' <buffer location> IN (defining occurrence> ')' ':' or: returns NULL_TREE. */static treeparse_receive_spec (){ tree val; tree name_list = NULL_TREE; if (!check_token (LPRN)) return NULL_TREE; val = parse_primval (); if (check_token (IN)) {#if 0 if (flag_local_loop_counter) name_list = parse_defining_occurrence_list (); else#endif { for (;;) { tree loc = parse_primval (); if (! ignoring) name_list = tree_cons (NULL_TREE, loc, name_list); if (! check_token (COMMA)) break; } } } if (! check_token (RPRN)) { error ("missing ')' in signal/buffer receive alternative"); return NULL_TREE; } if (check_token (COLON)) { if (ignoring || val == NULL_TREE || TREE_CODE (val) == ERROR_MARK) return error_mark_node; else return build_receive_case_label (val, name_list); } /* We saw: '(' <primitive value> ')' not followed by ':'. Presumably the start of an action. Backup and fail. */ if (name_list != NULL_TREE) error ("misplaced 'IN' in signal/buffer receive alternative"); pushback_paren_expr (val); return NULL_TREE;}/* To understand the code generation for this, see ch-tasking.c, and the 2-page comments preceding the build_chill_receive_case_start () definition. */static voidparse_receive_case_action (label) tree label;{ tree instance_location; tree have_else_actions; int spec_seen = 0; tree alt_list = NULL_TREE; require (RECEIVE); require (CASE); push_action (); pushlevel (1); if (! ignoring) { expand_exit_needed = 0; } if (check_token (SET)) { instance_location = parse_expression (); parse_semi_colon (); } else instance_location = NULL_TREE; if (! ignoring) instance_location = build_receive_case_start (instance_location); for (;;) { tree receive_spec = parse_receive_spec (); if (receive_spec) { if (! ignoring) alt_list = tree_cons (NULL_TREE, receive_spec, alt_list); spec_seen++; } else if (parse_action ()) { if (! spec_seen && pass == 1) error ("missing RECEIVE alternative"); if (! ignoring) expand_exit_needed = 1; spec_seen = 1; } else break; } if (check_token (ELSE)) { if (! ignoring) { emit_line_note (input_filename, lineno); if (build_receive_case_if_generated ()) expand_start_else (); } parse_opt_actions (); have_else_actions = integer_one_node; } else have_else_actions = integer_zero_node; expect (ESAC, "missing 'ESAC' matching 'RECEIVE CASE'"); if (! ignoring) { build_receive_case_end (nreverse (alt_list), have_else_actions); } possibly_define_exit_label (label); poplevel (0, 0, 0); }static voidparse_send_action (){ tree signal = NULL_TREE; tree buffer = NULL_TREE; tree value_list; tree with_expr, to_expr, priority; require (SEND); /* The tricky part is distinguishing between a SEND buffer action, and a SEND signal action. */ if (pass != 2 || PEEK_TOKEN () != NAME) { /* If this is pass 2, it's a SEND buffer action. If it's pass 1, we don't care. */ buffer = parse_primval (); } else { /* We have to specifically check for signalname followed by a '(', since we allow a signalname to be used (syntactically) as a "function". */ tree name = parse_name (); if (TREE_CODE (name) == TYPE_DECL && CH_DECL_SIGNAL (name)) signal = name; /* It's a SEND signal action! */ else { /* It's not a legal SEND signal action. Back up and try as a SEND buffer action. */ pushback_token (EXPR, name); buffer = parse_primval (); } } if (check_token (LPRN)) { value_list = NULL_TREE; for (;;) { tree expr = parse_untyped_expr (); if (! ignoring) value_list = tree_cons (NULL_TREE, expr, value_list); if (! check_token (COMMA)) break; } value_list = nreverse (value_list); expect (RPRN, "missing ')'"); } else value_list = NULL_TREE; if (check_token (WITH)) with_expr = parse_expression (); else with_expr = NULL_TREE; if (check_token (TO)) to_expr = parse_expression (); else to_expr = NULL_TREE; if (check_token (PRIORITY)) priority = parse_expression (); else priority = NULL_TREE; PUSH_ACTION; if (ignoring) return; if (signal) { /* It's a <send signal action>! */ tree sigdesc = build_signal_descriptor (signal, value_list); if (sigdesc != NULL_TREE && TREE_CODE (sigdesc) != ERROR_MARK) { tree sendto = to_expr ? to_expr : IDENTIFIER_SIGNAL_DEST (signal); expand_send_signal (sigdesc, with_expr, sendto, priority, DECL_NAME (signal)); } } else { /* all checks are done in expand_send_buffer */ expand_send_buffer (buffer, value_list, priority, with_expr, to_expr); }}static voidparse_start_action (){ tree name, copy_number, param_list, startset; require (START); name = parse_name_string (); expect (LPRN, "missing '(' in START action"); PUSH_ACTION; /* copy number is a required parameter */ copy_number = parse_expression (); if (!ignoring && (copy_number == NULL_TREE || TREE_CODE (copy_number) == ERROR_MARK || TREE_CODE (TREE_TYPE (copy_number)) != INTEGER_TYPE)) { error ("PROCESS copy number must be integer"); copy_number = integer_zero_node; } if (check_token (COMMA)) param_list = parse_expr_list (); /* user parameters */ else param_list = NULL_TREE; expect (RPRN, "missing ')'"); startset = check_token (SET) ? parse_primval () : NULL; build_start_process (name, copy_number, param_list, startset);}static voidparse_opt_actions (){ while (parse_action ()) ;}static intparse_action (){ tree label = NULL_TREE; tree expr, rhs, loclist; enum tree_code op; if (current_function_decl == global_function_decl && PEEK_TOKEN () != SC && PEEK_TOKEN () != END) seen_action = 1, build_constructor = 1; if (PEEK_TOKEN () == NAME && PEEK_TOKEN1 () == COLON) { label = parse_defining_occurrence (); require (COLON); INIT_ACTION; define_label (input_filename, lineno, label); } switch (PEEK_TOKEN ()) { case AFTER: { int delay; require (AFTER); expr = parse_primval (); delay = check_token (DELAY); expect (IN, "missing 'IN'"); push_action (); pushlevel (1); build_after_start (expr, delay); parse_opt_actions (); expect (TIMEOUT, "missing 'TIMEOUT'"); build_after_timeout_start (); parse_opt_actions (); expect (END, "missing 'END'"); build_after_end (); possibly_define_exit_label (label); poplevel (0, 0, 0); } goto bracketed_action; case ASM_KEYWORD: parse_asm_action (); goto no_handler_action; case ASSERT: require (ASSERT); PUSH_ACTION; expr = parse_expression (); if (! ignoring) { tree assertfail = ridpointers[(int) RID_ASSERTFAIL]; expr = build (TRUTH_ORIF_EXPR, void_type_node, expr, build_cause_exception (assertfail, 0)); expand_expr_stmt (fold (expr)); } goto handler_action; case AT: require (AT); PUSH_ACTION; expr = parse_primval (); expect (IN, "missing 'IN'"); pushlevel (1); if (! ignoring) build_at_action (expr); parse_opt_actions (); expect (TIMEOUT, "missing 'TIMEOUT'"); if (! ignoring) expand_start_else (); parse_opt_actions (); expect (END, "missing 'END'"); if (! ignoring) expand_end_cond (); possibly_define_exit_label (label); poplevel (0, 0, 0); goto bracketed_action; case BEGINTOKEN: parse_begin_end_block (label); return 1; case CASE: parse_case_action (label); goto bracketed_action;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -