Jspice3
inpptree.c File Reference
#include "spice.h"
#include "inpdefs.h"
#include "iferrmsg.h"
#include "misc.h"
Include dependency graph for inpptree.c:

Go to the source code of this file.

Data Structures

struct  constant
 

Macros

#define P_ALLOC   0
 
#define P_CLEAR   1
 
#define P_RESET   2
 
#define issep(c)
 
#define G   1 /* Greater than. */
 
#define L   2 /* Less than. */
 
#define E   3 /* Equal. */
 
#define R   4 /* Error. */
 

Functions

static void PTalias ()
 
static INPparseNodePTdifferentiate ()
 
static INPparseNodecopy_node ()
 
static INPparseNodemkcon ()
 
static INPparseNodemkb ()
 
static INPparseNodemkf ()
 
static int PTcheck ()
 
static INPparseNodePTparse ()
 
static INPparseNodemakepnode ()
 
static INPparseNodemkbnode ()
 
static INPparseNodemkfnode ()
 
static INPparseNodemknnode ()
 
static INPparseNodemksnode ()
 
static PTelementPTlexer ()
 
static char * get_stringvar ()
 
static int tran_hack ()
 
static int is_tranfunc ()
 
static INPparseNodeallocate_pnode ()
 
static int pt_const ()
 
static int pt_var ()
 
static int pt_parm ()
 
static int pt_fcn ()
 
static int pt_table ()
 
static int pt_tran ()
 
static int pt_op ()
 
void INPgetTree (char **line, INPparseTree **pt, GENERIC *ckt, INPtables *tab)
 
static void PTalias (char **line)
 
static INPparseNodePTdifferentiate (INPparseNode *p, int varnum)
 
static INPparseNodecopy_node (INPparseNode *p)
 
static INPparseNodemkcon (double value)
 
static INPparseNodemkb (int type, INPparseNode *left, INPparseNode *right)
 
static INPparseNodemkf (int type, INPparseNode *arg)
 
static int PTcheck (INPparseNode *p)
 
static INPparseNodePTparse (char **line)
 
static INPparseNodemakepnode (PTelement *elem)
 
static INPparseNodemkbnode (int opnum, INPparseNode *arg1, INPparseNode *arg2)
 
static INPparseNodemkfnode (char *fname, INPparseNode *arg)
 
static INPparseNodemknnode (double number)
 
static INPparseNodemksnode (char *string)
 
static PTelementPTlexer (char **line)
 
static char * get_stringvar (char **s, char *specials)
 
static int tran_hack (char *name, char *str)
 
static int is_tranfunc (char *s, INPparseNode *p)
 
static INPparseNodeallocate_pnode (int mode)
 
