mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 15:53:44 +02:00
b2/: first tentative version of hierarchy parser, with example
This commit is contained in:
parent
7fe553a4fc
commit
6bb8b03ef8
7
b2/HIERARCHY
Normal file
7
b2/HIERARCHY
Normal file
@ -0,0 +1,7 @@
|
||||
<comp> = R<C<L;
|
||||
|
||||
T:<comp> {
|
||||
R: { R:#R TOL:%R };
|
||||
C: { C:#F TOL:%C };
|
||||
L: { L:#H TOL:%L };
|
||||
}
|
@ -11,9 +11,9 @@
|
||||
|
||||
SHELL = /bin/bash
|
||||
|
||||
CFLAGS = -Wall $(shell pkg-config --cflags glib-2.0)
|
||||
CFLAGS = -g -Wall $(shell pkg-config --cflags glib-2.0)
|
||||
SLOPPY = -Wno-unused -Wno-implicit-function-declaration
|
||||
OBJS = boom.o chr.o comp.o db.o eval.o param.o util.o lex.yy.o y.tab.o
|
||||
OBJS = boom.o chr.o comp.o db.o dump.o eval.o param.o util.o lex.yy.o y.tab.o
|
||||
LDLIBS = -lfl $(shell pkg-config --libs glib-2.0)
|
||||
|
||||
YACC = bison -y
|
||||
|
50
b2/boom.c
50
b2/boom.c
@ -1,4 +1,52 @@
|
||||
int main(void)
|
||||
/*
|
||||
* boom.c - BOOM, main function
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
extern int yyparse(void);
|
||||
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [file]\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd;
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
fd = open(argv[1], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if (dup2(fd, 0) < 0) {
|
||||
perror("dup2");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(*argv);
|
||||
}
|
||||
(void) yyparse();
|
||||
return 0;
|
||||
}
|
||||
|
208
b2/chr.c
208
b2/chr.c
@ -10,93 +10,193 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "param.h"
|
||||
#include "chr.h"
|
||||
|
||||
|
||||
struct condition {
|
||||
struct value value;
|
||||
enum relop relop;
|
||||
struct condition *next;
|
||||
};
|
||||
|
||||
struct selector {
|
||||
struct condition *cond;
|
||||
struct selector *next;
|
||||
};
|
||||
|
||||
struct field {
|
||||
const char *name;
|
||||
const struct format *fmt;
|
||||
struct field *mark;
|
||||
struct selector *sel;
|
||||
struct field *next;
|
||||
};
|
||||
|
||||
static struct field *fields = NULL, *curr_field = NULL, *mark = NULL;
|
||||
|
||||
|
||||
const struct format *field_find(const char *name)
|
||||
const struct format *field_find(const char *name, const struct field *tail)
|
||||
{
|
||||
const struct field *f;
|
||||
|
||||
for (f = fields; f; f = f->next)
|
||||
if (f->name == name)
|
||||
return f->fmt;
|
||||
while (tail) {
|
||||
if (tail->name == name)
|
||||
return tail->fmt;
|
||||
tail = tail->prev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void field_add(const char *name, const struct format *fmt)
|
||||
/* ----- Construction of the field hierarchy ------------------------------- */
|
||||
|
||||
|
||||
struct field *field_new(const char *name, const struct format *fmt,
|
||||
const struct field *prev)
|
||||
{
|
||||
struct field *field;
|
||||
|
||||
if (field_find(name))
|
||||
if (field_find(name, prev))
|
||||
yyerrorf("duplicate field \"%s\"", name);
|
||||
field = alloc_type(struct field);
|
||||
field->name = name;
|
||||
field->fmt = fmt;
|
||||
field->mark = (void *) 1; /* poison */
|
||||
field->sel = NULL;
|
||||
if (curr_field)
|
||||
curr_field->next = field;
|
||||
field->any.fields = NULL;
|
||||
field->any.rules = NULL;
|
||||
field->next = NULL;
|
||||
field->prev = NULL;
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
struct selector *field_selector(void)
|
||||
{
|
||||
struct selector *sel;
|
||||
|
||||
sel = alloc_type(struct selector);
|
||||
sel->cond = NULL;
|
||||
sel->act.fields = NULL;
|
||||
sel->act.rules = NULL;
|
||||
sel->next = NULL;
|
||||
return sel;
|
||||
}
|
||||
|
||||
|
||||
struct condition *field_condition(enum relop relop, const char *word)
|
||||
{
|
||||
struct condition *cond;
|
||||
|
||||
cond = alloc_type(struct condition);
|
||||
cond->value.u.name = word;
|
||||
cond->relop = relop;
|
||||
cond->next = NULL;
|
||||
return cond;
|
||||
}
|
||||
|
||||
|
||||
void field_finalize(struct field *field)
|
||||
{
|
||||
const struct selector *sel;
|
||||
struct condition *cond;
|
||||
|
||||
for (sel = field->sel; sel; sel = sel->next)
|
||||
for (cond = sel->cond; cond; cond = cond->next)
|
||||
if (!evaluate(field->fmt, cond->value.u.name,
|
||||
&cond->value))
|
||||
yyerrorf("invalid value in selection");
|
||||
/* @@@ indicate exact location */
|
||||
}
|
||||
|
||||
|
||||
/* ----- Dumping ----------------------------------------------------------- */
|
||||
|
||||
|
||||
#define INDENT 8
|
||||
|
||||
|
||||
static void dump_fields(FILE *file, const struct field *field, int level);
|
||||
|
||||
|
||||
static void dump_set_decl(FILE *file, const struct names *first_name)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = nameset_rev_lookup(first_name);
|
||||
assert(name);
|
||||
fprintf(file, "<%s>", name);
|
||||
}
|
||||
|
||||
|
||||
static void dump_field_decl(FILE *file, const struct field *field)
|
||||
{
|
||||
if (field->fmt->ops == ¶m_ops_name)
|
||||
fprintf(file, "*");
|
||||
else if (field->fmt->ops == ¶m_ops_set)
|
||||
dump_set_decl(file, field->fmt->u.set);
|
||||
else if (field->fmt->ops == ¶m_ops_abs)
|
||||
fprintf(file, "#%s", field->fmt->u.abs);
|
||||
else if (field->fmt->ops == ¶m_ops_rel)
|
||||
fprintf(file, "%%%s", field->fmt->u.rel->u.abs);
|
||||
else
|
||||
fields = field;
|
||||
curr_field = field;
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
void field_mark(void)
|
||||
static void dump_action(FILE *file, const struct action *act, int level)
|
||||
{
|
||||
if (mark)
|
||||
mark->mark = curr_field;
|
||||
mark = curr_field;
|
||||
const struct field *field;
|
||||
|
||||
if (act->fields) {
|
||||
fprintf(file, " {");
|
||||
for (field = act->fields; field; field = field->next) {
|
||||
fprintf(file, " %s:", field->name);
|
||||
dump_field_decl(file, field);
|
||||
}
|
||||
fprintf(file, " }\n");
|
||||
} else {
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
dump_fields(file, act->rules, level+1);
|
||||
}
|
||||
|
||||
|
||||
void field_release(void)
|
||||
static void dump_one_field(FILE *file, const struct field *field, int level)
|
||||
{
|
||||
curr_field = mark;
|
||||
if (curr_field)
|
||||
mark = curr_field->mark;
|
||||
const struct selector *sel;
|
||||
const struct condition *cond;
|
||||
|
||||
fprintf(file, "%*s%s:", level*INDENT, "", field->name);
|
||||
dump_field_decl(file, field);
|
||||
|
||||
fprintf(file, " {\n");
|
||||
|
||||
for (sel = field->sel; sel; sel = sel->next) {
|
||||
fprintf(file, "%*s", level*INDENT+INDENT/2, "");
|
||||
for (cond = sel->cond; cond; cond = cond->next) {
|
||||
if (cond != sel->cond)
|
||||
fprintf(file, "|");
|
||||
switch (cond->relop) {
|
||||
case rel_lt:
|
||||
fprintf(file, "<");
|
||||
break;
|
||||
case rel_le:
|
||||
fprintf(file, "<=");
|
||||
break;
|
||||
case rel_eq:
|
||||
break;
|
||||
case rel_ge:
|
||||
fprintf(file, ">");
|
||||
break;
|
||||
case rel_gt:
|
||||
fprintf(file, ">=");
|
||||
break;
|
||||
default:
|
||||
fprintf(file, "?");
|
||||
}
|
||||
dump(file, field->fmt, &cond->value);
|
||||
}
|
||||
fprintf(file, ": ");
|
||||
dump_action(file, &sel->act, level);
|
||||
}
|
||||
if (field->any.fields || field->any.rules) {
|
||||
fprintf(file, "%*s*:", level*INDENT+INDENT/2, "");
|
||||
dump_action(file, &field->any, level);
|
||||
}
|
||||
fprintf(file, "%*s}\n", level*INDENT, "");
|
||||
}
|
||||
|
||||
|
||||
void field_add_selector(enum relop relop, const char *word)
|
||||
static void dump_fields(FILE *file, const struct field *field, int level)
|
||||
{
|
||||
|
||||
while (field) {
|
||||
dump_one_field(file, field, level);
|
||||
field = field->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void field_more_selectors(void)
|
||||
void field_dump(FILE *file, const struct field *field)
|
||||
{
|
||||
if (curr_field->fmt->ops != ¶m_ops_set)
|
||||
;//yyerrorf("
|
||||
dump_fields(file, field, 0);
|
||||
}
|
||||
|
||||
|
||||
void field_add_wildcard(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
45
b2/chr.h
45
b2/chr.h
@ -13,15 +13,46 @@
|
||||
#ifndef CHR_H
|
||||
#define CHR_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "param.h"
|
||||
|
||||
|
||||
void field_add(const char *name, const struct format *fmt);
|
||||
const struct format *field_find(const char *name);
|
||||
void field_mark(void);
|
||||
void field_release(void);
|
||||
void field_add_selector(enum relop relop, const char *word);
|
||||
void field_more_selectors(void);
|
||||
void field_add_wildcard(void);
|
||||
struct field;
|
||||
|
||||
struct action {
|
||||
struct field *fields;
|
||||
struct field *rules;
|
||||
};
|
||||
|
||||
struct condition {
|
||||
struct value value;
|
||||
enum relop relop;
|
||||
struct condition *next;
|
||||
};
|
||||
|
||||
struct selector {
|
||||
struct condition *cond;
|
||||
struct action act;
|
||||
struct selector *next;
|
||||
};
|
||||
|
||||
struct field {
|
||||
const char *name;
|
||||
const struct format *fmt;
|
||||
struct selector *sel;
|
||||
struct action any;
|
||||
struct field *next;
|
||||
const struct field *prev;
|
||||
};
|
||||
|
||||
|
||||
const struct format *field_find(const char *name, const struct field *tail);
|
||||
struct field *field_new(const char *name, const struct format *fmt,
|
||||
const struct field *prev);
|
||||
struct selector *field_selector(void);
|
||||
struct condition *field_condition(enum relop relop, const char *word);
|
||||
void field_finalize(struct field *field);
|
||||
void field_dump(FILE *file, const struct field *field);
|
||||
|
||||
#endif /* !CHR_H */
|
||||
|
63
b2/dump.c
Normal file
63
b2/dump.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* dump.c - Dump a value (for debugging)
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bitset.h"
|
||||
#include "param.h"
|
||||
|
||||
|
||||
void dump_name(FILE *file, const struct format *fmt, const struct value *v)
|
||||
{
|
||||
fprintf(file, "%s", v->u.name);
|
||||
}
|
||||
|
||||
|
||||
void dump_set(FILE *file, const struct format *fmt, const struct value *v)
|
||||
{
|
||||
const struct names *name;
|
||||
int first = 1;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for (name = fmt->u.set; name; name = name->next) {
|
||||
if (bitset_get(&v->u.set, i)) {
|
||||
fprintf(file, "%s%s", first ? "" : "|",
|
||||
name->equiv->name);
|
||||
first = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dump_abs(FILE *file, const struct format *fmt, const struct value *v)
|
||||
{
|
||||
fprintf(file, "%g%s", v->u.abs, fmt->u.abs);
|
||||
}
|
||||
|
||||
|
||||
void dump_rel(FILE *file, const struct format *fmt, const struct value *v)
|
||||
{
|
||||
if (v->u.rel.fract)
|
||||
fprintf(file, "-%f/+%f%%",
|
||||
v->u.rel.minus*100, v->u.rel.plus*100);
|
||||
else
|
||||
fprintf(file, "-%g/+%g%s",
|
||||
v->u.rel.minus, v->u.rel.plus, fmt->u.rel->u.abs);
|
||||
}
|
||||
|
||||
|
||||
void dump(FILE *file, const struct format *fmt, const struct value *v)
|
||||
{
|
||||
fmt->ops->dump(file, fmt, v);
|
||||
}
|
@ -30,10 +30,12 @@ static int lookup_name(const struct names *name, const char *s)
|
||||
const struct equiv *eq;
|
||||
int n;
|
||||
|
||||
for (n = 0; name; n++)
|
||||
for (n = 0; name; n++) {
|
||||
for (eq = name->equiv; eq; eq = eq->next)
|
||||
if (eq->name == s)
|
||||
return n;
|
||||
name = name->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "util.h"
|
||||
#include "param.h"
|
||||
#include "chr.h"
|
||||
#include "y.tab.h"
|
||||
|
||||
|
||||
|
166
b2/lang.y
166
b2/lang.y
@ -12,6 +12,7 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "param.h"
|
||||
@ -19,6 +20,41 @@
|
||||
|
||||
#include "y.tab.h"
|
||||
|
||||
|
||||
static struct field_stack {
|
||||
const struct field *field;
|
||||
struct field_stack *next;
|
||||
} *field_stack = NULL;
|
||||
|
||||
|
||||
static void push_field(const struct field *field)
|
||||
{
|
||||
struct field_stack *entry;
|
||||
|
||||
entry = alloc_type(struct field_stack);
|
||||
entry->field = field;
|
||||
entry->next = field_stack;
|
||||
field_stack = entry;
|
||||
}
|
||||
|
||||
|
||||
static void pop_field(void)
|
||||
{
|
||||
struct field_stack *entry;
|
||||
|
||||
assert(field_stack);
|
||||
entry = field_stack;
|
||||
field_stack = entry->next;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
||||
static const struct field *top_field(void)
|
||||
{
|
||||
return field_stack ? field_stack->field : NULL;
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
|
||||
|
||||
@ -28,6 +64,10 @@
|
||||
struct names *names;
|
||||
struct format *format;
|
||||
enum relop relop;
|
||||
struct field *field;
|
||||
struct selector *sel;
|
||||
struct condition *cond;
|
||||
struct action act;
|
||||
};
|
||||
|
||||
|
||||
@ -38,12 +78,19 @@
|
||||
%type <names> names nameq
|
||||
%type <format> format
|
||||
%type <relop> relop opt_relop
|
||||
%type <field> /*rules*/ opt_rule rule opt_fields fields field
|
||||
%type <sel> selectors
|
||||
%type <cond> conditions condition
|
||||
%type <act> opt_wildcard action
|
||||
|
||||
%%
|
||||
|
||||
all:
|
||||
| nameset ';'
|
||||
| rules
|
||||
rule
|
||||
{
|
||||
field_dump(stderr, $1);
|
||||
}
|
||||
| nameset all
|
||||
;
|
||||
|
||||
nameset:
|
||||
@ -89,41 +136,101 @@ nameqs:
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* @@@ for now, we can't select on a collective of fields. maybe later, with
|
||||
* a syntax change.
|
||||
*
|
||||
rules:
|
||||
field '{'
|
||||
{
|
||||
field_mark();
|
||||
$$ = NULL;
|
||||
}
|
||||
selections opt_wildcard '}'
|
||||
| rule rules
|
||||
{
|
||||
field_release();
|
||||
$$ = $1;
|
||||
$$->next = $2;
|
||||
}
|
||||
;
|
||||
*/
|
||||
|
||||
opt_rule:
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| rule
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
selections:
|
||||
| selectors ':' opt_fields rules selections
|
||||
rule:
|
||||
field
|
||||
{
|
||||
$1->prev = top_field();
|
||||
push_field($1);
|
||||
}
|
||||
'{' selectors opt_wildcard '}'
|
||||
{
|
||||
$$ = $1;
|
||||
$$->sel = $4;
|
||||
$$->any = $5;
|
||||
$$->next = NULL;
|
||||
field_finalize($$);
|
||||
pop_field();
|
||||
}
|
||||
;
|
||||
|
||||
selectors:
|
||||
selector
|
||||
| selector '|'
|
||||
{
|
||||
field_more_selectors();
|
||||
$$ = NULL;
|
||||
}
|
||||
| conditions ':' action selectors
|
||||
{
|
||||
$$ = field_selector();
|
||||
$$->cond = $1;
|
||||
$$->act = $3;
|
||||
$$->next = $4;
|
||||
}
|
||||
selectors
|
||||
;
|
||||
|
||||
selector:
|
||||
conditions:
|
||||
condition
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| condition '|' conditions
|
||||
{
|
||||
$$ = $1;
|
||||
$$->next = $3;
|
||||
}
|
||||
;
|
||||
|
||||
condition:
|
||||
opt_relop WORD
|
||||
{
|
||||
field_add_selector($1, $2);
|
||||
$$ = field_condition($1, $2);
|
||||
}
|
||||
;
|
||||
|
||||
opt_wildcard:
|
||||
'*' ':'
|
||||
{
|
||||
field_add_wildcard();
|
||||
$$.fields = NULL;
|
||||
$$.rules = NULL;
|
||||
}
|
||||
| '*' ':' action
|
||||
{
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
action:
|
||||
{
|
||||
push_field(top_field());
|
||||
}
|
||||
opt_fields opt_rule ';'
|
||||
{
|
||||
$$.fields = $2;
|
||||
$$.rules = $3;
|
||||
pop_field();
|
||||
}
|
||||
;
|
||||
|
||||
@ -161,17 +268,38 @@ relop:
|
||||
;
|
||||
|
||||
opt_fields:
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| '{' fields '}'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
fields:
|
||||
| field fields
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| field
|
||||
{
|
||||
push_field($1);
|
||||
}
|
||||
fields
|
||||
{
|
||||
$$ = $1;
|
||||
$$->next = $3;
|
||||
pop_field();
|
||||
$$->prev = top_field();
|
||||
if ($3)
|
||||
$3->prev = $1;
|
||||
}
|
||||
;
|
||||
|
||||
field:
|
||||
WORD ':' format
|
||||
{
|
||||
field_add($1, $3);
|
||||
$$ = field_new($1, $3, top_field());
|
||||
}
|
||||
;
|
||||
|
||||
@ -199,7 +327,7 @@ format:
|
||||
{
|
||||
$$ = alloc_type(struct format);
|
||||
$$->ops = ¶m_ops_rel;
|
||||
$$->u.rel = field_find($2);
|
||||
$$->u.rel = field_find($2, top_field());
|
||||
if (!$$->u.rel)
|
||||
yyerrorf("unknown field \"%s\"", $2);
|
||||
}
|
||||
|
41
b2/param.c
41
b2/param.c
@ -36,12 +36,14 @@ static void check_duplicates(const struct names *n)
|
||||
const struct equiv *ea;
|
||||
|
||||
for (na = n; na; na = na->next) {
|
||||
for (ea = na->equiv; ea; ea = ea->next)
|
||||
for (ea = na->equiv; ea; ea = ea->next) {
|
||||
if (duplicate(ea->name, ea->next))
|
||||
yyerrorf("duplicate name \"%s\"", ea->name);
|
||||
for (nb = na->next; nb; nb = nb->next)
|
||||
if (duplicate(ea->name, nb->equiv))
|
||||
yyerrorf("duplicate name \"%s\"", ea->name);
|
||||
for (nb = na->next; nb; nb = nb->next)
|
||||
if (duplicate(ea->name, nb->equiv))
|
||||
yyerrorf("duplicate name \"%s\"",
|
||||
ea->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,10 +71,41 @@ const struct names *find_nameset(const char *name)
|
||||
}
|
||||
|
||||
|
||||
struct lookup_data {
|
||||
const struct names *first_name;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
|
||||
static gboolean rev_traverse(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
struct lookup_data *d = data;
|
||||
|
||||
if (d->first_name == value) {
|
||||
d->name = key;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
const char *nameset_rev_lookup(const struct names *first_name)
|
||||
{
|
||||
struct lookup_data data = {
|
||||
.first_name = first_name,
|
||||
.name = NULL,
|
||||
};
|
||||
|
||||
g_tree_foreach(tree, rev_traverse, (void *) &data);
|
||||
return data.name;
|
||||
}
|
||||
|
||||
|
||||
#define MKOPS(type) \
|
||||
const struct param_ops param_ops_##type = { \
|
||||
.eval = eval_##type, \
|
||||
.comp = comp_##type, \
|
||||
.dump = dump_##type, \
|
||||
}
|
||||
|
||||
|
||||
|
11
b2/param.h
11
b2/param.h
@ -13,6 +13,8 @@
|
||||
#ifndef PARAM_H
|
||||
#define PARAM_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bitset.h"
|
||||
|
||||
|
||||
@ -72,11 +74,14 @@ struct param_ops {
|
||||
struct value *res);
|
||||
int (*comp)(const struct value *a, enum relop relop,
|
||||
const struct value *b);
|
||||
void (*dump)(FILE *file, const struct format *fmt,
|
||||
const struct value *v);
|
||||
};
|
||||
|
||||
|
||||
void register_nameset(const char *name, const struct names *set);
|
||||
const struct names *find_nameset(const char *name);
|
||||
const char *nameset_rev_lookup(const struct names *first_name);
|
||||
|
||||
int eval_name(const struct format *fmt, const char *s, struct value *res);
|
||||
int eval_set(const struct format *fmt, const char *s, struct value *res);
|
||||
@ -91,6 +96,12 @@ int comp_rel(const struct value *a, enum relop relop, const struct value *b);
|
||||
int compare(const struct format *fmt,
|
||||
const struct value *a, enum relop relop, const struct value *b);
|
||||
|
||||
void dump_name(FILE *file, const struct format *fmt, const struct value *v);
|
||||
void dump_set(FILE *file, const struct format *fmt, const struct value *v);
|
||||
void dump_abs(FILE *file, const struct format *fmt, const struct value *v);
|
||||
void dump_rel(FILE *file, const struct format *fmt, const struct value *v);
|
||||
void dump(FILE *file, const struct format *fmt, const struct value *v);
|
||||
|
||||
extern const struct param_ops param_ops_name;
|
||||
extern const struct param_ops param_ops_set;
|
||||
extern const struct param_ops param_ops_abs;
|
||||
|
Loading…
Reference in New Issue
Block a user