1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-12-22 21:49:53 +02:00

add floor() function

This commit is contained in:
Werner Almesberger 2012-05-26 14:13:58 -03:00
parent e0351bdf73
commit 9a6c7d2742
6 changed files with 51 additions and 8 deletions

6
README
View File

@ -509,7 +509,7 @@ Expressions
Expressions can contain numeric constants (in non-exponential notation),
variable names, the arithmetic operations +, -, *, /, unary -, and the
functions sin(), cos(), and sqrt().
functions sin(), cos(), sqrt(), and floor().
Parentheses can be used to change precedence.
@ -520,6 +520,10 @@ 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.
The function floor() returns the next integer that is below or equal to
the argument. If the argument has a dimension, that dimension is
preserved. E.g., floor(-1.2) returns -2, floor(4.7mm) returns 4mm.
GUI
---

13
expr.c
View File

@ -322,6 +322,17 @@ struct num op_minus(const struct expr *self, const struct frame *frame)
}
struct num op_floor(const struct expr *self, const struct frame *frame)
{
struct num res;
res = eval_num(self->u.op.a, frame);
if (!is_undef(res))
res.n = floor(res.n);
return res;
}
#define BINARY \
struct num a, b, res; \
\
@ -533,7 +544,7 @@ static void vacate_op(struct expr *expr)
free(expr->u.str);
return;
}
if (expr->op == op_minus ||
if (expr->op == op_minus || expr->op == op_floor ||
expr->op == op_sin || expr->op == op_cos || expr->op == op_sqrt) {
free_expr(expr->u.op.a);
return;

5
expr.h
View File

@ -1,8 +1,8 @@
/*
* expr.h - Expressions and values
*
* Written 2009 by Werner Almesberger
* Copyright 2009 by Werner Almesberger
* Written 2009, 2012 by Werner Almesberger
* Copyright 2009, 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
@ -116,6 +116,7 @@ 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_floor(const struct expr *self, const struct frame *frame);
struct num op_add(const struct expr *self, const struct frame *frame);
struct num op_sub(const struct expr *self, const struct frame *frame);

5
fpd.y
View File

@ -48,7 +48,7 @@ static struct obj **next_obj;
static int n_vars, n_values;
static const char *id_sin, *id_cos, *id_sqrt;
static const char *id_sin, *id_cos, *id_sqrt, *id_floor;
static struct tsort *tsort;
@ -491,6 +491,7 @@ all:
id_sin = unique("sin");
id_cos = unique("cos");
id_sqrt = unique("sqrt");
id_floor = unique("floor");
}
fpd
| START_EXPR expr
@ -1245,6 +1246,8 @@ primary_expr:
$$ = binary_op(op_cos, $3, NULL);
else if ($1 == id_sqrt)
$$ = binary_op(op_sqrt, $3, NULL);
else if ($1 == id_floor)
$$ = binary_op(op_floor, $3, NULL);
else {
yyerrorf("unknown function \"%s\"", $1);
YYABORT;

22
test/floor Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
. ./Common
###############################################################################
fped "floor: 4.7mm" <<EOF
%print floor(4.7mm)
EOF
expect <<EOF
4mm
EOF
#------------------------------------------------------------------------------
fped "floor: -1.2m" <<EOF
%print floor(-1.2)
EOF
expect <<EOF
-2
EOF
###############################################################################

View File

@ -1,8 +1,8 @@
/*
* unparse.c - Dump an expression tree into a string
*
* Written 2009 by Werner Almesberger
* Copyright 2009 by Werner Almesberger
* Written 2009, 2012 by Werner Almesberger
* Copyright 2009, 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
@ -39,7 +39,7 @@ static int precedence(op_type op)
if (op == op_minus)
return prec_unary;
if (op == op_num || op == op_string || op == op_var ||
op == op_sin || op == op_cos || op == op_sqrt)
op == op_sin || op == op_cos || op == op_sqrt || op == op_floor)
return prec_primary;
abort();
}
@ -125,6 +125,8 @@ static char *unparse_op(const struct expr *expr, enum prec prec)
return unparse_fn("cos", expr);
if (expr->op == op_sqrt)
return unparse_fn("sqrt", expr);
if (expr->op == op_floor)
return unparse_fn("floor", expr);
abort();
}