1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2025-04-21 12:27:27 +03:00

introduce keyed tables (?var syntax; WIP)

This cannot be set/changed through the GUI yet.
This commit is contained in:
Werner Almesberger
2012-05-27 16:10:59 -03:00
parent 3c39600c1c
commit 3488cf80ec
8 changed files with 276 additions and 26 deletions

78
expr.c
View File

@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "util.h"
@@ -95,6 +96,18 @@ int to_unit(struct num *n)
}
/* ----- number to string conversion (hackish) ----------------------------- */
static char *num_to_string(struct num n)
{
static char buf[100]; /* enough :-) */
snprintf(buf, sizeof(buf), "%lg%s", n.n, str_unit(n));
return buf;
}
/* ----- primary expressions ----------------------------------------------- */
@@ -131,7 +144,7 @@ struct num eval_var(const struct frame *frame, const char *name)
value = table->curr_row ? table->curr_row->values :
table->active_row->values;
for (var = table->vars; var; var = var->next) {
if (var->name == name) {
if (!var->key && var->name == name) {
if (var->visited) {
fail("recursive evaluation through "
"\"%s\"", name);
@@ -141,7 +154,6 @@ struct num eval_var(const struct frame *frame, const char *name)
res = eval_num(value->expr, frame);
var->visited = 0;
return res;
}
value = value->next;
}
@@ -176,14 +188,13 @@ static const char *eval_string_var(const struct frame *frame, const char *name)
value = table->curr_row ? table->curr_row->values :
table->active_row->values;
for (var = table->vars; var; var = var->next) {
if (var->name == name) {
if (!var->key && var->name == name) {
if (var->visited)
return NULL;
var->visited = 1;
res = eval_str(value->expr, frame);
var->visited = 0;
return res;
}
value = value->next;
}
@@ -210,6 +221,55 @@ struct num op_var(const struct expr *self, const struct frame *frame)
}
/* ----- Variable equivalence ---------------------------------------------- */
static int num_eq(struct num a, struct num b)
{
if (a.exponent != b.exponent)
return 0;
if (a.exponent && a.type != b.type) {
if (a.type == nt_mil)
return mil_to_mm(a.n, a.exponent) == b.n;
else
return a.n == mil_to_mm(b.n, b.exponent);
}
return a.n == b.n;
}
int var_eq(const struct frame *frame, const char *name,
const struct expr *expr)
{
const char *vs, *es;
struct num vn, en;
vs = eval_string_var(frame, name);
if (!vs) {
vn = eval_var(frame, name);
if (is_undef(vn)) {
fail("undefined variable \"%s\"", name);
return -1;
}
}
es = eval_str(expr, frame);
if (!es) {
en = eval_num(expr, frame);
if (is_undef(en))
return -1;
}
if (vs || es) {
if (!vs)
vs = num_to_string(vn);
if (!es)
es = num_to_string(en);
return !strcmp(vs, es);
} else {
return num_eq(vn, en);
}
}
/* ----- arithmetic -------------------------------------------------------- */
@@ -436,7 +496,6 @@ char *expand(const char *name, const struct frame *frame)
{
int len = strlen(name);
char *buf = alloc_size(len+1);
char num_buf[100]; /* enough :-) */
const char *s, *s0;
char *var;
const char *var_unique, *value_string;
@@ -483,18 +542,15 @@ char *expand(const char *name, const struct frame *frame)
var_unique = unique(var);
free(var);
value_string = eval_string_var(frame, var_unique);
if (value_string) {
value_len = strlen(value_string);
} else {
if (!value_string) {
value = eval_var(frame, var_unique);
if (is_undef(value)) {
fail("undefined variable \"%s\"", var_unique);
goto fail;
}
value_len = snprintf(num_buf, sizeof(num_buf), "%lg%s",
value.n, str_unit(value));
value_string = num_buf;
value_string = num_to_string(value);
}
value_len = strlen(value_string);
len += value_len;
buf = realloc(buf, len+1);
if (!buf)