mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-05 06:18:26 +02:00
386a9fd50b
- implemented eval_str - expand() now tries to obtain a string - added example fbga.fpd to demonstrate use of strings - when invoked with an inexisting file, fped now starts with an empty model, instead of getting confused - we now religiously call edit_nothing before adding fields to edit, so that we won't create a loop through edit-next git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5421 99fdad57-331a-0410-800a-d7fa5415bdb3
141 lines
2.9 KiB
C
141 lines
2.9 KiB
C
/*
|
|
* expr.h - Expressions and values
|
|
*
|
|
* Written 2009 by Werner Almesberger
|
|
* Copyright 2009 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.
|
|
*/
|
|
|
|
|
|
#ifndef EXPR_H
|
|
#define EXPR_H
|
|
|
|
#include <math.h>
|
|
|
|
|
|
#define UNDEF HUGE_VAL
|
|
|
|
|
|
struct frame;
|
|
struct expr;
|
|
|
|
enum num_type {
|
|
nt_none,
|
|
nt_mm,
|
|
nt_mil,
|
|
};
|
|
|
|
struct num {
|
|
enum num_type type;
|
|
int exponent;
|
|
double n;
|
|
};
|
|
|
|
typedef struct num (*op_type)(const struct expr *self,
|
|
const struct frame *frame);
|
|
|
|
struct expr {
|
|
op_type op;
|
|
union {
|
|
struct num num;
|
|
const char *var;
|
|
char *str;
|
|
struct {
|
|
struct expr *a;
|
|
struct expr *b;
|
|
} op;
|
|
} u;
|
|
int lineno;
|
|
};
|
|
|
|
|
|
extern struct num undef;
|
|
|
|
|
|
#define is_undef(num) ((num).type == nt_none)
|
|
#define is_dimensionless(num) (!(num).exponent)
|
|
|
|
|
|
static inline int is_distance(struct num num)
|
|
{
|
|
return (num.type == nt_mm || num.type == nt_mil) && num.exponent == 1;
|
|
}
|
|
|
|
|
|
void fail_expr(const struct expr *expr);
|
|
|
|
const char *str_unit(struct num n);
|
|
|
|
|
|
static inline struct num make_num(double n)
|
|
{
|
|
struct num res;
|
|
|
|
res.type = nt_mm;
|
|
res.exponent = 0;
|
|
res.n = n;
|
|
return res;
|
|
}
|
|
|
|
|
|
static inline struct num make_mm(double mm)
|
|
{
|
|
struct num res;
|
|
|
|
res.type = nt_mm;
|
|
res.exponent = 1;
|
|
res.n = mm;
|
|
return res;
|
|
}
|
|
|
|
|
|
static inline struct num make_mil(double mil)
|
|
{
|
|
struct num res;
|
|
|
|
res.type = nt_mil;
|
|
res.exponent = 1;
|
|
res.n = mil;
|
|
return res;
|
|
}
|
|
|
|
|
|
int to_unit(struct num *n);
|
|
|
|
struct num op_num(const struct expr *self, const struct frame *frame);
|
|
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_minus(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);
|
|
struct num op_mult(const struct expr *self, const struct frame *frame);
|
|
struct num op_div(const struct expr *self, const struct frame *frame);
|
|
|
|
struct expr *new_op(op_type op);
|
|
struct expr *binary_op(op_type op, struct expr *a, struct expr *b);
|
|
|
|
struct num eval_var(const struct frame *frame, const char *name);
|
|
|
|
/*
|
|
* eval_str returns NULL if the result isn't a string. Evaluation may then
|
|
* be attempted with eval_num, and the result can be converted accordingly.
|
|
*/
|
|
const char *eval_str(const struct expr *expr, const struct frame *frame);
|
|
|
|
struct num eval_num(const struct expr *expr, const struct frame *frame);
|
|
|
|
/* if frame == NULL, we only check the syntax without expanding */
|
|
char *expand(const char *name, const struct frame *frame);
|
|
|
|
struct expr *new_num(struct num num);
|
|
struct expr *parse_expr(const char *s);
|
|
void free_expr(struct expr *expr);
|
|
|
|
#endif /* !EXPR_H */
|