summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Machek <pavel@ucw.cz>1999-10-28 23:03:36 +0200
committerPavel Machek <pavel@ucw.cz>1999-10-28 23:03:36 +0200
commit41be4444f2f548c5cc135593b2c820180a22ff99 (patch)
treedb23c6c220b8a0304e6e29b07be67ff628099e23
parentc2250f91c749f563229ad624bbd03053c1d671d0 (diff)
downloadbird-41be4444f2f548c5cc135593b2c820180a22ff99.tar
bird-41be4444f2f548c5cc135593b2c820180a22ff99.zip
switch() { } done right.
-rw-r--r--Makefile4
-rw-r--r--bird.conf7
-rw-r--r--conf/confbase.Y2
-rw-r--r--filter/config.Y40
-rw-r--r--filter/filter.c60
-rw-r--r--filter/tree.c2
6 files changed, 50 insertions, 65 deletions
diff --git a/Makefile b/Makefile
index a2bba64..2221101 100644
--- a/Makefile
+++ b/Makefile
@@ -4,12 +4,12 @@
objdir=obj
-all depend:
+all depend tags:
$(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
rm -rf $(objdir)
diff --git a/bird.conf b/bird.conf
index b1220c3..3b8f6a7 100644
--- a/bird.conf
+++ b/bird.conf
@@ -14,7 +14,7 @@ function callme (int arg1; int arg2;)
case arg1 {
2: print "dva"; print "jeste jednou dva";
- [ 3 .. 5 ]: print "tri az pet";
+ 3 .. 5: print "tri az pet";
else: print "neco jineho";
}
}
@@ -40,8 +40,11 @@ prefix px;
print "Testing prefixes: 1.2.3.4/18 = " px;
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...";
- callme ( 1, 2 );
+# callme ( 1, 2 );
+ callme ( 2, 2 );
callme ( 2, 2 );
callme ( 3, 2 );
callme ( 4, 2 );
diff --git a/conf/confbase.Y b/conf/confbase.Y
index a6eb876..b266d25 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -43,7 +43,7 @@ CF_DECLS
%type <i> expr bool pxlen datetime
-%nonassoc '=' '<' '>' '~' ELSE IF '.'
+%nonassoc '=' '<' '>' '~' IF ELSE '.'
%left '+' '-'
%left '*' '/' '%'
%left '!'
diff --git a/filter/config.Y b/filter/config.Y
index 9385483..d5a9dca 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -11,7 +11,6 @@
FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
FIXME: create community lists
FIXME: access to dynamic attributes
- FIXME: make case faster
*/
CF_HDR
@@ -37,10 +36,10 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
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 <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 <s> decls function_params
@@ -191,6 +190,20 @@ set_items:
| 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:
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:
ifthen {
$$ = $1;
@@ -346,9 +342,9 @@ cmd:
}
| CASE term '{' switch_body '}' {
$$ = f_new_inst();
- $$->code = 'sw';
+ $$->code = 'SW';
$$->a1.p = $2;
- $$->a2.p = $4;
+ $$->a2.p = build_tree( $4 );
}
;
diff --git a/filter/filter.c b/filter/filter.c
index f6b2d4b..dc8235e 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -54,6 +54,13 @@ struct f_inst *startup_func = NULL;
int
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)
return CMP_ERROR;
switch (v1.type) {
@@ -64,7 +71,7 @@ val_compare(struct f_val v1, struct f_val v2)
return 1;
case T_IP:
return ipa_compare(v1.val.ip, v2.val.ip);
- default: return CMP_ERROR;
+ default: { printf( "Error comparing\n" ); return CMP_ERROR; }
}
}
@@ -115,40 +122,6 @@ static struct rte **f_rte;
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
interpret(struct f_inst *what)
{
struct symbol *sym;
@@ -309,9 +282,22 @@ interpret(struct f_inst *what)
ONEARG;
res = interpret(what->a2.p);
break;
- case 'sw': /* SWITCH alias CASE */
+ case 'SW':
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;
case 'iM': /* IP.MASK(val) */
TWOARGS_C;
diff --git a/filter/tree.c b/filter/tree.c
index ea1f18f..43888f0 100644
--- a/filter/tree.c
+++ b/filter/tree.c
@@ -73,7 +73,7 @@ struct f_tree *
find_tree(struct f_tree *t, struct f_val val)
{
if (!t)
- return 0;
+ return NULL;
if ((val_compare(t->from, val) != 1) &&
(val_compare(t->to, val) != -1))
return t;