extern void symbol_bind(struct scope *scope, const char *identifier,
struct expr *expr);
+extern int symbol_unbind(struct scope *scope, const char *identifier);
extern struct symbol *symbol_lookup(const struct scope *scope,
const char *identifier);
%token INCLUDE "include"
%token DEFINE "define"
+%token REDEFINE "redefine"
+%token UNDEFINE "undefine"
%token FIB "fib"
symbol_bind(scope, $2, $4);
xfree($2);
}
+ | REDEFINE identifier '=' initializer_expr stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ /* ignore missing identifier */
+ symbol_unbind(scope, $2);
+ symbol_bind(scope, $2, $4);
+ xfree($2);
+ }
+ | UNDEFINE identifier stmt_separator
+ {
+ struct scope *scope = current_scope(state);
+
+ if (symbol_unbind(scope, $2) < 0) {
+ erec_queue(error(&@2, "undefined symbol '%s'", $2),
+ state->msgs);
+ YYERROR;
+ }
+ xfree($2);
+ }
| error stmt_separator
{
if (++state->nerrs == nft->parser_max_errors)
list_add_tail(&sym->list, &scope->symbols);
}
+int symbol_unbind(struct scope *scope, const char *identifier)
+{
+ struct symbol *sym;
+
+ sym = symbol_lookup(scope, identifier);
+ if (!sym)
+ return -1;
+
+ list_del(&sym->list);
+ xfree(sym->identifier);
+ expr_free(sym->expr);
+ xfree(sym);
+ return 0;
+}
+
struct symbol *symbol_lookup(const struct scope *scope, const char *identifier)
{
struct symbol *sym;
"include" { return INCLUDE; }
"define" { return DEFINE; }
+"redefine" { return REDEFINE; }
+"undefine" { return UNDEFINE; }
"describe" { return DESCRIBE; }