static int pt_const (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_var (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_parm (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_fcn (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_table (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_tran (INPparseNode *tree, double *res, double *vals, double *parms)
 
static int pt_op (INPparseNode *tree, double *res, double *vals, double *parms)
 
static void printTree ()
 
void INPptPrint (char *str, IFparseTree *ptree)
 
static void printTree (INPparseNode *pt)
 

Variables

static IFvaluevalues = NULL
 
static int * types
 
static int numvalues
 
static GENERICcircuit
 
static INPtablestables
 
IFsimulatorft_sim
 
static struct constant constants []
 
static char prectable [11][11]
 

Macro Definition Documentation

#define E   3 /* Equal. */

Definition at line 719 of file inpptree.c.

#define G   1 /* Greater than. */

Definition at line 717 of file inpptree.c.

#define issep (   c)
Value:
((c)==' '||(c)=='\t'||(c)=='='||(c)=='('||(c)==')'||\
(c)==','||(c)=='-'||(c)=='+'||(c)=='*'||(c)=='/'||(c)=='^')
static double c
Definition: vectors.c:16
Definition: cddefs.h:177

Definition at line 91 of file inpptree.c.

#define L   2 /* Less than. */

Definition at line 718 of file inpptree.c.

#define P_ALLOC   0

Definition at line 75 of file inpptree.c.

#define P_CLEAR   1

Definition at line 76 of file inpptree.c.

#define P_RESET   2

Definition at line 77 of file inpptree.c.

#define R   4 /* Error. */

Definition at line 720 of file inpptree.c.

Function Documentation

static INPparseNode* allocate_pnode ( )
static
static INPparseNode* allocate_pnode ( int  mode)
static

Definition at line 1405 of file inpptree.c.

1408 {
1409  static nodes, size;
1410  static INPparseNode **pnodes;
1411  int i;
1412 
1413  if (mode == P_ALLOC) {
1414  nodes++;
1415  if (nodes > size) {
1416  size += 10;
1417  if (pnodes)
1418  pnodes = (INPparseNode**)
1419  trealloc((char*)pnodes,size * sizeof(INPparseNode*));
1420  else
1421  pnodes = (INPparseNode**)
1422  tmalloc(size * sizeof(INPparseNode*));
1423  }
1424  pnodes[nodes-1] = alloc(INPparseNode);
1425  return (pnodes[nodes-1]);
1426  }
1427  if (mode == P_CLEAR) {
1428  for (i = 0; i < nodes; i++) {
1429  if (pnodes[i]->type == PT_PLACEHOLDER) continue;
1430  if (pnodes[i]->type == PT_TFUNC) {
1431  if (pnodes[i]->trancoeffs)
1432  txfree((char*)pnodes[i]->trancoeffs);
1433  if (pnodes[i]->tranparms)
1434  txfree((char*)pnodes[i]->tranparms);
1435  if (pnodes[i]->trancache)
1436  txfree((char*)pnodes[i]->trancache);
1437  }
1438  txfree((char*)pnodes[i]);
1439  }
1440  }
1441  for (i = 0; i < nodes; i++) {
1442  if (pnodes[i]->type != PT_PLACEHOLDER) continue;
1443  txfree((char*)pnodes[i]);
1444  }
1445  txfree((char*)pnodes);
1446  pnodes = NULL;
1447  size = 0;
1448  nodes = 0;
1449  return (NULL);
1450 }
#define PT_PLACEHOLDER
Definition: inpptree.h:68
#define P_CLEAR
Definition: inpptree.c:76
#define P_ALLOC
Definition: inpptree.c:75
#define alloc(type)
Definition: cdmacs.h:21
char * tmalloc()
#define PT_TFUNC
Definition: inpptree.h:79
void txfree()
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
char * trealloc()
static INPparseNode* copy_node ( )
static
static INPparseNode* copy_node ( INPparseNode p)
static

Definition at line 501 of file inpptree.c.

503 {
504  INPparseNode *new;
505  int num;
506 
507  if (p == NULL)
508  return (NULL);
509 
510  if (p->new_deriv) {
511  p->new_deriv = 0;
512  p->left = copy_node(p->left);
513  p->right = copy_node(p->right);
514  return (p);
515  }
516 
517  new = allocate_pnode(P_ALLOC);
518 
519  *new = *p;
520  if (new->type == PT_TFUNC) {
521  new->trancoeffs =
522  (double*)tmalloc(new->numtrancoeffs*sizeof(double));
523  memcpy(new->trancoeffs,p->trancoeffs,new->numtrancoeffs*sizeof(double));
524  if (new->funcnum == PTF_tPULSE) {
525  new->trancache = (double*)tmalloc(2*sizeof(double));
526  }
527  else if (new->funcnum == PTF_tPWL) {
528  num = new->numtrancoeffs/2 - 1;
529  new->trancache = (double*)tmalloc(num*sizeof(double));
530  memcpy(new->trancache,p->trancache,num*sizeof(double));
531  }
532  }
533  new->left = copy_node(p->left);
534  new->right = copy_node(p->right);
535  return (new);
536 }
#define PTF_tPULSE
Definition: inpptree.h:106
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
struct INPparseNode * right
Definition: inpptree.h:48
char * tmalloc()
double * trancoeffs
Definition: inpptree.h:55
#define PT_TFUNC
Definition: inpptree.h:79
struct INPparseNode * left
Definition: inpptree.h:47
#define NULL
Definition: spdefs.h:121
static INPparseNode * copy_node()
#define PTF_tPWL
Definition: inpptree.h:107
double * trancache
Definition: inpptree.h:57
int new_deriv
Definition: inpptree.h:60
static char* get_stringvar ( )
static
static char* get_stringvar ( char **  s,
char *  specials 
)
static

Definition at line 1233 of file inpptree.c.

1236 {
1237  char *t;
1238  char *buf;
1239  int i, j;
1240 
1241  for (t = *s, i = 0; *t; t++, i++) {
1242  if (strchr(specials,*t))
1243  break;
1244  }
1245  buf = tmalloc(i+1);
1246  memcpy(buf,*s,i);
1247  buf[i] = '\0';
1248 
1249 
1250  for (j = 0; PTtFuncs[j].name; j++)
1251  if (!strcmp(PTtFuncs[j].name, buf))
1252  break;
1253 
1254  if (tran_hack(PTtFuncs[j].name,t)) {
1255  /* found a match, copy parameters and () */
1256  for ( ; *t; t++, i++) {
1257  if (*t == ')') {
1258  t++;
1259  i++;
1260  break;
1261  }
1262  }
1263  txfree(buf);
1264  buf = tmalloc(i+1);
1265  memcpy(buf,*s,i);
1266  buf[i] = '\0';
1267  }
1268  *s = t;
1269 
1270  /* set to lower case */
1271  for (t = buf; *t; t++)
1272  if (isupper(*t)) *t = tolower(*t);
1273 
1274  return (buf);
1275 }
static char buf[MAXPROMPT]
Definition: arg.c:18
char * name
Definition: inpptree.h:151
struct sPTfunc PTtFuncs[]
Definition: ptfuncs.c:132
Definition: cddefs.h:119
static int tran_hack()
char * tmalloc()
void txfree()
Definition: cddefs.h:192
void INPgetTree ( char **  line,
INPparseTree **  pt,
GENERIC ckt,
INPtables tab 
)

Definition at line 96 of file inpptree.c.

106 {
107  INPparseNode *p;
108  int i;
109  char *tl, *tl0;
110 
111  values = NULL;
112  types = NULL;
113  numvalues = 0;
114 
115  circuit = ckt;
116  tables = tab;
117 
118  tl = *line;
119  PTalias(&tl);
120  tl0 = tl;
121  p = PTparse(&tl);
122  *line += strlen(*line) - strlen(tl);
123  *--tl = '\0';
124 
125  if (!p || !PTcheck(p)) {
126  *pt = NULL;
127  (void)allocate_pnode(P_CLEAR);
128  txfree(tl0);
129  return;
130  }
131 
132  (*pt) = alloc(INPparseTree);
133 
134  (*pt)->p.numVars = numvalues;
135  (*pt)->p.varTypes = types;
136  (*pt)->p.vars = values;
137  (*pt)->p.IFinit = IFinit;
138  (*pt)->p.IFeval = IFeval;
139  (*pt)->p.IFfree = IFfree;
140  (*pt)->p.line = tl0;
141  (*pt)->tree = p;
142 
143  if (numvalues) {
144  (*pt)->derivs = (INPparseNode **)
145  tmalloc(numvalues * sizeof (INPparseNode *));
146 
147  for (i = 0; i < numvalues; i++)
148  (*pt)->derivs[i] = copy_node(PTdifferentiate(p, i));
149  }
150 
151 /*
152 INPptPrint("tree:",*pt);
153 */
154  (void)allocate_pnode(P_RESET);
155  return;
156 }
int IFeval()
void IFfree()
static INPparseNode * PTdifferentiate()
#define P_RESET
Definition: inpptree.c:77
#define P_CLEAR
Definition: inpptree.c:76
FILE * p
Definition: proc2mod.c:48
static IFvalue * values
Definition: inpptree.c:13
#define tab(num)
Definition: front.c:1365
static INPparseNode * allocate_pnode()
static int PTcheck()
static INPtables * tables
Definition: inpptree.c:17
#define alloc(type)
Definition: cdmacs.h:21
char * tmalloc()
int IFinit()
Definition: fteinp.h:14
void txfree()
#define NULL
Definition: spdefs.h:121
static int numvalues
Definition: inpptree.c:15
static GENERIC * circuit
Definition: inpptree.c:16
static INPparseNode * copy_node()
static int * types
Definition: inpptree.c:14
static void PTalias()
static INPparseNode * PTparse()
void INPptPrint ( char *  str,
IFparseTree ptree 
)

Definition at line 1596 of file inpptree.c.

1600 {
1601  int i;
1602 
1603  printf("%s\n\t", str);
1604  printTree(((INPparseTree *) ptree)->tree);
1605  printf("\n");
1606  for (i = 0; i < ptree->numVars; i++) {
1607  printf("d / d v%d : ", i);
1608  printTree(((INPparseTree *) ptree)->derivs[i]);
1609  printf("\n");
1610  }
1611  return;
1612 }
struct INPparseNode ** derivs
Definition: inpptree.h:33
struct INPparseNode * tree
Definition: inpptree.h:32
int numVars
Definition: ifsim.h:159
static void printTree()
static int is_tranfunc ( )
static
static int is_tranfunc ( char *  s,
INPparseNode p 
)
static

Definition at line 1325 of file inpptree.c.

1329 {
1330  int i, num, error;
1331  char *t, *tt;
1332  double tmp, *list;
1333 
1334  /* the tran function string includes parameters enclosed in () */
1335  if (!strchr(s,')'))
1336  return (false); /* can't be a tran function */
1337 
1338  t = strchr(s,'(');
1339  if (t == NULL)
1340  return (false); /* syntax error */
1341 
1342  *t = '\0';
1343  t++;
1344 
1345  /* get rid of intermediate space */
1346  tt = s;
1347  while (*tt && !isspace(*tt)) tt++;
1348  *tt = '\0';
1349 
1350  for (i = 0; PTtFuncs[i].name; i++)
1351  if (!strcmp(PTtFuncs[i].name, s))
1352  break;
1353 
1354  if (!PTtFuncs[i].name) {
1355  fprintf(stderr, "Internal Error: no such tran function '%s'", s);
1356  return (false);
1357  }
1358  if (p) {
1359  p->type = PT_TFUNC;
1360 
1361  num = 0;
1362  list = (double *)tmalloc(sizeof(double));
1363  tmp = INPevaluate(&t,&error,1);
1364  while (error == 0) {
1365  num++;
1366  list = (double *)
1367  trealloc((char *)list,num*sizeof(double));
1368  *(list+num-1) = tmp;
1369  tmp = INPevaluate(&t,&error,1);
1370  }
1371  p->trancoeffs = list;
1372  p->numtrancoeffs = num;
1373  p->funcname = PTtFuncs[i].name;
1374  p->funcnum = PTtFuncs[i].number;
1375  p->function = PTtFuncs[i].funcptr;
1376  p->evfunc = pt_tran;
1377  if (p->funcnum != PTF_tPWL)
1378  p->tranparms = (double*)tmalloc(8*sizeof(double));
1379 
1380  if (p->funcnum == PTF_tPULSE)
1381  p->trancache = (double*)tmalloc(2*sizeof(double));
1382  else if (p->funcnum == PTF_tPWL) {
1383  num = p->numtrancoeffs/2 - 1;
1384  if (num) {
1385  p->trancache = (double*)tmalloc(num*sizeof(double));
1386  for (i = 0; i < num; i++) {
1387  p->trancache[i] =
1388  (*(p->trancoeffs+2*i+3) - *(p->trancoeffs+2*i+1))/
1389  (*(p->trancoeffs+2*i+2) - *(p->trancoeffs+2*i));
1390  }
1391  }
1392  else {
1393  p->trancache = (double*)tmalloc(sizeof(double));
1394  p->trancache[0] = 0;
1395  }
1396  }
1397  }
1398  return (true);
1399 }
double(* funcptr)()
Definition: inpptree.h:153
#define PTF_tPULSE
Definition: inpptree.h:106
char * name
Definition: inpptree.h:151
struct sPTfunc PTtFuncs[]
Definition: ptfuncs.c:132
Definition: cddefs.h:119
int number
Definition: inpptree.h:152
Definition: xforms.c:16
double INPevaluate()
int(* evfunc)()
Definition: inpptree.h:53
int funcnum
Definition: inpptree.h:52
static int pt_tran()
char * tmalloc()
double * trancoeffs
Definition: inpptree.h:55
#define PT_TFUNC
Definition: inpptree.h:79
double(* function)()
Definition: inpptree.h:54
#define NULL
Definition: spdefs.h:121
double * tranparms
Definition: inpptree.h:56
#define PTF_tPWL
Definition: inpptree.h:107
Definition: dir.c:53
int numtrancoeffs
Definition: inpptree.h:58
double * trancache
Definition: inpptree.h:57
Definition: cddefs.h:192
char * trealloc()
char * funcname
Definition: inpptree.h:51
static INPparseNode* makepnode ( )
static
static INPparseNode* makepnode ( PTelement elem)
static

Definition at line 855 of file inpptree.c.

862 {
863  if (elem->token != TOK_VALUE)
864  return (NULL);
865 
866  switch (elem->type) {
867  case TYP_STRING:
868  return (mksnode(elem->value.string));
869 
870  case TYP_NUM:
871  return (mknnode(elem->value.real));
872 
873  case TYP_PNODE:
874  return (elem->value.pnode);
875 
876  default:
877  fprintf(stderr, "Internal Error: bad token type\n");
878  return (NULL);
879  }
880 }
union PTelement::@15 value
#define TOK_VALUE
Definition: inpptree.h:127
static INPparseNode * mknnode()
char * string
Definition: inpptree.h:142
#define TYP_PNODE
Definition: inpptree.h:134
INPparseNode * pnode
Definition: inpptree.h:144
double real
Definition: inpptree.h:143
#define NULL
Definition: spdefs.h:121
#define TYP_STRING
Definition: inpptree.h:133
static INPparseNode * mksnode()
#define TYP_NUM
Definition: inpptree.h:132
int type
Definition: inpptree.h:140
int token
Definition: inpptree.h:139
static INPparseNode* mkb ( )
static
static INPparseNode* mkb ( int  type,
INPparseNode left,
INPparseNode right 
)
static

Definition at line 556 of file inpptree.c.

560 {
561  INPparseNode *p;
562  int i;
563 
564  if ((right->type == PT_CONSTANT) && (left->type == PT_CONSTANT)) {
565  switch (type) {
566  case PT_TIMES:
567  return (mkcon(left->constant * right->constant));
568 
569  case PT_DIVIDE:
570  return (mkcon(left->constant / right->constant));
571 
572  case PT_PLUS:
573  return (mkcon(left->constant + right->constant));
574 
575  case PT_MINUS:
576  return (mkcon(left->constant - right->constant));
577 
578  case PT_POWER:
579  return (mkcon(pow(left->constant, right->constant)));
580  }
581  }
582  switch (type) {
583  case PT_TIMES:
584  if ((left->type == PT_CONSTANT) && (left->constant == 0))
585  return (left);
586  else if ((right->type == PT_CONSTANT) && (right->constant == 0))
587  return (right);
588  else if ((left->type == PT_CONSTANT) && (left->constant == 1))
589  return (right);
590  else if ((right->type == PT_CONSTANT) && (right->constant == 1))
591  return (left);
592  break;
593 
594  case PT_DIVIDE:
595  if ((left->type == PT_CONSTANT) && (left->constant == 0))
596  return (left);
597  else if ((right->type == PT_CONSTANT) && (right->constant == 1))
598  return (left);
599  break;
600 
601  case PT_PLUS:
602  if ((left->type == PT_CONSTANT) && (left->constant == 0))
603  return (right);
604  else if ((right->type == PT_CONSTANT) && (right->constant == 0))
605  return (left);
606  break;
607 
608  case PT_MINUS:
609  if ((right->type == PT_CONSTANT) && (right->constant == 0))
610  return (left);
611  else if ((left->type == PT_CONSTANT) && (left->constant == 0))
612  return (mkf(PTF_UMINUS, right));
613  break;
614 
615  case PT_POWER:
616  if (right->type == PT_CONSTANT) {
617  if (right->constant == 0)
618  return (mkcon(1.0));
619  else if (right->constant == 1)
620  return (left);
621  }
622  break;
623  }
624 
625  for (i = 0; PTops[i].number != PT_PLACEHOLDER; i++)
626  if (PTops[i].number == type)
627  break;
628  if (PTops[i].number == PT_PLACEHOLDER) {
629  fprintf(stderr, "Internal Error: bad type %d\n", type);
630  return (NULL);
631  }
632  p = allocate_pnode(P_ALLOC);
633  p->new_deriv = 1;
634  p->type = type;
635  p->left = left;
636  p->right = right;
637  p->function = PTops[i].funcptr;
638  p->funcname = PTops[i].name;
639  p->evfunc = pt_op;
640 
641  return (p);
642 }
#define PT_DIVIDE
Definition: inpptree.h:72
#define PT_PLACEHOLDER
Definition: inpptree.h:68
#define PT_CONSTANT
Definition: inpptree.h:75
char * name
Definition: inpptree.h:160
static INPparseNode * mkcon()
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
struct INPparseNode * right
Definition: inpptree.h:48
double constant
Definition: inpptree.h:49
double(* function)()
Definition: inpptree.h:54
struct INPparseNode * left
Definition: inpptree.h:47
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
#define PT_PLUS
Definition: inpptree.h:69
#define PT_MINUS
Definition: inpptree.h:70
static INPparseNode * mkf()
#define PTF_UMINUS
Definition: inpptree.h:100
double(* funcptr)()
Definition: inpptree.h:161
struct sPTop PTops[]
Definition: ptfuncs.c:97
#define PT_POWER
Definition: inpptree.h:73
int new_deriv
Definition: inpptree.h:60
static int pt_op()
#define PT_TIMES
Definition: inpptree.h:71
int number
Definition: inpptree.h:159
char * funcname
Definition: inpptree.h:51
static INPparseNode* mkbnode ( )
static
static INPparseNode* mkbnode ( int  opnum,
INPparseNode arg1,
INPparseNode arg2 
)
static

Definition at line 884 of file inpptree.c.

889 {
890  INPparseNode *p;
891  int i;
892 
893  for (i = 0; PTops[i].name != PT_PLACEHOLDER; i++)
894  if (PTops[i].number == opnum)
895  break;
896 
897  if (PTops[i].number == PT_PLACEHOLDER) {
898  fprintf(stderr, "Internal Error: no such op num %d\n", opnum);
899  return (NULL);
900  }
901  p = allocate_pnode(P_ALLOC);
902 
903  p->type = opnum;
904  p->funcname = PTops[i].name;
905  p->function = PTops[i].funcptr;
906  p->evfunc = pt_op;
907  p->left = arg1;
908  p->right = arg2;
909 
910  return (p);
911 }
#define PT_PLACEHOLDER
Definition: inpptree.h:68
char * name
Definition: inpptree.h:160
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
struct INPparseNode * right
Definition: inpptree.h:48
double(* function)()
Definition: inpptree.h:54
struct INPparseNode * left
Definition: inpptree.h:47
#define NULL
Definition: spdefs.h:121
double(* funcptr)()
Definition: inpptree.h:161
struct sPTop PTops[]
Definition: ptfuncs.c:97
static int pt_op()
char * funcname
Definition: inpptree.h:51
static INPparseNode* mkcon ( )
static
static INPparseNode* mkcon ( double  value)
static

Definition at line 540 of file inpptree.c.

543 {
545 
546  p->type = PT_CONSTANT;
547  p->constant = value;
548  p->evfunc = pt_const;
549  p->new_deriv = 1;
550 
551  return (p);
552 }
#define PT_CONSTANT
Definition: inpptree.h:75
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
Definition: cddefs.h:215
double constant
Definition: inpptree.h:49
static int pt_const()
int new_deriv
Definition: inpptree.h:60
static INPparseNode* mkf ( )
static
static INPparseNode* mkf ( int  type,
INPparseNode arg 
)
static

Definition at line 646 of file inpptree.c.

650 {
651  INPparseNode *p;
652  int i;
653  double constval;
654 
655  for (i = 0; PTfuncs[i].name; i++)
656  if (PTfuncs[i].number == type)
657  break;
658  if (!PTfuncs[i].name) {
659  fprintf(stderr, "Internal Error: bad type %d\n", type);
660  return (NULL);
661  }
662 
663  if (arg->type == PT_CONSTANT) {
664  constval = ((*PTfuncs[i].funcptr) (arg->constant));
665  return (mkcon(constval));
666  }
667  p = allocate_pnode(P_ALLOC);
668  p->new_deriv = 1;
669  p->type = PT_FUNCTION;
670  p->left = arg;
671  p->funcnum = i;
672  p->function = PTfuncs[i].funcptr;
673  p->funcname = PTfuncs[i].name;
674  p->evfunc = pt_fcn;
675 
676  return (p);
677 }
double(* funcptr)()
Definition: inpptree.h:153
static int pt_fcn()
char * name
Definition: inpptree.h:151
#define PT_FUNCTION
Definition: inpptree.h:74
#define PT_CONSTANT
Definition: inpptree.h:75
static INPparseNode * mkcon()
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
double constant
Definition: inpptree.h:49
int funcnum
Definition: inpptree.h:52
double(* function)()
Definition: inpptree.h:54
struct INPparseNode * left
Definition: inpptree.h:47
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
int new_deriv
Definition: inpptree.h:60
struct sPTfunc PTfuncs[]
Definition: ptfuncs.c:107
char * funcname
Definition: inpptree.h:51
static INPparseNode* mkfnode ( )
static
static INPparseNode* mkfnode ( char *  fname,
INPparseNode arg 
)
static

Definition at line 915 of file inpptree.c.

920 {
921  int i;
922  INPparseNode *p;
923  char *name, *s;
924  IFvalue temp;
925  GENERIC *table;
926 
927  p = allocate_pnode(P_ALLOC);
928 
929  if (!strcmp(fname, "v")) {
930  name = tmalloc(128);
931  if (arg->type == PT_PLACEHOLDER) {
932  strcpy(name, arg->funcname);
933  txfree(arg->funcname);
934  }
935  else if (arg->type == PT_CONSTANT) {
936  (void) sprintf(name, "%d", (int) arg->constant);
937  }
938  else if (arg->type != PT_COMMA) {
939  errMsg = copy("badly formed node voltage");
940  txfree(fname);
941  return (NULL);
942  }
943 
944  if (arg->type == PT_COMMA) {
945  /* Change v(a,b) into v(a) - v(b) */
946  p = mkb(PT_MINUS, mkfnode(copy(fname), arg->left),
947  mkfnode(copy(fname), arg->right));
948  }
949  else {
950  /* printf("getting a node called '%s'\n", name); */
951  INPtermInsert(circuit, &name, tables, &(temp.nValue));
952  for (i = 0; i < numvalues; i++)
953  if ((types[i] == IF_NODE) && (values[i].nValue ==
954  temp.nValue))
955  break;
956  if (i == numvalues) {
957  if (numvalues) {
958  values = (IFvalue *)
959  trealloc((char *) values,
960  (numvalues + 1) * sizeof (IFvalue));
961  types = (int *)
962  trealloc((char *) types,
963  (numvalues + 1) * sizeof (int));
964  }
965  else {
966  values = alloc(IFvalue);
967  types = (int *) tmalloc(sizeof (int));
968  }
969  values[i] = temp;
970  types[i] = IF_NODE;
971  numvalues++;
972  }
973  p->valueIndex = i;
974  p->type = PT_VAR;
975  p->evfunc = pt_var;
976  }
977  }
978  else if (!strcmp(fname, "i")) {
979  name = tmalloc(128);
980  if (arg->type == PT_PLACEHOLDER) {
981  strcpy(name, arg->funcname);
982  txfree(arg->funcname);
983  }
984  else if (arg->type == PT_CONSTANT) {
985  (void) sprintf(name, "%d", (int) arg->constant);
986  }
987  else {
988  errMsg = copy("badly formed branch current");
989  txfree(fname);
990  return (NULL);
991  }
992 /* printf("getting a device called '%s'\n", name); */
993  INPinsert(&name, tables);
994  for (i = 0; i < numvalues; i++)
995  if ((types[i] == IF_INSTANCE) && (values[i].uValue ==
996  temp.uValue))
997  break;
998  if (i == numvalues) {
999  if (numvalues) {
1000  values = (IFvalue *)
1001  trealloc((char *) values,
1002  (numvalues + 1) * sizeof (IFvalue));
1003  types = (int *)
1004  trealloc((char *) types,
1005  (numvalues + 1) * sizeof (int));
1006  }
1007  else {
1008  values = alloc(IFvalue);
1009  types = (int *) tmalloc(sizeof (int));
1010  }
1011  values[i].uValue = (IFuid) name;
1012  types[i] = IF_INSTANCE;
1013  numvalues++;
1014  }
1015  p->valueIndex = i;
1016  p->type = PT_VAR;
1017  p->evfunc = pt_var;
1018  }
1019  else {
1020  for (i = 0; PTfuncs[i].name; i++)
1021  if (!strcmp(PTfuncs[i].name, fname))
1022  break;
1023 
1024  if (!PTfuncs[i].name) {
1025  if (INPtablFind(fname,circuit,&table)) {
1026  errMsg = tmalloc(strlen(fname) + 100);
1027  sprintf(errMsg,"no such function '%s'",fname);
1028  txfree(fname);
1029  return (NULL);
1030  }
1031  p->type = PT_TABLE;
1032  p->left = arg;
1033  p->funcname = fname;
1034  p->funcnum = 0;
1035  p->function = (double(*)()) table;
1036  p->evfunc = pt_table;
1037  return (p);
1038  }
1039 
1040  p->type = PT_FUNCTION;
1041  p->left = arg;
1042  p->funcname = PTfuncs[i].name;
1043  p->funcnum = PTfuncs[i].number;
1044  p->function = PTfuncs[i].funcptr;
1045  p->evfunc = pt_fcn;
1046  }
1047 
1048  txfree(fname);
1049  return (p);
1050 }
double(* funcptr)()
Definition: inpptree.h:153
static int pt_fcn()
char * name
Definition: inpptree.h:151
#define PT_FUNCTION
Definition: inpptree.h:74
#define PT_TABLE
Definition: inpptree.h:80
static struct tab table[512]
int INPtermInsert()
#define PT_PLACEHOLDER
Definition: inpptree.h:68
char * strcpy()
Definition: cddefs.h:119
int number
Definition: inpptree.h:152
#define PT_CONSTANT
Definition: inpptree.h:75
char * errMsg
Definition: main.c:42
FILE * p
Definition: proc2mod.c:48
static IFvalue * values
Definition: inpptree.c:13
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
struct INPparseNode * right
Definition: inpptree.h:48
#define IF_INSTANCE
Definition: ifsim.h:112
static INPtables * tables
Definition: inpptree.c:17
#define alloc(type)
Definition: cdmacs.h:21
char * copy()
double constant
Definition: inpptree.h:49
int funcnum
Definition: inpptree.h:52
int INPinsert()
char * tmalloc()
GENERIC * IFuid
Definition: ifsim.h:72
double(* function)()
Definition: inpptree.h:54
#define PT_VAR
Definition: inpptree.h:76
struct INPparseNode * left
Definition: inpptree.h:47
void txfree()
#define NULL
Definition: spdefs.h:121
#define PT_MINUS
Definition: inpptree.h:70
IFnode nValue
Definition: ifsim.h:237
static int pt_table()
static INPparseNode * mkb()
static INPparseNode * mkfnode()
static int numvalues
Definition: inpptree.c:15
#define PT_COMMA
Definition: inpptree.h:78
static GENERIC * circuit
Definition: inpptree.c:16
int INPtablFind()
static int * types
Definition: inpptree.c:14
static int pt_var()
int valueIndex
Definition: inpptree.h:50
#define IF_NODE
Definition: ifsim.h:110
char * trealloc()
struct sPTfunc PTfuncs[]
Definition: ptfuncs.c:107
char * funcname
Definition: inpptree.h:51
char GENERIC
Definition: ifsim.h:27
IFuid uValue
Definition: ifsim.h:236
static INPparseNode* mknnode ( )
static
static INPparseNode* mknnode ( double  number)
static

Definition at line 1054 of file inpptree.c.

1058 {
1059  struct INPparseNode *p;
1060 
1061  p = allocate_pnode(P_ALLOC);
1062 
1063  p->type = PT_CONSTANT;
1064  p->constant = number;
1065  p->evfunc = pt_const;
1066 
1067  return (p);
1068 }
#define PT_CONSTANT
Definition: inpptree.h:75
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
double constant
Definition: inpptree.h:49
static int pt_const()
static INPparseNode* mksnode ( )
static
static INPparseNode* mksnode ( char *  string)
static

Definition at line 1072 of file inpptree.c.

1076 {
1077  int i, j;
1078 
1079  INPparseNode *p;
1080 
1081  p = allocate_pnode(P_ALLOC);
1082 
1083  /* First check it it is really a tran function */
1084  if (is_tranfunc(string,p)) {
1085  txfree(string);
1086  return (p);
1087  }
1088 
1089  /* Next see if it's a special parameter */
1090  for (i = 0; i < ft_sim->numSpecSigs; i++)
1091  if (!strcmp(ft_sim->specSigs[i], string))
1092  break;
1093  if (i < ft_sim->numSpecSigs) {
1094  p->valueIndex = i;
1095  p->type = PT_PARAM;
1096  p->evfunc = pt_parm;
1097  txfree(string);
1098  return (p);
1099  }
1100 
1101  for (i = 0; constants[i].name; i++)
1102  if (!strcmp(constants[i].name, string))
1103  break;
1104 
1105  if (!constants[i].name) {
1106  /* We'd better save this in case it's part of i(something). */
1107  p->type = PT_PLACEHOLDER;
1108  p->funcname = string;
1109  }
1110  else {
1111  p->type = PT_CONSTANT;
1112  p->constant = constants[i].value;
1113  p->evfunc = pt_const;
1114  txfree(string);
1115  }
1116 
1117  return (p);
1118 }
IFsimulator * ft_sim
Definition: main.c:111
#define PT_PLACEHOLDER
Definition: inpptree.h:68
#define PT_CONSTANT
Definition: inpptree.h:75
FILE * p
Definition: proc2mod.c:48
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
int(* evfunc)()
Definition: inpptree.h:53
double constant
Definition: inpptree.h:49
static int pt_const()
int numSpecSigs
Definition: ifsim.h:469
void txfree()
#define PT_PARAM
Definition: inpptree.h:77
char ** specSigs
Definition: ifsim.h:470
char * name
Definition: inpptree.c:83
double value
Definition: inpptree.c:84
int valueIndex
Definition: inpptree.h:50
static int pt_parm()
static struct constant constants[]
static int is_tranfunc()
char * funcname
Definition: inpptree.h:51
static void printTree ( )
static
static void printTree ( INPparseNode pt)
static

Definition at line 1616 of file inpptree.c.

1619 {
1620  int i;
1621 
1622  switch (pt->type) {
1623  case PT_CONSTANT:
1624  printf("%g", pt->constant);
1625  break;
1626 
1627  case PT_VAR:
1628  printf("v%d", pt->valueIndex);
1629  break;
1630 
1631  case PT_PARAM:
1632  printf("%s", ft_sim->specSigs[pt->valueIndex]);
1633  break;
1634 
1635  case PT_PLUS:
1636  printf("(");
1637  printTree(pt->left);
1638  printf(") + (");
1639  printTree(pt->right);
1640  printf(")");
1641  break;
1642 
1643  case PT_MINUS:
1644  printf("(");
1645  printTree(pt->left);
1646  printf(") - (");
1647  printTree(pt->right);
1648  printf(")");
1649  break;
1650 
1651  case PT_TIMES:
1652  printf("(");
1653  printTree(pt->left);
1654  printf(") * (");
1655  printTree(pt->right);
1656  printf(")");
1657  break;
1658 
1659  case PT_DIVIDE:
1660  printf("(");
1661  printTree(pt->left);
1662  printf(") / (");
1663  printTree(pt->right);
1664  printf(")");
1665  break;
1666 
1667  case PT_POWER:
1668  printf("(");
1669  printTree(pt->left);
1670  printf(") ^ (");
1671  printTree(pt->right);
1672  printf(")");
1673  break;
1674 
1675  case PT_FUNCTION:
1676  printf("%s (", pt->funcname);
1677  printTree(pt->left);
1678  printf(")");
1679  break;
1680 
1681  case PT_TFUNC:
1682  printf("%s (", pt->funcname);
1683  for (i = 0; i < pt->numtrancoeffs; i++)
1684  printf(" %g",pt->trancoeffs[i]);
1685  printf(" )");
1686  break;
1687 
1688  default:
1689  printf("oops");
1690  break;
1691  }
1692  return;
1693 }
IFsimulator * ft_sim
Definition: main.c:111
#define PT_FUNCTION
Definition: inpptree.h:74
#define PT_DIVIDE
Definition: inpptree.h:72
#define PT_CONSTANT
Definition: inpptree.h:75
struct INPparseNode * right
Definition: inpptree.h:48
double constant
Definition: inpptree.h:49
double * trancoeffs
Definition: inpptree.h:55
#define PT_TFUNC
Definition: inpptree.h:79
#define PT_VAR
Definition: inpptree.h:76
struct INPparseNode * left
Definition: inpptree.h:47
#define PT_PLUS
Definition: inpptree.h:69
#define PT_MINUS
Definition: inpptree.h:70
#define PT_PARAM
Definition: inpptree.h:77
char ** specSigs
Definition: ifsim.h:470
#define PT_POWER
Definition: inpptree.h:73
int valueIndex
Definition: inpptree.h:50
static void printTree()
int numtrancoeffs
Definition: inpptree.h:58
#define PT_TIMES
Definition: inpptree.h:71
char * funcname
Definition: inpptree.h:51
static int pt_const ( )
static
static int pt_const ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1456 of file inpptree.c.

1462 {
1463  *res = tree->constant;
1464  return (OK);
1465 }
double constant
Definition: inpptree.h:49
#define OK
Definition: iferrmsg.h:17
static int pt_fcn ( )
static
static int pt_fcn ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1495 of file inpptree.c.

1501 {
1502  int err;
1503  double r1;
1504 
1505  err = (*tree->left->evfunc)(tree->left, &r1, vals, parms);
1506  if (err != OK)
1507  return (err);
1508  *res = (*tree->function)(r1);
1509  /*
1510  if (*res == HUGE) {
1511  fprintf(stderr, "Error: %lg out of range for %s\n",
1512  r1, tree->funcname);
1513  return (E_PARMVAL);
1514  }
1515  */
1516  return (OK);
1517 }
int(* evfunc)()
Definition: inpptree.h:53
#define OK
Definition: iferrmsg.h:17
double(* function)()
Definition: inpptree.h:54
struct INPparseNode * left
Definition: inpptree.h:47
Definition: mfb.h:383
static int pt_op ( )
static
static int pt_op ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1558 of file inpptree.c.

1564 {
1565  int err;
1566  double r1, r2;
1567 
1568  err = (*tree->left->evfunc)(tree->left, &r1, vals, parms);
1569  if (err != OK)
1570  return (err);
1571  err = (*tree->right->evfunc)(tree->right, &r2, vals, parms);
1572  if (err != OK)
1573  return (err);
1574  *res = (*tree->function)(r1, r2);
1575  /*
1576  if (*res == HUGE) {
1577  fprintf(stderr, "Error: %lg, %lg out of range for %s\n",
1578  r1, r2, tree->funcname);
1579  return (E_PARMVAL);
1580  }
1581  */
1582  return (OK);
1583 }
int(* evfunc)()
Definition: inpptree.h:53
struct INPparseNode * right
Definition: inpptree.h:48
#define OK
Definition: iferrmsg.h:17
double(* function)()
Definition: inpptree.h:54
struct INPparseNode * left
Definition: inpptree.h:47
Definition: mfb.h:383
static int pt_parm ( )
static
static int pt_parm ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1482 of file inpptree.c.

1488 {
1489  *res = parms[tree->valueIndex];
1490  return (OK);
1491 }
#define OK
Definition: iferrmsg.h:17
int valueIndex
Definition: inpptree.h:50
static int pt_table ( )
static
static int pt_table ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1521 of file inpptree.c.

1527 {
1528  int err;
1529  double r1;
1530 
1531  err = (*tree->left->evfunc)(tree->left, &r1, vals, parms);
1532  if (err != OK)
1533  return (err);
1534 
1535  if (tree->funcnum == 0)
1536  *res = INPtablEval((GENERIC*)tree->function,r1);
1537  else
1538  *res = INPtablEvalDeriv((GENERIC*)tree->function,r1);
1539 
1540  return (OK);
1541 }
double INPtablEvalDeriv(GENERIC *tab, double x)
Definition: inptabpa.c:441
int(* evfunc)()
Definition: inpptree.h:53
int funcnum
Definition: inpptree.h:52
#define OK
Definition: iferrmsg.h:17
double(* function)()
Definition: inpptree.h:54
double INPtablEval()
struct INPparseNode * left
Definition: inpptree.h:47
Definition: mfb.h:383
char GENERIC
Definition: ifsim.h:27
static int pt_tran ( )
static
static int pt_tran ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1545 of file inpptree.c.

1551 {
1552  *res = (*tree->function)(tree,parms);
1553  return (OK);
1554 }
#define OK
Definition: iferrmsg.h:17
double(* function)()
Definition: inpptree.h:54
static int pt_var ( )
static
static int pt_var ( INPparseNode tree,
double *  res,
double *  vals,
double *  parms 
)
static

Definition at line 1469 of file inpptree.c.

1475 {
1476  *res = vals[tree->valueIndex];
1477  return (OK);
1478 }
#define OK
Definition: iferrmsg.h:17
int valueIndex
Definition: inpptree.h:50
static void PTalias ( )
static
static void PTalias ( char **  line)
static

Definition at line 160 of file inpptree.c.

164 {
165  char *s, *buf, *tok, c, cc;
166  char *newline, *nl, *tl;
167  int len, olen, count = 0;
168  IFvalue *v;
169 
170  tl = *line;
171  newline = copy(tl);
172  nl = newline;
173  len = strlen(newline);
174 
175  while (*tl) {
176 
177  while (*tl && issep(*tl)) {
178  if ((olen = (nl - newline)) >= len) {
179  len += 16;
180  newline = trealloc(newline,len+1);
181  nl = newline + olen;
182  }
183  *nl++ = *tl++;
184  }
185 
186  if (!*tl)
187  break;
188 
189  tok = tl;
190 
191  while (*tl && !issep(*tl))
192  tl++;
193 
194  c = *tl;
195  *tl = '\0';
196 
197  buf = NULL;
198 
199  /* is it a reference to a branch? */
200  if ((s = strchr(tok,'#')) != NULL && !strcmp(s+1,"branch")) {
201  cc = *s;
202  *s = '\0';
203  buf = tmalloc(strlen(tok) + 4);
204  sprintf(buf,"i(%s)",tok);
205  *s = cc;
206  }
207 
208  /* is it 'x' ? */
209  if (*tok == 'x' && !*(tok+1) && ft_sim->ptXalias) {
210  buf = copy(ft_sim->ptXalias);
211  }
212 
213  if (buf)
214  tok = buf;
215 
216  while (*tok) {
217  if ((olen = (nl - newline)) >= len) {
218  len += 16;
219  newline = trealloc(newline,len);
220  nl = newline + olen;
221  }
222  *nl++ = *tok++;
223  }
224 
225  if (buf)
226  txfree(buf);
227 
228  *tl = c;
229  }
230  *nl = '\0';
231  *line = newline;
232 }
IFsimulator * ft_sim
Definition: main.c:111
static char buf[MAXPROMPT]
Definition: arg.c:18
Definition: subckt.c:18
#define issep(c)
Definition: inpptree.c:91
char * ptXalias
Definition: ifsim.h:471
Definition: cddefs.h:119
char * copy()
char * tmalloc()
Definition: fteinp.h:14
void txfree()
#define NULL
Definition: spdefs.h:121
static double c
Definition: vectors.c:16
int count
Definition: output.c:152
char * trealloc()
static int PTcheck ( )
static
static int PTcheck ( INPparseNode p)
static

Definition at line 681 of file inpptree.c.

687 {
688  switch (p->type) {
689  case PT_PLACEHOLDER:
690  return (0);
691 
692  case PT_CONSTANT:
693  case PT_VAR:
694  case PT_PARAM:
695  case PT_TFUNC:
696  return (1);
697 
698  case PT_FUNCTION:
699  return (PTcheck(p->left));
700 
701  case PT_PLUS:
702  case PT_MINUS:
703  case PT_TIMES:
704  case PT_DIVIDE:
705  case PT_POWER:
706  return (PTcheck(p->left) && PTcheck(p->right));
707 
708  default:
709  fprintf(stderr, "Internal error: bad node type %d\n", p->type);
710  return (0);
711  }
712 }
#define PT_FUNCTION
Definition: inpptree.h:74
#define PT_DIVIDE
Definition: inpptree.h:72
#define PT_PLACEHOLDER
Definition: inpptree.h:68
#define PT_CONSTANT
Definition: inpptree.h:75
static int PTcheck()
struct INPparseNode * right
Definition: inpptree.h:48
#define PT_TFUNC
Definition: inpptree.h:79
#define PT_VAR
Definition: inpptree.h:76
struct INPparseNode * left
Definition: inpptree.h:47
#define PT_PLUS
Definition: inpptree.h:69
#define PT_MINUS
Definition: inpptree.h:70
#define PT_PARAM
Definition: inpptree.h:77
#define PT_POWER
Definition: inpptree.h:73
#define PT_TIMES
Definition: inpptree.h:71
static INPparseNode* PTdifferentiate ( )
static
static INPparseNode* PTdifferentiate ( INPparseNode p,
int  varnum 
)
static

Definition at line 236 of file inpptree.c.

245 {
246  INPparseNode *arg1, *arg2, *newp;
247 
248 /* printf("differentiating: "); printTree(p); printf(" wrt var %d\n", varnum);*/
249 
250  switch (p->type) {
251 
252  case PT_CONSTANT:
253  case PT_PARAM:
254  case PT_TFUNC:
255  newp = mkcon((double) 0);
256  break;
257 
258  case PT_VAR:
259  /* Is this the variable we're differentiating wrt? */
260  if (p->valueIndex == varnum)
261  newp = mkcon((double) 1);
262  else
263  newp = mkcon((double) 0);
264  break;
265 
266  case PT_PLUS:
267  case PT_MINUS:
268  arg1 = PTdifferentiate(p->left, varnum);
269  arg2 = PTdifferentiate(p->right, varnum);
270  if (arg1->type == PT_CONSTANT && arg1->constant == 0) {
271  txfree((char*)arg1);
272  if (p->type == PT_PLUS)
273  newp = arg2;
274  else
275  newp = mkf(PTF_UMINUS,arg2);
276  }
277  else if (arg2->type == PT_CONSTANT && arg2->constant == 0) {
278  txfree((char*)arg2);
279  newp = arg1;
280  }
281  else
282  newp = mkb(p->type, arg1, arg2);
283  break;
284 
285  case PT_TIMES:
286  /* d(a * b) = d(a) * b + d(b) * a */
287  arg1 = PTdifferentiate(p->left, varnum);
288  arg2 = PTdifferentiate(p->right, varnum);
289  if (arg1->type == PT_CONSTANT && arg1->constant == 0) {
290  txfree((char*)arg1);
291  newp = mkb(PT_TIMES,p->left,arg2);
292  }
293  else if (arg2->type == PT_CONSTANT && arg2->constant == 0) {
294  txfree((char*)arg2);
295  newp = mkb(PT_TIMES,arg1,p->right);
296  }
297  else
298  newp = mkb(PT_PLUS, mkb(PT_TIMES, arg1, p->right),
299  mkb(PT_TIMES, p->left, arg2));
300  break;
301 
302  case PT_DIVIDE:
303  /* d(a / b) = (d(a) * b - d(b) * a) / b^2 */
304  arg1 = PTdifferentiate(p->left, varnum);
305  arg2 = PTdifferentiate(p->right, varnum);
306  if (arg1->type == PT_CONSTANT && arg1->constant == 0) {
307  txfree((char*)arg1);
308  newp = mkb(PT_DIVIDE, mkf(PTF_UMINUS,
309  mkb(PT_TIMES, p->left, arg2)),
310  mkb(PT_POWER, p->right, mkcon((double) 2)));
311  }
312  else if (arg2->type == PT_CONSTANT && arg2->constant == 0) {
313  txfree((char*)arg2);
314  newp = mkb(PT_DIVIDE, arg1, p->right);
315  }
316  else
317  newp = mkb(PT_DIVIDE, mkb(PT_MINUS, mkb(PT_TIMES, arg1,
318  p->right), mkb(PT_TIMES, p->left, arg2)),
319  mkb(PT_POWER, p->right, mkcon((double) 2)));
320  break;
321 
322  case PT_POWER:
323  /* Two cases... If the power is a constant then we're cool.
324  * Otherwise we have to be tricky.
325  */
326 
327  if (p->right->type == PT_CONSTANT) {
328 
329  arg1 = PTdifferentiate(p->left, varnum);
330  newp = mkb(PT_TIMES, mkb(PT_TIMES,
331  mkcon(p->right->constant),
332  mkb(PT_POWER, p->left,
333  mkcon(p->right->constant - 1))),
334  arg1);
335  }
336  else {
337  /* This is complicated. f(x) ^ g(x) ->
338  * exp(y(x) * ln(f(x)) ...
339  */
340  arg1 = PTdifferentiate(p->left, varnum);
341  arg2 = PTdifferentiate(p->right, varnum);
342  newp = mkb(PT_TIMES, mkf(PTF_EXP, mkb(PT_TIMES,
343  p->right, mkf(PTF_LN, p->left))),
345  mkb(PT_DIVIDE, arg1, p->left)),
346  mkb(PT_TIMES, arg2,
347  mkf(PTF_LN, arg1))));
348 
349  }
350  break;
351 
352  case PT_FUNCTION:
353  /* Many cases. Set arg1 to the derivative of the function,
354  * and arg2 to the derivative of the argument.
355  */
356  arg2 = PTdifferentiate(p->left, varnum);
357  if (arg2->type == PT_CONSTANT && arg2->constant == 0) {
358  newp = arg2;
359  break;
360  }
361 
362  switch (p->funcnum) {
363 
364  case PTF_ABS: /* sgn(u) */
365  arg1 = mkf(PTF_SGN, p->left);
366  break;
367 
368  case PTF_SGN: /* u -> a hack */
369  arg1 = p->left;
370  break;
371 
372  case PTF_ACOS: /* - 1 / sqrt(1 - u^2) */
373  arg1 = mkb(PT_DIVIDE, mkcon((double) -1), mkf(PTF_SQRT,
374  mkb(PT_MINUS, mkcon((double) 1),
375  mkb(PT_POWER, p->left, mkcon((double)
376  2)))));
377  break;
378 
379  case PTF_ACOSH: /* 1 / sqrt(u^2 - 1) */
380  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT,
382  mkcon((double) 2)),
383  mkcon((double) 1))));
384 
385  break;
386 
387  case PTF_ASIN: /* 1 / sqrt(1 - u^2) */
388  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT,
389  mkb(PT_MINUS, mkcon((double) 1),
390  mkb(PT_POWER, p->left, mkcon((double)
391  2)))));
392  break;
393 
394  case PTF_ASINH: /* 1 / sqrt(u^2 + 1) */
395  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkf(PTF_SQRT,
396  mkb(PT_PLUS, mkb(PT_POWER, p->left,
397  mkcon((double) 2)),
398  mkcon((double) 1))));
399  break;
400 
401  case PTF_ATAN: /* 1 / (1 + u^2) */
402  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_PLUS,
403  mkb(PT_POWER, p->left, mkcon((double)
404  2)), mkcon((double) 1)));
405  break;
406 
407  case PTF_ATANH: /* 1 / (1 - u^2) */
408  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_MINUS,
409  mkcon((double) 1), mkb(PT_POWER,
410  p->left, mkcon((double) 2))));
411  break;
412 
413  case PTF_COS: /* - sin(u) */
414  arg1 = mkf(PTF_UMINUS, mkf(PTF_SIN, p->left));
415  break;
416 
417  case PTF_COSH: /* sinh(u) */
418  arg1 = mkf(PTF_SINH, p->left);
419  break;
420 
421  case PTF_EXP: /* exp(u) */
422  arg1 = mkf(PTF_EXP, p->left);
423  break;
424 
425  case PTF_LN: /* 1 / u */
426  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), p->left);
427  break;
428 
429  case PTF_LOG: /* log(e) / u */
430  arg1 = mkb(PT_DIVIDE, mkcon((double) M_LOG10E), p->left);
431  break;
432 
433  case PTF_SIN: /* cos(u) */
434  arg1 = mkf(PTF_COS, p->left);
435  break;
436 
437  case PTF_SINH: /* cosh(u) */
438  arg1 = mkf(PTF_COSH, p->left);
439  break;
440 
441  case PTF_SQRT: /* 1 / (2 * sqrt(u)) */
442  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_TIMES,
443  mkcon((double) 2), mkf(PTF_SQRT,
444  p->left)));
445  break;
446 
447  case PTF_TAN: /* 1 / (cos(u) ^ 2) */
448  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_POWER,
449  mkf(PTF_COS, p->left), mkcon((double)
450  2)));
451  break;
452 
453  case PTF_TANH: /* 1 / (cosh(u) ^ 2) */
454  arg1 = mkb(PT_DIVIDE, mkcon((double) 1), mkb(PT_POWER,
455  mkf(PTF_COSH, p->left), mkcon((double)
456  2)));
457  break;
458 
459  case PTF_UMINUS: /* - 1 ; like a constant (was 0 !) */
460  arg1 = mkcon((double) - 1.0);
461  break;
462 
463  default:
464  fprintf(stderr, "Internal Error: bad function # %d\n",
465  p->funcnum);
466  newp = NULL;
467  break;
468  }
469  newp = mkb(PT_TIMES, arg1, arg2);
470  break;
471 
472  case PT_TABLE:
473  arg2 = PTdifferentiate(p->left, varnum);
474  if (arg2->type == PT_CONSTANT && arg2->constant == 0) {
475  newp = arg2;
476  break;
477  }
478  arg1 = allocate_pnode(P_ALLOC);
479  arg1->new_deriv = 1;
480  arg1->type = PT_TABLE;
481  arg1->left = p->left;
482  arg1->funcnum = 1; /* return derivative if 1 */
483  arg1->function = p->function;
484  arg1->funcname = p->funcname;
485  arg1->evfunc = pt_table;
486  newp = mkb(PT_TIMES, arg1, arg2);
487  break;
488 
489  default:
490  fprintf(stderr, "Internal error: bad node type %d\n", p->type);
491  newp = NULL;
492  break;
493  }
494 
495 /* printf("result is: "); printTree(newp); printf("\n"); */
496  return (newp);
497 }
#define PTF_SQRT
Definition: inpptree.h:97
#define PT_FUNCTION
Definition: inpptree.h:74
#define PT_TABLE
Definition: inpptree.h:80
#define PT_DIVIDE
Definition: inpptree.h:72
#define PTF_ACOS
Definition: inpptree.h:84
static INPparseNode * PTdifferentiate()
#define PTF_COS
Definition: inpptree.h:90
#define PT_CONSTANT
Definition: inpptree.h:75
static INPparseNode * mkcon()
static INPparseNode * allocate_pnode()
#define P_ALLOC
Definition: inpptree.c:75
#define PTF_TANH
Definition: inpptree.h:99
int(* evfunc)()
Definition: inpptree.h:53
#define PTF_COSH
Definition: inpptree.h:91
struct INPparseNode * right
Definition: inpptree.h:48
double constant
Definition: inpptree.h:49
int funcnum
Definition: inpptree.h:52
#define PTF_EXP
Definition: inpptree.h:92
#define PTF_SIN
Definition: inpptree.h:95
#define PT_TFUNC
Definition: inpptree.h:79
double(* function)()
Definition: inpptree.h:54
#define PT_VAR
Definition: inpptree.h:76
struct INPparseNode * left
Definition: inpptree.h:47
void txfree()
#define NULL
Definition: spdefs.h:121
#define PT_PLUS
Definition: inpptree.h:69
#define PT_MINUS
Definition: inpptree.h:70
#define PT_PARAM
Definition: inpptree.h:77
#define PTF_ATANH
Definition: inpptree.h:89
static INPparseNode * mkf()
static int pt_table()
static INPparseNode * mkb()
#define PTF_ASINH
Definition: inpptree.h:87
#define PTF_UMINUS
Definition: inpptree.h:100
#define PTF_ASIN
Definition: inpptree.h:86
#define PTF_LN
Definition: inpptree.h:93
#define PTF_ABS
Definition: inpptree.h:101
#define PT_POWER
Definition: inpptree.h:73
#define PTF_LOG
Definition: inpptree.h:94
int valueIndex
Definition: inpptree.h:50
#define PTF_SINH
Definition: inpptree.h:96
#define M_LOG10E
Definition: spice.h:140
#define PTF_ACOSH
Definition: inpptree.h:85
#define PTF_ATAN
Definition: inpptree.h:88
#define PTF_SGN
Definition: inpptree.h:102
#define PTF_TAN
Definition: inpptree.h:98
int new_deriv
Definition: inpptree.h:60
#define PT_TIMES
Definition: inpptree.h:71
char * funcname
Definition: inpptree.h:51
static PTelement* PTlexer ( )
static
static PTelement* PTlexer ( char **  line)
static

