Merge branch 'master' into SuperChayan
This commit is contained in:
commit
aef102cf8e
107
src/eval_expr.y
107
src/eval_expr.y
|
|
@ -10,6 +10,8 @@
|
||||||
static const char *str, *strptr;
|
static const char *str, *strptr;
|
||||||
static char *ret = NULL;
|
static char *ret = NULL;
|
||||||
|
|
||||||
|
static int dbglev = 1;
|
||||||
|
|
||||||
/* Data type for links in the chain of functions. */
|
/* Data type for links in the chain of functions. */
|
||||||
struct symrec
|
struct symrec
|
||||||
{
|
{
|
||||||
|
|
@ -29,13 +31,14 @@ static int kklex();
|
||||||
static void kkerror(char *s);
|
static void kkerror(char *s);
|
||||||
static double toint(double x);
|
static double toint(double x);
|
||||||
static void get_expr(double x);
|
static void get_expr(double x);
|
||||||
|
static void get_char(int c);
|
||||||
|
|
||||||
struct fn
|
struct fn
|
||||||
{
|
{
|
||||||
char *fname;
|
char *fname;
|
||||||
double (*fnct)();
|
double (*fnct)();
|
||||||
};
|
};
|
||||||
|
static int lex_state = 0;
|
||||||
struct fn fn_array[]
|
struct fn fn_array[]
|
||||||
= {
|
= {
|
||||||
{"int" , toint},
|
{"int" , toint},
|
||||||
|
|
@ -54,11 +57,14 @@ struct fn fn_array[]
|
||||||
|
|
||||||
%define api.prefix {kk}
|
%define api.prefix {kk}
|
||||||
%union {
|
%union {
|
||||||
|
int c;
|
||||||
double val; /* For returning numbers. */
|
double val; /* For returning numbers. */
|
||||||
symrec *tptr; /* For returning symbol-table pointers */
|
symrec *tptr; /* For returning symbol-table pointers */
|
||||||
}
|
}
|
||||||
|
|
||||||
%token STREND 0
|
%token STREND 0
|
||||||
|
%token <c> CHAR
|
||||||
|
%token EXPR /* expr( */
|
||||||
%token <val> NUM /* Simple double precision number */
|
%token <val> NUM /* Simple double precision number */
|
||||||
%token <tptr> FNCT /* Variable and Function */
|
%token <tptr> FNCT /* Variable and Function */
|
||||||
%type <val> exp
|
%type <val> exp
|
||||||
|
|
@ -70,29 +76,45 @@ symrec *tptr; /* For returning symbol-table pointers */
|
||||||
|
|
||||||
/* Grammar follows */
|
/* Grammar follows */
|
||||||
%%
|
%%
|
||||||
|
input:
|
||||||
line:
|
| input line
|
||||||
| exp STREND {get_expr($1);}
|
|
||||||
| '\'' exp '\'' STREND {get_expr($2);}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
exp: NUM { $$ = $1;}
|
line:
|
||||||
| FNCT '(' exp ')' { $$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
|
CHAR {get_char($1);}
|
||||||
| exp '+' exp { $$ = $1 + $3; }
|
| EXPR exp ')' {get_expr($2);lex_state = 0;}
|
||||||
| exp '-' exp { $$ = $1 - $3;}
|
| EXPR '\'' exp '\'' ')' {get_expr($3);lex_state = 0;}
|
||||||
| exp '*' exp { $$ = $1 * $3;}
|
| EXPR exp error
|
||||||
| exp '%' exp { $$ = (int)$1 % (int)$3;}
|
;
|
||||||
| exp '/' exp { $$ = $1 / $3;}
|
|
||||||
| '-' exp %prec NEG { $$ = -$2;}
|
exp: NUM {$$ = $1;}
|
||||||
| exp '^' exp { $$ = pow ($1, $3);}
|
| FNCT '(' exp ')' {$$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
|
||||||
| '(' exp ')' { $$ = $2;}
|
| 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 */
|
/* End of grammar */
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
static void get_char(int c)
|
||||||
|
{
|
||||||
|
char s[2];
|
||||||
|
dbg(dbglev, "get_char: %c |%s|\n", c, str);
|
||||||
|
s[0] = (char)c;
|
||||||
|
s[1] = '\0';
|
||||||
|
my_mstrcat(_ALLOC_ID_, &ret, s, NULL);
|
||||||
|
strptr = str;
|
||||||
|
}
|
||||||
|
|
||||||
static void get_expr(double x)
|
static void get_expr(double x)
|
||||||
{
|
{
|
||||||
char xx[100];
|
char xx[100];
|
||||||
|
dbg(dbglev,"get_expr(): x=%g\n", x);
|
||||||
my_snprintf(xx, S(xx), "%.15g", x);
|
my_snprintf(xx, S(xx), "%.15g", x);
|
||||||
my_mstrcat(_ALLOC_ID_, &ret, xx, NULL);
|
my_mstrcat(_ALLOC_ID_, &ret, xx, NULL);
|
||||||
strptr = str;
|
strptr = str;
|
||||||
|
|
@ -104,10 +126,39 @@ static double toint(double x)
|
||||||
return floor(x);
|
return floor(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ad=expr(3*xa) pd=expr(2*(3+xa)) --> ad=3*xa pd=2*(3+xa) */
|
||||||
|
static void remove_expr(char *s)
|
||||||
|
{
|
||||||
|
char *ptr = s;
|
||||||
|
int plev = 0;
|
||||||
|
while(*ptr) {
|
||||||
|
if(strstr(ptr, "expr(") == ptr) {
|
||||||
|
ptr += 5;
|
||||||
|
plev++;
|
||||||
|
}
|
||||||
|
if(*ptr == '(') plev++;
|
||||||
|
if(*ptr == ')') {
|
||||||
|
plev--;
|
||||||
|
if(plev == 0) ptr++;
|
||||||
|
if(!ptr) break;
|
||||||
|
}
|
||||||
|
*s = *ptr;
|
||||||
|
ptr++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*s = *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void kkerror(char *s) /* Called by kkparse on error */
|
static void kkerror(char *s) /* Called by kkparse on error */
|
||||||
{
|
{
|
||||||
/* printf("error: |%s|\n\n |%s|\n", s, strptr); */
|
char *ss = NULL;
|
||||||
my_mstrcat(_ALLOC_ID_, &ret, strptr, NULL);
|
dbg(dbglev, "error: |%s|\n\n |%s|\n", s, str ? str : "<NULL>");
|
||||||
|
my_strdup2(_ALLOC_ID_, &ss, strptr);
|
||||||
|
remove_expr(ss);
|
||||||
|
my_mstrcat(_ALLOC_ID_, &ret, ss, NULL);
|
||||||
|
my_free(_ALLOC_ID_, &ss);
|
||||||
|
lex_state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static symrec *getsym(char *sym_name)
|
static symrec *getsym(char *sym_name)
|
||||||
|
|
@ -155,6 +206,23 @@ static int kklex()
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if(!str) { return 0; }
|
if(!str) { return 0; }
|
||||||
|
if(strstr(str, "expr(") == str) {
|
||||||
|
lex_state = 1;
|
||||||
|
str += 5;
|
||||||
|
dbg(dbglev, "lex(): EXPR\n");
|
||||||
|
return EXPR;
|
||||||
|
}
|
||||||
|
if(!lex_state) {
|
||||||
|
c = *str++;
|
||||||
|
if(c) {
|
||||||
|
kklval.c = c;
|
||||||
|
dbg(dbglev, "lex(): CHAR; %c\n", c);
|
||||||
|
return CHAR;
|
||||||
|
} else {
|
||||||
|
dbg(dbglev, "lex(): STREND\n");
|
||||||
|
return STREND;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Ignore whitespace, get first nonwhite character. */
|
/* Ignore whitespace, get first nonwhite character. */
|
||||||
while ((c = *str++) == ' ' || c == '\t' || c == '\n');
|
while ((c = *str++) == ' ' || c == '\t' || c == '\n');
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
|
|
@ -171,7 +239,7 @@ static int kklex()
|
||||||
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
|
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
|
||||||
kklval.val = atof_spice(s);
|
kklval.val = atof_spice(s);
|
||||||
str += rd;
|
str += rd;
|
||||||
/* printf("yylex: NUM: %s\n", s); */
|
dbg(dbglev, "lex(): NUM: %s\n", s);
|
||||||
return NUM;
|
return NUM;
|
||||||
}
|
}
|
||||||
/* Char starts an identifier => read the name. */
|
/* Char starts an identifier => read the name. */
|
||||||
|
|
@ -192,7 +260,7 @@ static int kklex()
|
||||||
symbuf[i] = '\0';
|
symbuf[i] = '\0';
|
||||||
s = getsym (symbuf);
|
s = getsym (symbuf);
|
||||||
kklval.tptr = s;
|
kklval.tptr = s;
|
||||||
/* printf("yylex: FNCT=%s\n", symbuf); */
|
dbg(dbglev, "ylex: FNCT=%s\n", symbuf);
|
||||||
return FNCT;
|
return FNCT;
|
||||||
}
|
}
|
||||||
/* Any other character is a token by itself. */
|
/* Any other character is a token by itself. */
|
||||||
|
|
@ -201,6 +269,7 @@ static int kklex()
|
||||||
|
|
||||||
char *eval_expr(const char *s)
|
char *eval_expr(const char *s)
|
||||||
{
|
{
|
||||||
|
lex_state = 0;
|
||||||
if(ret) my_free(_ALLOC_ID_, &ret);
|
if(ret) my_free(_ALLOC_ID_, &ret);
|
||||||
strptr = str = s;
|
strptr = str = s;
|
||||||
kkparse();
|
kkparse();
|
||||||
|
|
|
||||||
22
src/token.c
22
src/token.c
|
|
@ -2249,12 +2249,9 @@ int print_spice_element(FILE *fd, int inst)
|
||||||
if (!xctx->tok_size) value=get_tok_value(template, token+1, 0);
|
if (!xctx->tok_size) value=get_tok_value(template, token+1, 0);
|
||||||
token_exists = xctx->tok_size;
|
token_exists = xctx->tok_size;
|
||||||
|
|
||||||
if(strstr(value, "expr(") == value) {
|
if(strstr(value, "expr(") ) {
|
||||||
char *ptr;
|
my_strdup2(_ALLOC_ID_, &val, value);
|
||||||
my_strdup(_ALLOC_ID_, &val, value);
|
value = eval_expr(translate3(val, 1, xctx->inst[inst].prop_ptr, template, NULL));
|
||||||
ptr = strrchr(val + 5, ')');
|
|
||||||
*ptr = '\0';
|
|
||||||
value = eval_expr(translate3(val + 5, 1, xctx->inst[inst].prop_ptr, template, NULL));
|
|
||||||
}
|
}
|
||||||
if(!strcmp("@savecurrent", token)) {
|
if(!strcmp("@savecurrent", token)) {
|
||||||
token_exists = 0; /* processed later */
|
token_exists = 0; /* processed later */
|
||||||
|
|
@ -2503,6 +2500,9 @@ int print_spice_element(FILE *fd, int inst)
|
||||||
}
|
}
|
||||||
dbg(1, "print_spice_element(): after translate() result=%s\n", result);
|
dbg(1, "print_spice_element(): after translate() result=%s\n", result);
|
||||||
}
|
}
|
||||||
|
if(strstr(result, "expr(") ) {
|
||||||
|
result = eval_expr(result);
|
||||||
|
}
|
||||||
if(result) fprintf(fd, "%s", result);
|
if(result) fprintf(fd, "%s", result);
|
||||||
my_free(_ALLOC_ID_, &template);
|
my_free(_ALLOC_ID_, &template);
|
||||||
my_free(_ALLOC_ID_, &format);
|
my_free(_ALLOC_ID_, &format);
|
||||||
|
|
@ -4490,11 +4490,9 @@ const char *translate(int inst, const char* s)
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if(strstr(value1, "expr(") == value1) {
|
if(strstr(value1, "expr(") == value1) {
|
||||||
char *ptr = strrchr(value1 + 5, ')');
|
|
||||||
dbg(1, "translate(): expr():%s\n", value1);
|
dbg(1, "translate(): expr():%s\n", value1);
|
||||||
*ptr = '\0';
|
|
||||||
my_strdup2(_ALLOC_ID_, &value1, eval_expr(
|
my_strdup2(_ALLOC_ID_, &value1, eval_expr(
|
||||||
translate3(value1 + 5, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
|
translate3(value1, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
|
||||||
}
|
}
|
||||||
tmp=strlen(value1);
|
tmp=strlen(value1);
|
||||||
STR_ALLOC(&result, tmp + result_pos, &size);
|
STR_ALLOC(&result, tmp + result_pos, &size);
|
||||||
|
|
@ -4521,12 +4519,10 @@ const char *translate(int inst, const char* s)
|
||||||
* can be calculated */
|
* can be calculated */
|
||||||
my_strdup2(_ALLOC_ID_, &translated_tok, spice_get_node(tcl_hook2(result)));
|
my_strdup2(_ALLOC_ID_, &translated_tok, spice_get_node(tcl_hook2(result)));
|
||||||
|
|
||||||
if(strstr(translated_tok, "expr(") == translated_tok) {
|
if(strstr(translated_tok, "expr(")) {
|
||||||
char *ptr = strrchr(translated_tok + 5, ')');
|
|
||||||
dbg(1, "translate(): expr():%s\n", translated_tok);
|
dbg(1, "translate(): expr():%s\n", translated_tok);
|
||||||
*ptr = '\0';
|
|
||||||
my_strdup2(_ALLOC_ID_, &translated_tok, eval_expr(
|
my_strdup2(_ALLOC_ID_, &translated_tok, eval_expr(
|
||||||
translate3(translated_tok + 5, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
|
translate3(translated_tok, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return translated_tok;
|
return translated_tok;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue