r5732 - trunk/eda/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Tue Dec 1 13:43:59 CET 2009
Author: werner
Date: 2009-12-01 13:43:59 +0100 (Tue, 01 Dec 2009)
New Revision: 5732
Modified:
trunk/eda/fped/README
trunk/eda/fped/expr.c
trunk/eda/fped/expr.h
trunk/eda/fped/fpd.y
trunk/eda/fped/unparse.c
Log:
Added functions sin(), cos(), and sqrt().
Modified: trunk/eda/fped/README
===================================================================
--- trunk/eda/fped/README 2009-12-01 10:50:55 UTC (rev 5731)
+++ trunk/eda/fped/README 2009-12-01 12:43:59 UTC (rev 5732)
@@ -438,10 +438,19 @@
-----------
Expressions can contain numeric constants (in non-exponential notation),
-variable names, the arithmetic operations +, -, *, /, and unary -.
+variable names, the arithmetic operations +, -, *, /, unary -, and the
+functions sin(), cos(), and sqrt().
+
Parentheses can be used to change precedence.
+The argument of sin and cos is a dimensionless number that specifies the
+angle in degrees. E.g., sin(90) yields 1.
+The argument of sqrt() can be dimensionless or have a dimension with an
+exponent that's a multiple of two. E.g., sqrt(2) and sqrt(2mm*3mm) are
+valid expressions, sqrt(2mm) isn't.
+
+
GUI
---
Modified: trunk/eda/fped/expr.c
===================================================================
--- trunk/eda/fped/expr.c 2009-12-01 10:50:55 UTC (rev 5731)
+++ trunk/eda/fped/expr.c 2009-12-01 12:43:59 UTC (rev 5732)
@@ -249,6 +249,56 @@
}
+static struct num sin_cos(const struct expr *self,
+ const struct frame *frame, double (*fn)(double arg))
+{
+ struct num res;
+
+ res = eval_num(self->u.op.a, frame);
+ if (is_undef(res))
+ return undef;
+ if (!is_dimensionless(res)) {
+ fail("angle must be dimensionless");
+ return undef;
+ }
+ res.n = fn(res.n/180.0*M_PI);
+ return res;
+}
+
+
+struct num op_sin(const struct expr *self, const struct frame *frame)
+{
+ return sin_cos(self, frame, sin);
+}
+
+
+struct num op_cos(const struct expr *self, const struct frame *frame)
+{
+ return sin_cos(self, frame, cos);
+}
+
+
+struct num op_sqrt(const struct expr *self, const struct frame *frame)
+{
+ struct num res;
+
+ res = eval_num(self->u.op.a, frame);
+ if (is_undef(res))
+ return undef;
+ if (res.exponent & 1) {
+ fail("exponent of sqrt argument must be a multiple of two");
+ return undef;
+ }
+ if (res.n < 0) {
+ fail("argument of sqrt must be positive");
+ return undef;
+ }
+ res.n = sqrt(res.n);
+ res.exponent >>= 1;
+ return res;
+}
+
+
struct num op_minus(const struct expr *self, const struct frame *frame)
{
struct num res;
@@ -306,7 +356,7 @@
{
BINARY;
if (!b.n) {
- fail("Division by zero");
+ fail("division by zero");
return undef;
}
res = compatible_mult(&a, &b, a.exponent-b.exponent);
@@ -471,7 +521,8 @@
free(expr->u.str);
return;
}
- if (expr->op == op_minus) {
+ if (expr->op == op_minus ||
+ expr->op == op_sin || expr->op == op_cos || expr->op == op_sqrt) {
free_expr(expr->u.op.a);
return;
}
Modified: trunk/eda/fped/expr.h
===================================================================
--- trunk/eda/fped/expr.h 2009-12-01 10:50:55 UTC (rev 5731)
+++ trunk/eda/fped/expr.h 2009-12-01 12:43:59 UTC (rev 5732)
@@ -111,6 +111,10 @@
struct num op_var(const struct expr *self, const struct frame *frame);
struct num op_string(const struct expr *self, const struct frame *frame);
+struct num op_sin(const struct expr *self, const struct frame *frame);
+struct num op_cos(const struct expr *self, const struct frame *frame);
+struct num op_sqrt(const struct expr *self, const struct frame *frame);
+
struct num op_minus(const struct expr *self, const struct frame *frame);
struct num op_add(const struct expr *self, const struct frame *frame);
Modified: trunk/eda/fped/fpd.y
===================================================================
--- trunk/eda/fped/fpd.y 2009-12-01 10:50:55 UTC (rev 5731)
+++ trunk/eda/fped/fpd.y 2009-12-01 12:43:59 UTC (rev 5732)
@@ -43,7 +43,9 @@
static int n_vars, n_values;
+static const char *id_sin, *id_cos, *id_sqrt;
+
static struct frame *find_frame(const char *name)
{
struct frame *f;
@@ -186,6 +188,9 @@
{
root_frame = zalloc_type(struct frame);
set_frame(root_frame);
+ id_sin = unique("sin");
+ id_cos = unique("cos");
+ id_sqrt = unique("sqrt");
}
fpd
{
@@ -704,6 +709,19 @@
{
$$ = $2;
}
+ | ID '(' expr ')'
+ {
+ if ($1 == id_sin)
+ $$ = binary_op(op_sin, $3, NULL);
+ else if ($1 == id_cos)
+ $$ = binary_op(op_cos, $3, NULL);
+ else if ($1 == id_sqrt)
+ $$ = binary_op(op_sqrt, $3, NULL);
+ else {
+ yyerrorf("unknown function \"%s\"", $1);
+ YYABORT;
+ }
+ }
;
/* special sub-grammar */
Modified: trunk/eda/fped/unparse.c
===================================================================
--- trunk/eda/fped/unparse.c 2009-12-01 10:50:55 UTC (rev 5731)
+++ trunk/eda/fped/unparse.c 2009-12-01 12:43:59 UTC (rev 5732)
@@ -38,7 +38,8 @@
return prec_mult;
if (op == op_minus)
return prec_unary;
- if (op == op_num || op == op_string || op == op_var)
+ if (op == op_num || op == op_string || op == op_var ||
+ op == op_sin || op == op_cos || op == op_sqrt)
return prec_primary;
abort();
}
@@ -67,6 +68,21 @@
}
+static char *unparse_op(const struct expr *expr, enum prec prec);
+
+
+static char *unparse_fn(const char *name, const struct expr *expr)
+{
+ char *buf, *tmp;
+
+ tmp = unparse_op(expr->u.op.a, prec_add);
+ buf = alloc_size(strlen(name)+strlen(tmp)+3);
+ sprintf(buf, "%s(%s)", name, tmp);
+ free(tmp);
+ return buf;
+}
+
+
static char *unparse_op(const struct expr *expr, enum prec prec)
{
char tmp[100];
@@ -103,6 +119,12 @@
if (expr->op == op_div)
return merge3(unparse_op(expr->u.op.a, prec_mult), "/",
unparse_op(expr->u.op.b, prec_primary));
+ if (expr->op == op_sin)
+ return unparse_fn("sin", expr);
+ if (expr->op == op_cos)
+ return unparse_fn("cos", expr);
+ if (expr->op == op_sqrt)
+ return unparse_fn("sqrt", expr);
abort();
}
More information about the commitlog
mailing list