Definition at line 1123 of file inpptree.c.

1127 {
1128  double td;
1129  int err;
1130  static PTelement el;
1131  static char *specials = " \t()^+-*/,";
1132  static int lasttoken = TOK_END, lasttype;
1133  char *sbuf, *s;
1134 
1135  sbuf = *line;
1136 /*
1137 printf("entering lexer, sbuf = '%s', lastoken = %d, lasttype = %d\n",
1138 sbuf, lasttoken, lasttype);
1139 */
1140  while ((*sbuf == ' ') || (*sbuf == '\t') || (*sbuf == '='))
1141  sbuf++;
1142 
1143  switch (*sbuf) {
1144  case '\0':
1145  el.token = TOK_END;
1146  break;
1147 
1148  case ',':
1149  el.token = TOK_COMMA;
1150  sbuf++;
1151  break;
1152 
1153  case '-':
1154  if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN))
1155  el.token = TOK_MINUS;
1156  else
1157  el.token = TOK_UMINUS;
1158  sbuf++;
1159  break;
1160 
1161  case '+':
1162  el.token = TOK_PLUS;
1163  sbuf++;
1164  break;
1165 
1166  case '*':
1167  el.token = TOK_TIMES;
1168  sbuf++;
1169  break;
1170 
1171  case '/':
1172  el.token = TOK_DIVIDE;
1173  sbuf++;
1174  break;
1175 
1176  case '^':
1177  el.token = TOK_POWER;
1178  sbuf++;
1179  break;
1180 
1181  case '(':
1182  if (((lasttoken == TOK_VALUE) && ((lasttype == TYP_NUM))) ||
1183  (lasttoken == TOK_RPAREN)) {
1184  el.token = TOK_END;
1185  }
1186  else {
1187  el.token = TOK_LPAREN;
1188  sbuf++;
1189  }
1190  break;
1191 
1192  case ')':
1193  el.token = TOK_RPAREN;
1194  sbuf++;
1195  break;
1196 
1197  default:
1198  if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN)) {
1199  el.token = TOK_END;
1200  break;
1201  }
1202 
1203  td = INPevaluate(&sbuf, &err, 0);
1204  if (err == OK) {
1205  while (isalpha(*sbuf))
1206  sbuf++;
1207  el.token = TOK_VALUE;
1208  el.type = TYP_NUM;
1209  el.value.real = td;
1210  }
1211  else {
1212  el.token = TOK_VALUE;
1213  el.type = TYP_STRING;
1214  el.value.string = get_stringvar(&sbuf,specials);
1215  }
1216  }
1217 
1218  lasttoken = el.token;
1219  lasttype = el.type;
1220 
1221  *line = sbuf;
1222 
1223 /*
1224 printf("PTlexer: token = %d, type = %d, left = '%s'\n",
1225 el.token, el.type, sbuf);
1226 */
1227 
1228  return (&el);
1229 }
union PTelement::@15 value
#define TOK_VALUE
Definition: inpptree.h:127
#define TOK_UMINUS
Definition: inpptree.h:124
#define TOK_MINUS
Definition: inpptree.h:120
Definition: cddefs.h:119
#define TOK_TIMES
Definition: inpptree.h:121
char * string
Definition: inpptree.h:142
double INPevaluate()
static char * get_stringvar()
#define TOK_DIVIDE
Definition: inpptree.h:122
static int lasttype
Definition: parse.c:39
#define OK
Definition: iferrmsg.h:17
Definition: fteinp.h:14
static char * sbuf
Definition: parse.c:40
double real
Definition: inpptree.h:143
#define TOK_LPAREN
Definition: inpptree.h:125
#define TYP_STRING
Definition: inpptree.h:133
static int lasttoken
Definition: parse.c:39
#define TOK_RPAREN
Definition: inpptree.h:126
#define TOK_END
Definition: inpptree.h:118
#define TOK_PLUS
Definition: inpptree.h:119
#define TOK_COMMA
Definition: inpptree.h:128
#define TYP_NUM
Definition: inpptree.h:132
int type
Definition: inpptree.h:140
Definition: mfb.h:383
int token
Definition: inpptree.h:139
#define TOK_POWER
Definition: inpptree.h:123
static INPparseNode* PTparse ( )
static
static INPparseNode* PTparse ( char **  line)
static

