⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpressn.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 3 页
字号:
      Else        pscopy(t,s,i+1, k-i-1);         err=evaluate( dico, q,t,0);      EndIf      i=k;      If Not err Then /*insert number*/        sadd(r,q)      Else         err=message( dico,s)      EndIf    ElsIf c==Intro Then      Inc(i);      While (i<ls) And (s[i-1]<=' ') Do Inc(i) Done      k=i;      If s[k-1]=='(' Then /*sub-formula*/         level=1;        Repeat           Inc(k);          If k>ls Then             d=chr(0)           Else             d=s[k-1]           EndIf          If d=='(' Then             Inc(level)           ElsIf d==')' Then             Dec(level)          EndIf        Until (k>ls) Or ((d==')') And (level<=0)) EndRep	If k>ls Then            err=message( dico,"Closing \")\" not found.");        Else	  pscopy(t,s,i+1, k-i-1);           err=evaluate( dico, q,t,0);        EndIf        i=k;      Else /*simple identifier may also be string*/        Repeat           Inc(k);          If k>ls Then             d=chr(0)           Else             d=s[k-1]           EndIf        Until (k>ls) Or (d<=' ') EndRep	pscopy(t,s,i,k-i);         err=evaluate( dico, q,t,1);        i=k-1;      EndIf      If Not err Then /*insert the number*/         sadd(r,q)      Else         message( dico,s)      EndIf    ElsIf c==Nodekey Then /*follows: a node keyword*/      Repeat         Inc(i)       Until s[i-1]>' ' EndRep      k=i;      Repeat         Inc(k)       Until (k>ls) Or Not alfanum(s[k-1]) EndRep      pscopy(q,s,i,k-i);      nd=parsenode( Addr(dico->nodetab), q);       If Not spice3 Then         stri(nd,q)       EndIf; /* substitute by number */       sadd(r,q);      i=k-1;    Else       If Not spice3 Then c=upcase(c) EndIf      cadd(r,c); /*c<>Intro*/    EndIf  Done /*while*/  return err;EndFunc#endif/********* interface functions for spice3f5 extension ***********/InternProc compactfloatnb(Pchar v)/* try to squeeze a floating pt format to 10 characters */ /* erase superfluous 000 digit streams before E *//* bug: truncating, no rounding */ Begin  short n,k, lex;  Str(20,expo);  n=cpos('E',v); /* if too long, try to delete digits */  If n >3 Then    pscopy(expo, v, n,length(v));    lex= length(expo);    k=n-2;  /* mantissa is 0...k */    While (v[k]=='0') And (v[k-1]=='0') Do Dec(k) Done    If (k+1+lex) > 10 Then k= 9-lex EndIf    pscopy(v,v, 1,k+1);     sadd(v,expo);     EndIfEndProcInternFunc short insertnumber(tdico *dico, short i, Pchar s, Pchar u)/* insert u in string s in place of the next placeholder number */Begin  Str(40,v);  Str(80,msg);  Bool found;  short ls, k;   long accu;  ls= length(s);  scopy(v,u);  compactfloatnb(v);  While length(v)<10 Do     cadd(v,' ')   Done  If length(v)>10 Then     scopy(msg," insertnumber fails: ");     sadd(msg,u);     message( dico, msg)   EndIf  found=False;  While (Not found) And (i<ls) Do    found= (s[i]=='1');    k=0; accu=0;    While found And (k<10) Do /* parse a 10-digit number */        found= num(s[i+k]);      If found Then          accu= 10 * accu + s[i+k]- '0'       EndIf      Inc(k)    Done    If found Then       accu=accu - 1000000000L; /* plausibility test */      found= (accu>0) And (accu<2000)    EndIf    Inc(i)  Done  If found Then /* substitute at i-1 */    Dec(i);    For k=0; k<10; Inc(k) Do s[i+k]= v[k] Done    i= i+10;  Else     i= ls;     message( dico,"insertnumber: missing slot ");  EndIf  return iEndFuncFunc Bool nupa_substitute( tdico *dico, Pchar s, Pchar r, Bool err)/* s: pointer to original source line.   r: pointer to result line, already heavily modified wrt s    anywhere we find a 10-char numstring in r, substitute it.  bug: wont flag overflow!*/Begin  short i,k,ls,level, nnest, ir;  char c,d;  Strbig(Llen, q);  Strbig(Llen, t);  i=0;   ls=length(s);   err=False;   ir=0;  While (i<ls) And (Not err) Do    Inc(i); c=s[i-1];    If c==Pspice Then /* try pspice expression syntax */      k=i; nnest=1;      Repeat         Inc(k); d=s[k-1];        If d=='{' Then           Inc(nnest)         ElsIf d=='}' Then           Dec(nnest)         EndIf      Until (nnest==0) Or (d==0) EndRep      If d==0 Then         err=message( dico,"Closing \"}\" not found.");      Else        pscopy(t,s,i+1, k-i-1);         err=evaluate( dico, q,t,0);      EndIf      i=k;      If Not err Then        ir= insertnumber(dico, ir, r,q)      Else         err=message( dico, "Cannot compute substitute")      EndIf    ElsIf c==Intro Then      Inc(i);      While (i<ls) And (s[i-1]<=' ') Do Inc(i) Done      k=i;      If s[k-1]=='(' Then /*sub-formula*/         level=1;        Repeat           Inc(k);          If k>ls Then             d=chr(0)           Else             d=s[k-1]          EndIf          If d=='(' Then             Inc(level)           ElsIf d==')' Then             Dec(level)          EndIf        Until (k>ls) Or ((d==')') And (level<=0)) EndRep	If k>ls Then          err=message( dico,"Closing \")\" not found.");        Else	  pscopy(t,s,i+1, k-i-1);          err=evaluate( dico, q,t,0);        EndIf        i=k;      Else /*simple identifier may also be string? */        Repeat           Inc(k);          If k>ls Then            d=chr(0)           Else            d=s[k-1]          EndIf        Until (k>ls) Or (d<=' ') EndRep	pscopy(t,s,i,k-i);         err=evaluate( dico, q,t,1);        i= k-1;      EndIf      If Not err Then        ir= insertnumber(dico, ir, r,q)      Else        message( dico, "Cannot compute &(expression)")      EndIf    EndIf  Done /*while*/  return errEndFuncInternFunc Byte getword( Pchar  s, Pchar t, Byte  after, short * pi)/* isolate a word from s after position "after". return i= last read+1 */Begin  short i= *pi;  short ls;  Byte key;  i=after;  ls=length(s);  Repeat    Inc(i)  Until (i>=ls) Or alfa(s[i-1]) EndRep  scopy(t,"");  While (i<=ls) And (alfa(s[i-1]) Or num(s[i-1])) Do    cadd(t,upcase(s[i-1]));     Inc(i);  Done  If NotZ(t[0]) Then      key=keyword(keys,t)   Else     key=0   EndIf  *pi=i;  return key;EndFuncInternFunc char getexpress( Pchar s, Pchar t, short * pi)/* returns expression-like string until next separator Input  i=position before expr, output  i=just after expr, on separator. returns tpe=='R' If numeric, 'S' If string only*/Begin  short i= *pi;   short ia,ls,level;  char c,d, tpe;  Bool comment= False;  ls=length(s);  ia=i+1;  While (ia<ls) And (s[ia-1]<=' ') Do    Inc(ia)  Done /*white space ? */  If s[ia-1]=='\"' Then /*string constant*/    Inc(ia);     i=ia;    While (i<ls) And (s[i-1]!='\"') Do Inc(i) Done    tpe='S';    Repeat      Inc(i)    Until (i>ls) Or (s[i-1] >' ') EndRep  Else    If s[ia-1]=='{' Then Inc(ia) EndIf    i= ia-1;    Repeat       Inc(i);       If i>ls Then        c=';'       Else        c=s[i-1]      EndIf      If c=='(' Then /*sub-formula*/         level=1;        Repeat          Inc(i);          If i>ls Then            d=Nul          Else            d=s[i-1]          EndIf          If d=='(' Then            Inc(level)          ElsIf d==')' Then            Dec(level)          EndIf        Until (i>ls) Or ((d==')') And (level<=0)) EndRep      EndIf      /* buggy? */ If (c=='/') Or (c=='-') Then comment= (s[i]==c) EndIf     Until (cpos(c, ",;)}") >0)  Or comment EndRep /*legal separators*/    tpe='R';  EndIf  pscopy(t,s,ia,i-ia);   If s[i-1]=='}' Then Inc(i) EndIf  If tpe=='S' Then Inc(i) EndIf /* beyond quote */  *pi=i;   return tpe;EndFuncFunc Bool nupa_assignment( tdico *dico, Pchar  s, char mode)/* is called for all 'Param' lines of the input file.   is also called for the params: section of a subckt .   mode='N' define new local variable, else global...   bug: we cannot rely on the transformed line, must re-parse everything!*/Begin/* s has the format: ident = expression; ident= expression ...  */  Strbig(Llen, t);   Strbig(Llen,u);  short i,j, ls;  Byte key;  Bool error, err;  char dtype;  Word wval=0;  double rval= 0.0;  ls=length(s);  error=False;  i=0;  j= spos("//", s); /* stop before comment if any */  If j>0 Then ls= j-1 EndIf   /* bug: doesnt work. need to  revise getexpress ... !!! */  i=0;  While (i<ls) And (s[i]<=' ') Do Inc(i) Done  If s[i]==Intro Then Inc(i) EndIf  If s[i]=='.' Then  /* skip any dot keyword */    While s[i]>' ' Do Inc(i) Done  EndIf  While (i<ls) And (Not error) Do    key=getword(s,t, i, Addr(i));    If (t[0]==0) Or (key>0) Then       error=message( dico," Identifier expected")    EndIf    If Not error Then /* assignment expressions */      While (i<=ls) And (s[i-1] !='=') Do Inc(i) Done      If i>ls Then          error= message( dico," = sign expected .")       EndIf      dtype=getexpress(s,u, Addr(i));      If dtype=='R' Then         rval=formula( dico, u, Addr(error));        If error Then           message( dico," Formula() error.")         EndIf       ElsIf dtype=='S' Then         wval= i       EndIf      err=define(dico,t, mode /*was ' ' */ , dtype,rval,wval,Null);       error= error Or err;    EndIf    If (i<ls) And (s[i-1] != ';') Then       error=message( dico," ; sign expected.")    Else /*Inc(i)*/     EndIf   Done  return errorEndFuncFunc Bool nupa_subcktcall( tdico *dico, Pchar s, Pchar x, Bool err)/* s= a subckt define line, with formal params.   x= a matching subckt call line, with actual params */Begin  short n,m,i,j,k,g,h, narg=0, ls, nest;  Strbig(Llen,t);  Strbig(Llen,u);  Strbig(Llen,v);  Strbig(Llen,idlist);  Str(80,subname);	    /***** first, analyze the subckt definition line */  n=0; /* number of parameters if any */  ls=length(s);  j=spos("//",s);  If j>0 Then pscopy(t,s,1,j-1) Else scopy(t,s) EndIf   stupcase(t);   j= spos("SUBCKT", t);   If j>0 Then    j= j +6; /* fetch its name */    While (j<ls) And (t[j]<=' ') Do Inc(j) Done    While alfanum(t[j]) Do      cadd(subname,t[j]); Inc(j)     Done   Else     err=message( dico," Not a subckt line!")   EndIf;  i= spos("PARAMS:",t);   If i>0 Then     pscopy(t,t, i+7, length(t));     While j=cpos('=',t), j>0 Do /* isolate idents to the left of =-signs */      k= j-2;       While (k>=0) And (t[k]<=' ') Do Dec(k) Done      h=k;      While (h>=0) And alfanum(t[h]) Do Dec(h) Done      If alfa(t[h+1]) And (k>h) Then /* we have some id */        For m=(h+1); m<=k; Inc(m) Do           cadd(idlist,t[m])        Done         sadd(idlist,"=$;");        Inc(n);      Else         message( dico,"identifier expected.")      EndIf           pscopy(t,t, j+1, length(t));    Done  EndIf  /***** next, analyze the circuit call line */  If Not err Then    narg=0;    j=spos("//",x);    If j>0 Then pscopy(t,x,1,j-1) Else scopy(t,x) EndIf     stupcase(t);    ls=length(t);    j= spos(subname,t);     If j>0 Then      j=j + length(subname) -1; /* 1st position of arglist: j */      While (j<ls) And ((t[j]<=' ') Or (t[j]==',')) Do Inc(j) Done       While j<ls Do /* try to fetch valid arguments */        k= j;         scopy(u,"");        If (t[k]==Intro) Then /* handle historical syntax... */          If alfa(t[k+1]) Then             Inc(k)          ElsIf t[k+1]=='(' Then /* transform to braces... */            Inc(k); t[k]='{';            g=k;  nest=1;            While (nest>0) And (g<ls) Do              Inc(g);               If t[g]=='(' Then Inc(nest)               ElsIf t[g]==')' Then Dec(nest)              EndIf            Done            If (g<ls) And (nest==0) Then t[g]='}' EndIf          EndIf        EndIf        If alfanum(t[k]) Then /* number, identifier */          h=k;           While t[k] > ' ' Do Inc(k) Done          pscopy(u,t, h+1, k-h);           j= k;            ElsIf t[k]=='{' Then          getexpress(t,u, Addr(j));           Dec(j); /* confusion: j was in Turbo Pascal convention */        Else           Inc(j);          If t[k]>' ' Then             scopy(v,"Subckt call, symbol ");             cadd(v,t[k]);             sadd(v," not understood");            message( dico,v);          EndIf         EndIf        If NotZ(u[0]) Then           Inc(narg);          k=cpos('$',idlist);           If k>0 Then /* replace dollar with expression string u */            pscopy(v,idlist,1,k-1);            sadd(v,u);             pscopy(u,idlist, k+1, length(idlist));            scopy(idlist,v);             sadd(idlist,u);           EndIf        EndIf      Done    Else       message( dico,"Cannot find called subcircuit")     EndIf   EndIf  /***** finally, execute the multi-assignment line */  dicostack(dico, Push);  /* create local symbol scope */  If narg != n Then    scopy(t," Mismatch: ");    nadd(t,n);     sadd(t,"  formal but ");    nadd(t,narg);     sadd(t," actual params.");     err= message( dico,t);    message( dico,idlist);  /* Else debugwarn(dico, idlist) */  EndIf  err= nupa_assignment(dico, idlist, 'N');        return errEndFuncProc nupa_subcktexit( tdico *dico)Begin  dicostack(dico, Pop);EndProc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -