and name is used). In both cases, it must have the same type as elements.
<p>The <cf>case</cf> is similar to case from Pascal. Syntax is <cf>case
- <m/expr/ { else: | <m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [
- ... ] }</cf>. The expression after <cf>case</cf> can be of any type which can be
- on the left side of the ˜ operator and anything that could be a member of
- a set is allowed before <cf/:/. Multiple commands must be grouped by <cf/{}/.
- If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements
- between it and next <cf/:/ statement are executed. If <cf><m/expr/</cf> matches
- neither of the <cf/:/ clauses, the statements after <cf/else:/ are executed.
+ <m/expr/ { else: | <m/set_body_expr/ /: <m/statement/ ; [... ] }</cf>.
+
+ The expression after <cf>case</cf> can be of any type that could be a member of
+ a set, while the <m/set_body_expr/ before <cf/:/ can be anything (constants,
+ intervals, expressions) that could be a part of a set literal. One exception is
+ prefix type, which can be used in sets bud not in <cf/case/ structure. Multiple
-commands are allowed without <cf/{}/ grouping. If <cf><m/expr/</cf> matches one
-of the <cf/:/ clauses, statements between it and next <cf/:/ statement are
++commands must be grouped by <cf/{}/. If <cf><m/expr/</cf> matches one
++of the <cf/:/ clauses, the statement or block after it is
+ executed. If <cf><m/expr/</cf> matches neither of the <cf/:/ clauses, the
-statements after <cf/else:/ are executed.
++statement or block after <cf/else:/ is executed.
<p>Here is example that uses <cf/if/ and <cf/case/ structures:
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
| '(' term ')' {
- $$ = cf_eval($2, T_VOID);
+ $$ = cf_eval_tmp($2, T_VOID);
- if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
+ if (!f_valid_set_type($$.type))
+ cf_error("Set-incompatible type (%s)", f_type_name($$.type));
}
- | symbol_known {
+ ;
+
+ set_atom:
+ set_atom0
+ | CF_SYM_KNOWN {
cf_assert_symbol($1, SYM_CONSTANT);
- if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
+ if (!f_valid_set_type(SYM_TYPE($1)))
+ cf_error("%s: Set-incompatible type (%s)", $1->name, f_type_name(SYM_TYPE($1)));
$$ = *$1->val;
}
;
;
switch_body: /* EMPTY */ { $$ = NULL; }
- | switch_body switch_items ':' cmd {
- | switch_body switch_items ':' cmds_scoped {
++ | switch_body switch_items ':' cmd {
/* Fill data fields */
struct f_tree *t;
for (t = $2; t; t = t->left)