Definition at line 740 of file inpptree.c.

744 {
745  PTelement stack[PT_STACKSIZE];
746  int sp = 0, st, i;
747  PTelement *top, *next;
748  INPparseNode *pn, *lpn, *rpn;
749 
750  stack[0].token = TOK_END;
751  next = PTlexer(line);
752 
753  while ((sp > 1) || (next->token != TOK_END)) {
754  /* Find the top-most terminal. */
755  i = sp;
756  do {
757  top = &stack[i--];
758  } while (top->token == TOK_VALUE);
759 
760 
761  switch (prectable[top->token][next->token]) {
762  case L:
763  case E:
764  /* Push the token read. */
765  if (sp == (PT_STACKSIZE - 1)) {
766  errMsg = copy("stack overflow");
767  return (NULL);
768  }
769  bcopy((char *) next, (char *) &stack[++sp],
770  sizeof (PTelement));
771  next = PTlexer(line);
772  continue;
773 
774  case R:
775  return (NULL);
776 
777  case G:
778  /* Reduce. Make st and sp point to the elts on the
779  * stack at the end and beginning of the junk to
780  * reduce, then try and do some stuff. When scanning
781  * back for a <, ignore VALUES.
782  */
783  st = sp;
784  if (stack[sp].token == TOK_VALUE)
785  sp--;
786  while (sp > 0) {
787  if (stack[sp - 1].token == TOK_VALUE)
788  i = 2; /* No 2 pnodes together... */
789  else
790  i = 1;
791  if (prectable[stack[sp - i].token]
792  [stack[sp].token] == L)
793  break;
794  else
795  sp = sp - i;
796  }
797  if (stack[sp - 1].token == TOK_VALUE)
798  sp--;
799  /* Now try and see what we can make of this.
800  * The possibilities are: - node
801  * node op node
802  * ( node )
803  * func ( node )
804  * func ( node, node, node, ... ) <- new
805  * node
806  */
807  if (st == sp) {
808  pn = makepnode(&stack[st]);
809  if (pn == NULL)
810  goto err;
811  }
812  else if ((stack[sp].token == TOK_UMINUS) &&
813  (st == sp + 1)) {
814  lpn = makepnode(&stack[st]);
815  if (lpn == NULL)
816  goto err;
817  pn = mkfnode(copy("-"), lpn);
818  }
819  else if ((stack[sp].token == TOK_LPAREN) &&
820  (stack[st].token == TOK_RPAREN)) {
821  pn = makepnode(&stack[sp + 1]);
822  if (pn == NULL)
823  goto err;
824  }
825  else if ((stack[sp + 1].token == TOK_LPAREN) &&
826  (stack[st].token == TOK_RPAREN)) {
827  lpn = makepnode(&stack[sp + 2]);
828  if ((lpn == NULL) || (stack[sp].type != TYP_STRING))
829  goto err;
830  if (!(pn = mkfnode(stack[sp].value.string, lpn)))
831  return (NULL);
832  }
833  else { /* node op node */
834  lpn = makepnode(&stack[sp]);
835  rpn = makepnode(&stack[st]);
836  if ((lpn == NULL) || (rpn == NULL))
837  goto err;
838  pn = mkbnode(stack[sp + 1].token, lpn, rpn);
839  }
840  stack[sp].token = TOK_VALUE;
841  stack[sp].type = TYP_PNODE;
842  stack[sp].value.pnode = pn;
843  continue;
844  }
845  }
846  pn = makepnode(&stack[1]);
847  if (pn)
848  return (pn);
849 err:
850  return (NULL);
851 }
union PTelement::@15 value
#define TOK_VALUE
Definition: inpptree.h:127
#define TOK_UMINUS
Definition: inpptree.h:124
#define R
Definition: inpptree.c:720
char * string
Definition: inpptree.h:142
char * errMsg
Definition: main.c:42
static INPparseNode * mkbnode()
static INPparseNode * makepnode()
char * copy()
#define PT_STACKSIZE
Definition: inpptree.h:148
Definition: fteinp.h:14
#define TYP_PNODE
Definition: inpptree.h:134
INPparseNode * pnode
Definition: inpptree.h:144
#define TOK_LPAREN
Definition: inpptree.h:125
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
#define L
Definition: inpptree.c:718
#define TYP_STRING
Definition: inpptree.h:133
#define G
Definition: inpptree.c:717
static INPparseNode * mkfnode()
#define TOK_RPAREN
Definition: inpptree.h:126
#define TOK_END
Definition: inpptree.h:118
#define E
Definition: inpptree.c:719
static char prectable[11][11]
Definition: inpptree.c:722
int type
Definition: inpptree.h:140
Definition: mfb.h:383
int token
Definition: inpptree.h:139
void bcopy(char *from, char *to, int num)
Definition: string.c:339
static PTelement * PTlexer()
static int tran_hack ( )
static
static int tran_hack ( char *  name,
char*  str 
)
static

Definition at line 1279 of file inpptree.c.

1286 {
1287  char *s, *t, *tok;
1288  char *buf;
1289  int n, error;
1290 
1291  if (name == NULL)
1292  return (false);
1293 
1294  if (strcmp(name,"sin") && strcmp(name,"exp"))
1295  return (true);
1296 
1297  for (n = 0, s = str; *s != ')'; n++,s++) ;
1298 
1299  buf = tmalloc(n+1);
1300  memcpy(buf,str,n);
1301  buf[n] = '\0';
1302 
1303  n = 0;
1304  t = buf;
1305  while (*t) {
1306  error = INPgetTok(&t,&tok,1);
1307  if (error) break;
1308  s = tok;
1309  (void)INPevaluate(&tok,&error,1);
1310  if (error) {
1311  txfree(s);
1312  break;
1313  }
1314  txfree(s);
1315  n++;
1316  }
1317  txfree(buf);
1318  if (!error && n >= 2)
1319  return (true);
1320  return (false);
1321 }
static char buf[MAXPROMPT]
Definition: arg.c:18
Definition: cddefs.h:119
double INPevaluate()
char * tmalloc()
void txfree()
#define NULL
Definition: spdefs.h:121
Definition: cddefs.h:192
int INPgetTok()

Variable Documentation

GENERIC* circuit
static

Definition at line 16 of file inpptree.c.

struct constant constants[]
static
Initial value:
= {
{ "e", M_E },
{ "pi", M_PI },
{ NULL, 0 }
}
#define M_PI
Definition: spice.h:132
#define M_E
Definition: spice.h:136
#define NULL
Definition: spdefs.h:121
IFsimulator* ft_sim

Definition at line 111 of file main.c.

int numvalues
static

Definition at line 15 of file inpptree.c.

char prectable[11][11]
static
Initial value:
= {
{ R, L, L, L, L, L, L, L, R, L, R },
{ G, G, G, L, L, L, L, L, G, L, G },
{ G, G, G, L, L, L, L, L, G, L, G },
{ G, G, G, G, G, L, L, L, G, L, G },
{ G, G, G, G, G, L, L, L, G, L, G },
{ G, G, G, G, G, L, L, L, G, L, G },
{ G, G, G, G, G, G, G, L, G, L, R },
{ R, L, L, L, L, L, L, L, E, L, L },
{ G, G, G, G, G, G, G, R, G, R, G },
{ G, G, G, G, G, G, G, G, G, R, G },
{ G, L, L, L, L, L, L, L, G, L, G }
}
#define R
Definition: inpptree.c:720
#define L
Definition: inpptree.c:718
#define G
Definition: inpptree.c:717
#define E
Definition: inpptree.c:719

Definition at line 722 of file inpptree.c.

INPtables* tables
static

Definition at line 17 of file inpptree.c.

int* types
static

Definition at line 14 of file inpptree.c.

IFvalue* values = NULL
static

Definition at line 13 of file inpptree.c.