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 char *ret = NULL;
|
||||
|
||||
static int dbglev = 1;
|
||||
|
||||
/* Data type for links in the chain of functions. */
|
||||
struct symrec
|
||||
{
|
||||
|
|
@ -29,13 +31,14 @@ static int kklex();
|
|||
static void kkerror(char *s);
|
||||
static double toint(double x);
|
||||
static void get_expr(double x);
|
||||
static void get_char(int c);
|
||||
|
||||
struct fn
|
||||
{
|
||||
char *fname;
|
||||
double (*fnct)();
|
||||
};
|
||||
|
||||
static int lex_state = 0;
|
||||
struct fn fn_array[]
|
||||
= {
|
||||
{"int" , toint},
|
||||
|
|
@ -54,11 +57,14 @@ struct fn fn_array[]
|
|||
|
||||
%define api.prefix {kk}
|
||||
%union {
|
||||
int c;
|
||||
double val; /* For returning numbers. */
|
||||
symrec *tptr; /* For returning symbol-table pointers */
|
||||
}
|
||||
|
||||
%token STREND 0
|
||||
%token <c> CHAR
|
||||
%token EXPR /* expr( */
|
||||
%token <val> NUM /* Simple double precision number */
|
||||
%token <tptr> FNCT /* Variable and Function */
|
||||
%type <val> exp
|
||||
|
|
@ -70,29 +76,45 @@ symrec *tptr; /* For returning symbol-table pointers */
|
|||
|
||||
/* Grammar follows */
|
||||
%%
|
||||
|
||||
line:
|
||||
| exp STREND {get_expr($1);}
|
||||
| '\'' exp '\'' STREND {get_expr($2);}
|
||||
input:
|
||||
| input line
|
||||
;
|
||||
|
||||
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;}
|
||||
line:
|
||||
CHAR {get_char($1);}
|
||||
| EXPR exp ')' {get_expr($2);lex_state = 0;}
|
||||
| EXPR '\'' exp '\'' ')' {get_expr($3);lex_state = 0;}
|
||||
| EXPR exp error
|
||||
;
|
||||
|
||||
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_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)
|
||||
{
|
||||
char xx[100];
|
||||
dbg(dbglev,"get_expr(): x=%g\n", x);
|
||||
my_snprintf(xx, S(xx), "%.15g", x);
|
||||
my_mstrcat(_ALLOC_ID_, &ret, xx, NULL);
|
||||
strptr = str;
|
||||
|
|
@ -104,10 +126,39 @@ static double toint(double 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 */
|
||||
{
|
||||
/* printf("error: |%s|\n\n |%s|\n", s, strptr); */
|
||||
my_mstrcat(_ALLOC_ID_, &ret, strptr, NULL);
|
||||
char *ss = 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)
|
||||
|
|
@ -155,6 +206,23 @@ static int kklex()
|
|||
int c;
|
||||
|
||||
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. */
|
||||
while ((c = *str++) == ' ' || c == '\t' || c == '\n');
|
||||
if (c == 0) {
|
||||
|
|
@ -171,7 +239,7 @@ static int kklex()
|
|||
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
|
||||
kklval.val = atof_spice(s);
|
||||
str += rd;
|
||||
/* printf("yylex: NUM: %s\n", s); */
|
||||
dbg(dbglev, "lex(): NUM: %s\n", s);
|
||||
return NUM;
|
||||
}
|
||||
/* Char starts an identifier => read the name. */
|
||||
|
|
@ -192,7 +260,7 @@ static int kklex()
|
|||
symbuf[i] = '\0';
|
||||
s = getsym (symbuf);
|
||||
kklval.tptr = s;
|
||||
/* printf("yylex: FNCT=%s\n", symbuf); */
|
||||
dbg(dbglev, "ylex: FNCT=%s\n", symbuf);
|
||||
return FNCT;
|
||||
}
|
||||
/* Any other character is a token by itself. */
|
||||
|
|
@ -201,6 +269,7 @@ static int kklex()
|
|||
|
||||
char *eval_expr(const char *s)
|
||||
{
|
||||
lex_state = 0;
|
||||
if(ret) my_free(_ALLOC_ID_, &ret);
|
||||
strptr = str = s;
|
||||
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);
|
||||
token_exists = xctx->tok_size;
|
||||
|
||||
if(strstr(value, "expr(") == value) {
|
||||
char *ptr;
|
||||
my_strdup(_ALLOC_ID_, &val, value);
|
||||
ptr = strrchr(val + 5, ')');
|
||||
*ptr = '\0';
|
||||
value = eval_expr(translate3(val + 5, 1, xctx->inst[inst].prop_ptr, template, NULL));
|
||||
if(strstr(value, "expr(") ) {
|
||||
my_strdup2(_ALLOC_ID_, &val, value);
|
||||
value = eval_expr(translate3(val, 1, xctx->inst[inst].prop_ptr, template, NULL));
|
||||
}
|
||||
if(!strcmp("@savecurrent", token)) {
|
||||
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);
|
||||
}
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
}
|
||||
if(result) fprintf(fd, "%s", result);
|
||||
my_free(_ALLOC_ID_, &template);
|
||||
my_free(_ALLOC_ID_, &format);
|
||||
|
|
@ -4490,11 +4490,9 @@ const char *translate(int inst, const char* s)
|
|||
i--;
|
||||
}
|
||||
if(strstr(value1, "expr(") == value1) {
|
||||
char *ptr = strrchr(value1 + 5, ')');
|
||||
dbg(1, "translate(): expr():%s\n", value1);
|
||||
*ptr = '\0';
|
||||
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);
|
||||
STR_ALLOC(&result, tmp + result_pos, &size);
|
||||
|
|
@ -4521,12 +4519,10 @@ const char *translate(int inst, const char* s)
|
|||
* can be calculated */
|
||||
my_strdup2(_ALLOC_ID_, &translated_tok, spice_get_node(tcl_hook2(result)));
|
||||
|
||||
if(strstr(translated_tok, "expr(") == translated_tok) {
|
||||
char *ptr = strrchr(translated_tok + 5, ')');
|
||||
if(strstr(translated_tok, "expr(")) {
|
||||
dbg(1, "translate(): expr():%s\n", translated_tok);
|
||||
*ptr = '\0';
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue