mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
switch() { } done right.
This commit is contained in:
parent
c2250f91c7
commit
41be4444f2
4
Makefile
4
Makefile
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
objdir=obj
|
objdir=obj
|
||||||
|
|
||||||
all depend:
|
all depend tags:
|
||||||
$(MAKE) -C $(objdir) $@
|
$(MAKE) -C $(objdir) $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C $(objdir) clean
|
$(MAKE) -C $(objdir) clean
|
||||||
find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core -or -name depend -or -name .#* | xargs rm -f
|
find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core -or -name depend -or -name ".#*" | xargs rm -f
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf $(objdir)
|
rm -rf $(objdir)
|
||||||
|
@ -14,7 +14,7 @@ function callme (int arg1; int arg2;)
|
|||||||
|
|
||||||
case arg1 {
|
case arg1 {
|
||||||
2: print "dva"; print "jeste jednou dva";
|
2: print "dva"; print "jeste jednou dva";
|
||||||
[ 3 .. 5 ]: print "tri az pet";
|
3 .. 5: print "tri az pet";
|
||||||
else: print "neco jineho";
|
else: print "neco jineho";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,8 +40,11 @@ prefix px;
|
|||||||
print "Testing prefixes: 1.2.3.4/18 = " px;
|
print "Testing prefixes: 1.2.3.4/18 = " px;
|
||||||
print "Testing pairs: (1,2) = " (1,2);
|
print "Testing pairs: (1,2) = " (1,2);
|
||||||
|
|
||||||
|
print "What will this do? " [ 1, 2, 1, 1, 1, 3, 4, 1, 1, 1, 5 ];
|
||||||
|
|
||||||
print "Testing functions...";
|
print "Testing functions...";
|
||||||
callme ( 1, 2 );
|
# callme ( 1, 2 );
|
||||||
|
callme ( 2, 2 );
|
||||||
callme ( 2, 2 );
|
callme ( 2, 2 );
|
||||||
callme ( 3, 2 );
|
callme ( 3, 2 );
|
||||||
callme ( 4, 2 );
|
callme ( 4, 2 );
|
||||||
|
@ -43,7 +43,7 @@ CF_DECLS
|
|||||||
|
|
||||||
%type <i> expr bool pxlen datetime
|
%type <i> expr bool pxlen datetime
|
||||||
|
|
||||||
%nonassoc '=' '<' '>' '~' ELSE IF '.'
|
%nonassoc '=' '<' '>' '~' IF ELSE '.'
|
||||||
%left '+' '-'
|
%left '+' '-'
|
||||||
%left '*' '/' '%'
|
%left '*' '/' '%'
|
||||||
%left '!'
|
%left '!'
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
|
FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
|
||||||
FIXME: create community lists
|
FIXME: create community lists
|
||||||
FIXME: access to dynamic attributes
|
FIXME: access to dynamic attributes
|
||||||
FIXME: make case faster
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CF_HDR
|
CF_HDR
|
||||||
@ -37,10 +36,10 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
|
|||||||
FILTER
|
FILTER
|
||||||
)
|
)
|
||||||
|
|
||||||
%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list switch_body
|
%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list
|
||||||
%type <f> filter filter_body
|
%type <f> filter filter_body
|
||||||
%type <i> type break_command pair
|
%type <i> type break_command pair
|
||||||
%type <e> set_item set_items
|
%type <e> set_item set_items switch_body
|
||||||
%type <v> set_atom prefix prefix_s ipa
|
%type <v> set_atom prefix prefix_s ipa
|
||||||
%type <s> decls function_params
|
%type <s> decls function_params
|
||||||
|
|
||||||
@ -191,6 +190,20 @@ set_items:
|
|||||||
| set_items ',' set_item { $$ = $3; $$->left = $1; }
|
| set_items ',' set_item { $$ = $3; $$->left = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* 2 shift/reduce conflicts here. Curable by replacing cmds with block which breaks syntax */
|
||||||
|
switch_body: /* EMPTY */ { $$ = NULL; }
|
||||||
|
| set_item ':' cmds switch_body {
|
||||||
|
$$ = $1;
|
||||||
|
$$->data = $3;
|
||||||
|
$$->left = $4;
|
||||||
|
}
|
||||||
|
| ELSE ':' cmds {
|
||||||
|
$$ = f_new_tree();
|
||||||
|
$$->from.type = T_VOID;
|
||||||
|
$$->to.type = T_VOID;
|
||||||
|
$$->data = $3;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
constant:
|
constant:
|
||||||
CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $3; }
|
CONST '(' expr ')' { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_INT; $$->a2.i = $3; }
|
||||||
@ -286,23 +299,6 @@ var_list: term {
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* 2 shift/reduce conflicts here. Curable by replacing cmds with block which breaks syntax */
|
|
||||||
switch_body: /* EMPTY */ { $$ = NULL; }
|
|
||||||
| term ':' cmds switch_body {
|
|
||||||
$$ = f_new_inst();
|
|
||||||
$$->code = 'of';
|
|
||||||
$$->a1.p = $1;
|
|
||||||
$$->a2.p = $3;
|
|
||||||
$$->next = $4;
|
|
||||||
}
|
|
||||||
| ELSE ':' cmds {
|
|
||||||
$$ = f_new_inst();
|
|
||||||
$$->code = 'el';
|
|
||||||
$$->a1.p = NULL;
|
|
||||||
$$->a2.p = $3;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
cmd:
|
cmd:
|
||||||
ifthen {
|
ifthen {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -346,9 +342,9 @@ cmd:
|
|||||||
}
|
}
|
||||||
| CASE term '{' switch_body '}' {
|
| CASE term '{' switch_body '}' {
|
||||||
$$ = f_new_inst();
|
$$ = f_new_inst();
|
||||||
$$->code = 'sw';
|
$$->code = 'SW';
|
||||||
$$->a1.p = $2;
|
$$->a1.p = $2;
|
||||||
$$->a2.p = $4;
|
$$->a2.p = build_tree( $4 );
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -54,6 +54,13 @@ struct f_inst *startup_func = NULL;
|
|||||||
int
|
int
|
||||||
val_compare(struct f_val v1, struct f_val v2)
|
val_compare(struct f_val v1, struct f_val v2)
|
||||||
{
|
{
|
||||||
|
if ((v1.type == T_VOID) && (v2.type == T_VOID))
|
||||||
|
return 0;
|
||||||
|
if (v1.type == T_VOID) /* Hack for else */
|
||||||
|
return -1;
|
||||||
|
if (v2.type == T_VOID)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (v1.type != v2.type)
|
if (v1.type != v2.type)
|
||||||
return CMP_ERROR;
|
return CMP_ERROR;
|
||||||
switch (v1.type) {
|
switch (v1.type) {
|
||||||
@ -64,7 +71,7 @@ val_compare(struct f_val v1, struct f_val v2)
|
|||||||
return 1;
|
return 1;
|
||||||
case T_IP:
|
case T_IP:
|
||||||
return ipa_compare(v1.val.ip, v2.val.ip);
|
return ipa_compare(v1.val.ip, v2.val.ip);
|
||||||
default: return CMP_ERROR;
|
default: { printf( "Error comparing\n" ); return CMP_ERROR; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,40 +121,6 @@ static struct rte **f_rte;
|
|||||||
|
|
||||||
static struct f_val interpret(struct f_inst *what);
|
static struct f_val interpret(struct f_inst *what);
|
||||||
|
|
||||||
static struct f_val
|
|
||||||
interpret_switch(struct f_inst *what, struct f_val control)
|
|
||||||
{
|
|
||||||
struct f_val this, res;
|
|
||||||
int i;
|
|
||||||
res.type = T_VOID;
|
|
||||||
|
|
||||||
if (!what)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
switch(what->code) {
|
|
||||||
case 'el':
|
|
||||||
return interpret(what->a2.p);
|
|
||||||
|
|
||||||
case 'of':
|
|
||||||
this = interpret(what->a1.p);
|
|
||||||
i = val_compare(control, this);
|
|
||||||
if (!i)
|
|
||||||
return interpret(what->a2.p);
|
|
||||||
if (i==CMP_ERROR) {
|
|
||||||
i = val_in_range(control, this);
|
|
||||||
if (i==1)
|
|
||||||
return interpret(what->a2.p);
|
|
||||||
if (i==CMP_ERROR)
|
|
||||||
runtime( "incompatible types in case" );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
bug( "This can not happen (%x)\n", what->code );
|
|
||||||
}
|
|
||||||
return interpret_switch(what->next, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct f_val
|
static struct f_val
|
||||||
interpret(struct f_inst *what)
|
interpret(struct f_inst *what)
|
||||||
{
|
{
|
||||||
@ -309,9 +282,22 @@ interpret(struct f_inst *what)
|
|||||||
ONEARG;
|
ONEARG;
|
||||||
res = interpret(what->a2.p);
|
res = interpret(what->a2.p);
|
||||||
break;
|
break;
|
||||||
case 'sw': /* SWITCH alias CASE */
|
case 'SW':
|
||||||
ONEARG;
|
ONEARG;
|
||||||
interpret_switch(what->a2.p, v1);
|
{
|
||||||
|
struct f_tree *t = find_tree(what->a2.p, v1);
|
||||||
|
if (!t) {
|
||||||
|
v1.type = T_VOID;
|
||||||
|
t = find_tree(what->a2.p, v1);
|
||||||
|
if (!t) {
|
||||||
|
printf( "No else statement?\n ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!t->data)
|
||||||
|
die( "Impossible: no code associated!\n" );
|
||||||
|
return interpret(t->data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'iM': /* IP.MASK(val) */
|
case 'iM': /* IP.MASK(val) */
|
||||||
TWOARGS_C;
|
TWOARGS_C;
|
||||||
|
@ -73,7 +73,7 @@ struct f_tree *
|
|||||||
find_tree(struct f_tree *t, struct f_val val)
|
find_tree(struct f_tree *t, struct f_val val)
|
||||||
{
|
{
|
||||||
if (!t)
|
if (!t)
|
||||||
return 0;
|
return NULL;
|
||||||
if ((val_compare(t->from, val) != 1) &&
|
if ((val_compare(t->from, val) != 1) &&
|
||||||
(val_compare(t->to, val) != -1))
|
(val_compare(t->to, val) != -1))
|
||||||
return t;
|
return t;
|
||||||
|
Loading…
Reference in New Issue
Block a user