Merge branch 'master' into SuperChayan
This commit is contained in:
commit
6bf4e3146d
|
|
@ -5,7 +5,7 @@ put /local/src {
|
||||||
select.c font.c editprop.c save.c paste.c token.c psprint.c node_hash.c
|
select.c font.c editprop.c save.c paste.c token.c psprint.c node_hash.c
|
||||||
hilight.c options.c vhdl_netlist.c svgdraw.c spice_netlist.c
|
hilight.c options.c vhdl_netlist.c svgdraw.c spice_netlist.c
|
||||||
tedax_netlist.c verilog_netlist.c parselabel.c expandlabel.c
|
tedax_netlist.c verilog_netlist.c parselabel.c expandlabel.c
|
||||||
in_memory_undo.c cairo_jpg.c
|
eval_expr.c in_memory_undo.c cairo_jpg.c
|
||||||
}
|
}
|
||||||
|
|
||||||
# list all files that need to be installed in "$(XSHAREDIR)"
|
# list all files that need to be installed in "$(XSHAREDIR)"
|
||||||
|
|
@ -49,12 +49,15 @@ parselabel.c: parselabel.l expandlabel.h
|
||||||
expandlabel.c expandlabel.h: expandlabel.y
|
expandlabel.c expandlabel.h: expandlabel.y
|
||||||
bison -d -o expandlabel.c expandlabel.y
|
bison -d -o expandlabel.c expandlabel.y
|
||||||
|
|
||||||
|
eval_expr.c: eval_expr.y
|
||||||
|
bison -o eval_expr.c eval_expr.y
|
||||||
|
|
||||||
parselabel.o: expandlabel.h
|
parselabel.o: expandlabel.h
|
||||||
|
|
||||||
$(OBJ): xschem.h ../config.h Makefile
|
$(OBJ): xschem.h ../config.h Makefile
|
||||||
|
|
||||||
clean: FORCE
|
clean: FORCE
|
||||||
rm -rf rawtovcd xschem *.o expandlabel.[ch] parselabel.c
|
rm -rf rawtovcd xschem *.o eval_expr.c expandlabel.[ch] parselabel.c
|
||||||
|
|
||||||
# Explicit rule for each object:
|
# Explicit rule for each object:
|
||||||
@]
|
@]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h> /* For math functions, cos(), sin(), etc. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "xschem.h"
|
||||||
|
|
||||||
|
static const char *str, *strptr;
|
||||||
|
static char *ret = NULL;
|
||||||
|
|
||||||
|
/* Data type for links in the chain of functions. */
|
||||||
|
struct symrec
|
||||||
|
{
|
||||||
|
char *name; /* name of symbol */
|
||||||
|
double (*fnctptr)(); /* value of a FNCT */
|
||||||
|
struct symrec *next; /* link field */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct symrec symrec;
|
||||||
|
|
||||||
|
/* The symbol table: a chain of `struct symrec'. */
|
||||||
|
symrec *sym_table = (symrec *)0;
|
||||||
|
|
||||||
|
static symrec *getsym(char *sym_name);
|
||||||
|
static symrec *putsym(char *sym_name);
|
||||||
|
static int kklex();
|
||||||
|
static void kkerror(char *s);
|
||||||
|
static double toint(double x);
|
||||||
|
static void get_expr(double x);
|
||||||
|
|
||||||
|
struct fn
|
||||||
|
{
|
||||||
|
char *fname;
|
||||||
|
double (*fnct)();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fn fn_array[]
|
||||||
|
= {
|
||||||
|
{"int" , toint},
|
||||||
|
{"sin" , sin},
|
||||||
|
{"cos" , cos},
|
||||||
|
{"asin", asin},
|
||||||
|
{"acos", acos},
|
||||||
|
{"atan", atan},
|
||||||
|
{"log" , log10},
|
||||||
|
{"ln" , log},
|
||||||
|
{"exp" , exp},
|
||||||
|
{"sqrt", sqrt},
|
||||||
|
{0 , 0}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%define api.prefix {kk}
|
||||||
|
%union {
|
||||||
|
double val; /* For returning numbers. */
|
||||||
|
symrec *tptr; /* For returning symbol-table pointers */
|
||||||
|
}
|
||||||
|
|
||||||
|
%token STREND 0
|
||||||
|
%token <val> NUM /* Simple double precision number */
|
||||||
|
%token <tptr> FNCT /* Variable and Function */
|
||||||
|
%type <val> exp
|
||||||
|
%right '='
|
||||||
|
%left '-' '+'
|
||||||
|
%left '*' '/' '%'
|
||||||
|
%left NEG /* Negation--unary minus */
|
||||||
|
%right '^' /* Exponentiation */
|
||||||
|
|
||||||
|
/* Grammar follows */
|
||||||
|
%%
|
||||||
|
|
||||||
|
line:
|
||||||
|
| exp STREND {get_expr($1);}
|
||||||
|
| '\'' exp '\'' STREND {get_expr($2);}
|
||||||
|
;
|
||||||
|
|
||||||
|
exp: NUM { $$ = $1;}
|
||||||
|
| FNCT '(' exp ')' { $$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
|
||||||
|
| exp '+' exp { $$ = $1 + $3; }
|
||||||
|
| exp '-' exp { $$ = $1 - $3;}
|
||||||
|
| exp '*' exp { $$ = $1 * $3;}
|
||||||
|
| exp '%' exp { $$ = (int)$1 % (int)$3;}
|
||||||
|
| exp '/' exp { $$ = $1 / $3;}
|
||||||
|
| '-' exp %prec NEG { $$ = -$2;}
|
||||||
|
| exp '^' exp { $$ = pow ($1, $3);}
|
||||||
|
| '(' exp ')' { $$ = $2;}
|
||||||
|
;
|
||||||
|
/* End of grammar */
|
||||||
|
%%
|
||||||
|
|
||||||
|
static void get_expr(double x)
|
||||||
|
{
|
||||||
|
char xx[100];
|
||||||
|
my_snprintf(xx, S(xx), "%.17g", x);
|
||||||
|
my_mstrcat(_ALLOC_ID_, &ret, xx, NULL);
|
||||||
|
strptr = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double toint(double x)
|
||||||
|
{
|
||||||
|
if(x < 0.0) return ceil(x);
|
||||||
|
return floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kkerror(char *s) /* Called by kkparse on error */
|
||||||
|
{
|
||||||
|
/* printf("error: |%s|\n\n |%s|\n", s, strptr); */
|
||||||
|
my_mstrcat(_ALLOC_ID_, &ret, strptr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static symrec *getsym(char *sym_name)
|
||||||
|
{
|
||||||
|
symrec *ptr;
|
||||||
|
for (ptr = sym_table; ptr; ptr = ptr->next)
|
||||||
|
if (strcmp (ptr->name,sym_name) == 0) return ptr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
symrec * putsym (char *sym_name)
|
||||||
|
{
|
||||||
|
symrec *ptr;
|
||||||
|
ptr = (symrec *) my_malloc(_ALLOC_ID_, sizeof (symrec));
|
||||||
|
ptr->name = (char *) my_malloc(_ALLOC_ID_, strlen (sym_name) + 1);
|
||||||
|
strcpy (ptr->name,sym_name);
|
||||||
|
ptr->next = (struct symrec *)sym_table;
|
||||||
|
sym_table = ptr;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eval_expr_init_table(void) /* puts arithmetic functions in table. */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
symrec *ptr;
|
||||||
|
for (i = 0; fn_array[i].fname != 0; i++)
|
||||||
|
{
|
||||||
|
ptr = putsym (fn_array[i].fname);
|
||||||
|
ptr->fnctptr = fn_array[i].fnct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eval_expr_clear_table(void)
|
||||||
|
{
|
||||||
|
symrec *ptr;
|
||||||
|
for (ptr = sym_table; ptr; ptr = ptr->next) {
|
||||||
|
symrec *tmp = ptr;
|
||||||
|
my_free(_ALLOC_ID_, &(tmp->name));
|
||||||
|
my_free(_ALLOC_ID_, &tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kklex()
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if(!str) { return 0; }
|
||||||
|
/* Ignore whitespace, get first nonwhite character. */
|
||||||
|
while ((c = *str++) == ' ' || c == '\t' || c == '\n');
|
||||||
|
if (c == 0) {
|
||||||
|
str = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Char starts a number => parse the number. */
|
||||||
|
if (c == '.' || isdigit (c))
|
||||||
|
{
|
||||||
|
char s[100] ="";
|
||||||
|
int rd = 0;
|
||||||
|
str--;
|
||||||
|
|
||||||
|
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
|
||||||
|
kklval.val = atof_spice(s);
|
||||||
|
str += rd;
|
||||||
|
/* printf("yylex: NUM: %s\n", s); */
|
||||||
|
return NUM;
|
||||||
|
}
|
||||||
|
/* Char starts an identifier => read the name. */
|
||||||
|
if(isalpha(c)) {
|
||||||
|
symrec *s;
|
||||||
|
int length = 40; /* max length of function names */
|
||||||
|
char symbuf[41];
|
||||||
|
int i = 0;
|
||||||
|
/* Initially make the buffer int enough
|
||||||
|
* for a 40-character symbol name. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
symbuf[i++] = (char) c; /* Add this character to the buffer.*/
|
||||||
|
c = *str++; /* Get another character.*/
|
||||||
|
}
|
||||||
|
while (c != 0 && isalnum(c) && i < length);
|
||||||
|
str--;
|
||||||
|
symbuf[i] = '\0';
|
||||||
|
s = getsym (symbuf);
|
||||||
|
kklval.tptr = s;
|
||||||
|
/* printf("yylex: FNCT=%s\n", symbuf); */
|
||||||
|
return FNCT;
|
||||||
|
}
|
||||||
|
/* Any other character is a token by itself. */
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *eval_expr(const char *s)
|
||||||
|
{
|
||||||
|
if(ret) my_free(_ALLOC_ID_, &ret);
|
||||||
|
strptr = str = s;
|
||||||
|
kkparse();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -1008,6 +1008,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* eval_expr str
|
||||||
|
* debug function: evaluate arithmetic expression in str */
|
||||||
|
else if(!strcmp(argv[1], "eval_expr"))
|
||||||
|
{
|
||||||
|
if(argc > 2) {
|
||||||
|
Tcl_SetResult(interp, eval_expr(argv[2]), TCL_VOLATILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* exit [exit_code] [closewindow] [force]
|
/* exit [exit_code] [closewindow] [force]
|
||||||
* Exit the program, ask for confirm if current file modified.
|
* Exit the program, ask for confirm if current file modified.
|
||||||
* if exit_code is given exit with its value, otherwise use 0 exit code
|
* if exit_code is given exit with its value, otherwise use 0 exit code
|
||||||
|
|
|
||||||
|
|
@ -955,6 +955,7 @@ static void xwin_exit(void)
|
||||||
trim_chars(NULL, ""); /* clear static data in function */
|
trim_chars(NULL, ""); /* clear static data in function */
|
||||||
tcl_hook2(NULL); /* clear static data in function */
|
tcl_hook2(NULL); /* clear static data in function */
|
||||||
save_ascii_string(NULL, NULL, 0); /* clear static data in function */
|
save_ascii_string(NULL, NULL, 0); /* clear static data in function */
|
||||||
|
eval_expr_clear_table(); /* clear expression parser data */
|
||||||
dbg(1, "xwin_exit(): removing font\n");
|
dbg(1, "xwin_exit(): removing font\n");
|
||||||
for(i=0;i<127; ++i) my_free(_ALLOC_ID_, &character[i]);
|
for(i=0;i<127; ++i) my_free(_ALLOC_ID_, &character[i]);
|
||||||
dbg(1, "xwin_exit(): closed display\n");
|
dbg(1, "xwin_exit(): closed display\n");
|
||||||
|
|
@ -2310,6 +2311,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
const char* home_buff;
|
const char* home_buff;
|
||||||
#endif
|
#endif
|
||||||
|
eval_expr_init_table();
|
||||||
/* get PWD and HOME */
|
/* get PWD and HOME */
|
||||||
if(!getcwd(pwd_dir, PATH_MAX)) {
|
if(!getcwd(pwd_dir, PATH_MAX)) {
|
||||||
fprintf(errfp, "Tcl_AppInit(): getcwd() failed\n");
|
fprintf(errfp, "Tcl_AppInit(): getcwd() failed\n");
|
||||||
|
|
|
||||||
|
|
@ -1675,6 +1675,9 @@ extern void check_box_storage(int c);
|
||||||
extern void check_arc_storage(int c);
|
extern void check_arc_storage(int c);
|
||||||
extern void check_line_storage(int c);
|
extern void check_line_storage(int c);
|
||||||
extern void check_polygon_storage(int c);
|
extern void check_polygon_storage(int c);
|
||||||
|
extern void eval_expr_init_table(void);
|
||||||
|
extern void eval_expr_clear_table(void);
|
||||||
|
extern char *eval_expr(const char *s);
|
||||||
extern const char *expandlabel(const char *s, int *m);
|
extern const char *expandlabel(const char *s, int *m);
|
||||||
extern void parse(const char *s);
|
extern void parse(const char *s);
|
||||||
extern void clear_expandlabel_data(void);
|
extern void clear_expandlabel_data(void);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue