summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/expression.h2
-rw-r--r--src/evaluate.c37
-rw-r--r--src/expression.c2
-rw-r--r--src/parser.y27
-rw-r--r--src/scanner.l3
5 files changed, 59 insertions, 12 deletions
diff --git a/include/expression.h b/include/expression.h
index e9d21cfc..d4222060 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -55,6 +55,7 @@ enum expr_types {
enum ops {
OP_INVALID,
+ OP_IMPLICIT,
/* Unary operations */
OP_HTON,
OP_NTOH,
@@ -172,6 +173,7 @@ struct expr {
struct {
/* EXPR_SYMBOL */
const struct datatype *sym_type;
+ const struct scope *scope;
const char *identifier;
};
struct {
diff --git a/src/evaluate.c b/src/evaluate.c
index 0deff9ad..706ec2e5 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -102,13 +102,25 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
{
struct error_record *erec;
+ struct symbol *sym;
struct expr *new;
(*expr)->sym_type = ctx->ectx.dtype;
- erec = symbol_parse(*expr, &new);
- if (erec != NULL) {
- erec_queue(erec, ctx->msgs);
- return -1;
+
+ if ((*expr)->scope != NULL) {
+ sym = symbol_lookup((*expr)->scope, (*expr)->identifier);
+ if (sym == NULL)
+ return expr_error(ctx, *expr,
+ "undefined identifier '%s'",
+ (*expr)->identifier);
+ // FIXME: need to copy (on write)
+ new = expr_get(sym->expr);
+ } else {
+ erec = symbol_parse(*expr, &new);
+ if (erec != NULL) {
+ erec_queue(erec, ctx->msgs);
+ return -1;
+ }
}
expr_free(*expr);
@@ -702,6 +714,23 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
"constant value",
expr_op_symbols[rel->op]);
+ if (rel->op == OP_IMPLICIT) {
+ switch (right->ops->type) {
+ case EXPR_RANGE:
+ rel->op = OP_RANGE;
+ break;
+ case EXPR_SET:
+ rel->op = OP_LOOKUP;
+ break;
+ case EXPR_LIST:
+ rel->op = OP_FLAGCMP;
+ break;
+ default:
+ rel->op = OP_EQ;
+ break;
+ }
+ }
+
switch (rel->op) {
case OP_LOOKUP:
/* Data for range lookups needs to be in big endian order */
diff --git a/src/expression.c b/src/expression.c
index 66a8793f..4b3e1e04 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -162,7 +162,7 @@ struct expr *verdict_expr_alloc(const struct location *loc,
static void symbol_expr_print(const struct expr *expr)
{
- printf("%s", expr->identifier);
+ printf("%s%s", expr->scope != NULL ? "$" : "", expr->identifier);
}
static void symbol_expr_destroy(struct expr *expr)
diff --git a/src/parser.y b/src/parser.y
index 1ca5981b..d9da115a 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -151,6 +151,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token SET "set"
%token INCLUDE "include"
+%token DEFINE "define"
%token HOOK "hook"
%token <val> HOOKNUM "hooknum"
@@ -379,8 +380,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%type <expr> set_expr set_list_expr set_list_member_expr
%destructor { expr_free($$); } set_expr set_list_expr set_list_member_expr
-%type <expr> expr
-%destructor { expr_free($$); } expr
+%type <expr> expr initializer_expr
+%destructor { expr_free($$); } expr initializer_expr
%type <expr> match_expr
%destructor { expr_free($$); } match_expr
@@ -461,6 +462,11 @@ common_block : INCLUDE QUOTED_STRING stmt_seperator
}
xfree($2);
}
+ | DEFINE identifier '=' initializer_expr stmt_seperator
+ {
+ symbol_bind(current_scope(state), $2, $4);
+ xfree($2);
+ }
;
line : common_block { $$ = NULL; }
@@ -809,6 +815,12 @@ symbol_expr : string
$$ = symbol_expr_alloc(&@$, $1);
xfree($1);
}
+ | '$' identifier
+ {
+ $$ = symbol_expr_alloc(&@$, $2);
+ $$->scope = current_scope(state);
+ xfree($2);
+ }
;
integer_expr : NUM
@@ -985,17 +997,18 @@ expr : concat_expr
| multiton_expr
;
+initializer_expr : expr
+ | set_expr
+ | list_expr
+ ;
+
match_expr : relational_expr
| membership_expr
;
relational_expr : expr /* implicit */ expr
{
- enum ops op;
-
- /* RHS determines operation */
- op = ($2->ops->type == EXPR_RANGE) ? OP_RANGE : OP_EQ;
- $$ = relational_expr_alloc(&@$, op, $1, $2);
+ $$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
}
| expr /* implicit */ list_expr
{
diff --git a/src/scanner.l b/src/scanner.l
index 3b22bb9e..7fc01f77 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -207,6 +207,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"-" { return DASH; }
"*" { return ASTERISK; }
"@" { return AT; }
+"$" { return '$'; }
+"=" { return '='; }
"=>" { return ARROW; }
"map" { return MAP; }
"vmap" { return VMAP; }
@@ -219,6 +221,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"NF_INET_POST_ROUTING" { yylval->val = NF_INET_POST_ROUTING; return HOOKNUM; }
"include" { return INCLUDE; }
+"define" { return DEFINE; }
"describe" { return DESCRIBE; }