//#include "Unix.h"
#include "stdafx.h"   //MS Windows
#include "Strawberry.h"

#include "string.h"

void type_string(DWORD start)
{
  int i;

  for (i=start; StringStore[i]!=0; i++)
    if (StringStore[i]=='\\')
    {
      string2[len++]='\\';
      if (StringStore[i+1]!='0')
        string2[len++]='\\';
    }
    else if (StringStore[i]=='\"')
    {
      string2[len++]='\\';
      string2[len++]='\"';
    }
    else if (StringStore[i]=='\n')
    {
      string2[len++]='\\';
      string2[len++]='n';
    }
    else if (StringStore[i]=='\t')
    {
      string2[len++]='\\';
      string2[len++]='t';
    }
    else if (StringStore[i]=='\r')
    {
      string2[len++]='\\';
      string2[len++]='r';
    }
    else
      string2[len++]=StringStore[i];
}
DWORD write_p(DWORD ter, DWORD flag, DWORD buda_br2)
// flag  &1 Is it a klause from the program,
//       &2 Deep 0 is deep 0, 1 is deep br_buf1,
//       &4 Print unreadable (not quoted),
//       &8 buda_br2 is in Link,
{
  DWORD br_buf=0, atom_br=0, buf[BUFFERS][2];
  DWORD  i, j, t, t2, m, p;            

  if (flag&1)
    ter=Prog_fild[Program[p=ter]];
  if (flag&2)
  {
    t2=t=br_buf1+1; // +1?
    buf_4[t]=ter;
    buf_6[t]=0;
  }
  else
  {
    t2=t=0;
    buf_4[0]=ter;
    buf_6[0]=0;
  }
  br_buf=0;
eOK:if (ter<TT_START)
  {
    if (ter>=TT_VAR)
    {
      if (!(flag&1))
      {
        for (j=0, i=t+1; i>t2; )                            
          if ( buf_6[--i]&2 )   /* 2,3,6,7,10 */
          {
            if (buf_6[i]&1)
            {
              m=Buda1[buf_4[i]]-TT_START;
              if (Ufil_vs[m-MEMORY_C]!=M1)
                j=Substi[Ufil_vs[m-MEMORY_C]+j];
              else if (Ufil_c1[m]>=MEMORY_c256)
                j+=Chfil_v[Ufil_c1[m]-MEMORY_c256];
              else if (Ufil_c1[m]==TT_VAR)
                j++;
            }
            j=Link[Buda2[buf_4[i]]+j];
            goto e1;
          }
          else if (buf_6[i]%2)
          {
            if (Ufil_vs[buf_4[i]-MEMORY_c256]!=M1)
              j=Substi[Ufil_vs[buf_4[i]-MEMORY_c256]+j];
            else if (Ufil_c1[buf_4[i]-TT_START]>=MEMORY_c256)
              j+=Chfil_v[Ufil_c1[buf_4[i]-TT_START]-MEMORY_c256];
            else if (Ufil_c1[buf_4[i]-TT_START]==TT_VAR)
              j++;
          }
        if (flag&8)
          j=Link[buda_br2+j];  
        else
          j+=buda_br2;  
e1:     while (Buda1[j]==TT_LINK)
          j=Buda2[j];
        if (Buda1[j]<TT_START && Buda1[j]>=TT_VAR)
        {
          if (atom_br)
          {
            string2[len++]='[';
            for (i=0; i<atom_br; i++)
            {
              if (!(flag&4) && (atom_buf[i]<=36 || atom_buf[i]>62 || (Pointers[atom_buf[i]]&OBSEG6)))
              {
                string2[len++]='\'';
                string2[len++]=key_oposit[atom_buf[i]];
                string2[len++]='\'';
              }
              else
                string2[len++]=key_oposit[atom_buf[i]];
              string2[len++]=',';
            }
            atom_br=0;
            string2[len-1]='|';
            buf[br_buf][0]=0;
            buf[br_buf++][1]=1;
          }
          if (Buda1[j]==TT_VAR)
          {
            if (j<global_br)
            {
et_j:         string2[len++]='G';
              string2[len++]='_';
              for(m=global[j]; m>=TT_START; m=Ufil_c2[m-TT_START])
                string2[len++]=key_oposit[Ufil_c1[m-TT_START]];
              string2[len++]=key_oposit[m];
            }
            else if ((int)j<0)
            {
              if (!(Link[j]&HALF))
              {
                j=Link[j];
                goto et_j;
              }
              else
                len+=sprintf((LPSTR)(string2+len), "_M%d",0-j);
            }
            else
              len+=sprintf((LPSTR)(string2+len), "_%d",j-global_br);
          }
          else if (Buda1[j]==TT_STR)                       // NewTypes - string
          {
            string2[len++]='\"';
            if (!(flag&4)) // quoted
              type_string(Buda2[j]);
            else
            {
              strcpy((LPSTR)(string2+len), (LPSTR)(StringStore+Buda2[j]));
              len+=strlen((LPSTR)(StringStore+Buda2[j]));
            }
            string2[len++]='\"';
          }
          else if (Buda1[j]==TT_INT)                       // NewTypes - integer
            len+=sprintf((LPSTR)(string2+len), "%d", (int)Buda2[j]);
          else if (Buda1[j]==TT_FLOAT)                       // NewTypes - float
            len+=sprintf((LPSTR)(string2+len), "%G", *(float*)&(Buda2[j]));
          else if (Buda1[j]==TT_OBJ)
          {
            if (Buda2[j]<ObjectStore_br && SUBTYPE(ObjectStore[Buda2[j]],CLASS_SYSTEM_LIST)) // NewTypes - object
            {
              DWORD *Temp=(LPDWORD)ObjectStore[Buda2[j]+5];
              string2[len++]='[';
              for (i=0; i<ObjectStore[Buda2[j]+2]; i++)
              {
                if (ObjectStore[Buda2[j]+8]==TT_STR)          // NewTypes - string
                {
                  string2[len++]='\"';
                  if (!(flag&4)) // quoted
                    type_string(Temp[i]);
                  else
                  {
                    strcpy((LPSTR)(string2+len), (LPSTR)(StringStore+Temp[i]));
                    len+=strlen((LPSTR)(StringStore+Temp[i]));
                  }
                  string2[len++]='\"';
                  string2[len++]=',';
                }
                else if (ObjectStore[Buda2[j]+8]==TT_INT)     // NewTypes - integer
                  len+=sprintf((LPSTR)(string2+len), "%d,", (int)Temp[i]);
                else if (ObjectStore[Buda2[j]+8]==TT_FLOAT)     // NewTypes - float
                  len+=sprintf((LPSTR)(string2+len), "%G,", *(float*)&(Temp[i]));
                else if (ObjectStore[Buda2[j]+8]==TT_OBJ)
                  len+=sprintf((LPSTR)(string2+len), "0j%d,", (int)Temp[i]);
              }
              string2[len-1]=']';
            }
            else
              len+=sprintf((LPSTR)(string2+len), "0j%d", (int)Buda2[j]);
          }
        }  
        else
        {
          ter=Buda1[j];
          buf_6[t]|=2;
          buf_4[t]=j;
          goto eOK;
        }
      }
      else
      {
        for (j=0, i=t; i>0; )
          if (buf_6[--i])
          {
            if (Ufil_vs[buf_4[i]-MEMORY_c256]!=M1)
              j=Substi[Ufil_vs[buf_4[i]-MEMORY_c256]+j];
            else if (Ufil_c1[buf_4[i]-TT_START]>=MEMORY_c256)
              j+=Chfil_v[Ufil_c1[buf_4[i]-TT_START]-MEMORY_c256];
            else if (Ufil_c1[buf_4[i]-TT_START]==TT_VAR)
              j++;
          }
        if (Prog_fild[Program[p]+1]&HALF) // Prog_Obj[p]!=M1
        {
          for(i=Prog_fild[Program[p]+1]&MASKA1; Prog_fild[i]<j; i+=3);
          if(Prog_fild[i]==j)
          {
            if (Prog_fild[i+1]==TT_LINK)
            {
              string2[len++]='G';
              string2[len++]='_';
              for(m=global[Prog_fild[i+2]]; m>=TT_START; m=Ufil_c2[m-TT_START])
                string2[len++]=key_oposit[Ufil_c1[m-TT_START]];
              string2[len++]=key_oposit[m];
            }
            else if (Prog_fild[i+1]==TT_STR)
            {
              string2[len++]='\"';
              if (!(flag&4)) // quoted
                type_string(Prog_fild[i+2]);
              else
              {
                strcpy((LPSTR)(string2+len), (LPSTR)(StringStore+Prog_fild[i+2]));
                len+=strlen((LPSTR)(StringStore+Prog_fild[i+2]));
              }
              string2[len++]='\"';
            }
            else if (Prog_fild[i+1]==TT_INT)
              len+=sprintf((LPSTR)(string2+len), "%d", (int)Prog_fild[i+2]);
            else if (Prog_fild[i+1]==TT_FLOAT)
              len+=sprintf((LPSTR)(string2+len), "%G", *(float*)&(Prog_fild[i+2]));
            else if (Prog_fild[i+1]==TT_OBJ)
            {
              if (SUBTYPE(ObjectStore[Prog_fild[i+2]],CLASS_SYSTEM_LIST)
                 && ObjectStore[Prog_fild[i+2]+6]==TT_INT) //NewTypes - object
              {
                DWORD *Temp=(LPDWORD)ObjectStore[Prog_fild[i+2]+4];
                string2[len++]='[';
                for (i=0; i<ObjectStore[Prog_fild[i+2]+2]; i++)
                  len+=sprintf((LPSTR)(string2+len), "%d,", (int)Temp[i]);
                string2[len-1]=']';
              }
              else
                len+=sprintf((LPSTR)(string2+len), "0j%d", (int)Prog_fild[i+2]);
            }
          }  
          else  
            len+=sprintf((LPSTR)(string2+len), "_%d", j);
        }
        else  
          len+=sprintf((LPSTR)(string2+len), "_%d", j);
      }          
    }
    else if (ter==TT_LIST)
    {
      if (atom_br)
        goto E4;
      else if ((flag&4) && len && string2[len-1]=='|')
        len--;
      else
      {
        strcpy((LPSTR)(string2+len), "[]");
        len+=2;
      }  
    }  
    else if (ter==TT_SET)
    {
      strcpy((LPSTR)(string2+len), "{}");
      len+=2;
    }  
    else
    {
      atom_buf[atom_br++]=(BYTE)ter;
      goto e4;
    }
E1: if (br_buf)
    {
      t=bufu6[--br_buf];
      switch(buf[br_buf][0])
      {
       case 0:
        if (buf[br_buf][1]==0)
          string2[len++]=')';
        else if (buf[br_buf][1]==1)
          string2[len++]=']';
        else if (buf[br_buf][1]==2)
          string2[len-1]=')';
        goto E1;
       case 1:
        string2[len++]='(';
        buf_6[t]|=1;
        ter=buf_4[++t]=buf[br_buf][1];
        buf_6[t]=0;
        if (ter==TT_LIST)
        {
          string2[len++]=')';
          goto E1;
        }
        else if (ter<TT_START || Chfil_c[ter-TT_START]!=2)
        {
          string2[len++]='|';
          buf[br_buf][0]=0;
          buf[br_buf++][1]=0;
          goto eOK;
        }
        buf[br_buf][0]=3;
        buf[br_buf][1]=Ufil_c2[ter-=TT_START];
        bufu6[br_buf++]=t;
        ter=buf_4[++t]=Ufil_c1[ter];
        buf_6[t]=0;
        goto eOK;
       case 2:
        buf_6[t]|=1;
        ter=buf_4[++t]=buf[br_buf][1];
        buf_6[t]=0;
        if (ter==TT_LIST)
        {
          string2[len++]=']';
          goto E1;
        }
        else if (ter<TT_START || Chfil_c[ter-TT_START]!=2)
        {
          string2[len++]='|';
          buf[br_buf][0]=0;
          buf[br_buf++][1]=1;
          goto eOK;
        }
E2:     string2[len++]=',';
        buf[br_buf][1]=Ufil_c2[ter-=TT_START];
        bufu6[br_buf++]=t;
        ter=buf_4[++t]=Ufil_c1[ter];
        buf_6[t]=0;
        goto eOK;
       case 3:
        buf_6[t]|=1;
        ter=buf_4[++t]=buf[br_buf][1];
        buf_6[t]=0;
        if (ter==TT_LIST)
        {
          string2[len++]=')';
          goto E1;
        }
        else if (ter<TT_START || Chfil_c[ter-TT_START]!=2)
        {
          string2[len++]='|';
          buf[br_buf][0]=0;
          buf[br_buf++][1]=0;
          goto eOK;
        }
        goto E2;
      }
    }
    else
    {
      string2[len]=0;
      if (len>=L_BUFER)
        MessageBoxA(NUL, "String2 is small!", "Error", MB_OK | MB_ICONEXCLAMATION);
      return(1);
    }
  }
  else if (Chfil_c[ter-=TT_START]==2)
  {
    while (Ufil_c1[ter]<TT_SET)
    {
      atom_buf[atom_br++]=(BYTE)Ufil_c1[ter];
e3:   if (Ufil_c2[ter]<TT_SET)
      {
        DWORD the_atom, the_op;
          
        atom_buf[atom_br++]=(BYTE)Ufil_c2[ter];
e4:     if (flag&4)                    // not quoted
          m=0;
        else if (atom_buf[0]<=36)
          m=1;
        else if (atom_buf[0]<=62)                    // letter
        {
          for (i=1; i<atom_br && atom_buf[i]<=62; i++);
E_op:     if (i<atom_br && atom_br>1)
            m=1;
          else if (atom_br==1)
          {
E_op2:      if (Pointers[atom_buf[0]]&OBSEG6)   // if op
            {
              the_op=D_field[(Pointers[atom_buf[0]]&MASKA3)+7];
              m=(OpType[the_op]==0 && Oper[the_op]!=Oper[the_op+1])?0:1;
            }
            else
              m=0;
          }
          else
          {
            the_atom=(buf_6[t-atom_br+2]&2)?Buda1[buf_4[t-atom_br+2]]:buf_4[t-atom_br+2];
            if (the_atom>=MEMORY_c256)
              m=1;
            else if (Pointers[the_atom]&OBSEG6)   // if op
            {
              the_op=D_field[(Pointers[the_atom]&MASKA3)+7];
              m=(OpType[the_op]==0 && Oper[the_op]!=Oper[the_op+1])?0:1;
            }
            else
              m=0;
          }
        }
        else if (atom_buf[0]<80)    // symbol
        {
          for (i=1; i<atom_br && 62<atom_buf[i] && atom_buf[i]<80; i++);
          goto E_op;
        }
        else if (atom_buf[0]<82)    // ! or ;
        {
          if (atom_br==1)
            goto E_op2;
          else
            m=1;
        }
        else //if (atom_buf[0]<84)    // , or |
          m=1;
        //else  // something like cyrilic letter
        if (m)
          string2[len++]='\'';
        for(j=0; j<atom_br; j++)
          string2[len++]=key_oposit[atom_buf[j]];
        if (m)
          string2[len++]='\'';
        atom_br=0;
        goto E1;
      }
      else
      {
        buf_6[t]|=1;
        ter=buf_4[++t]=Ufil_c2[ter];
        buf_6[t]=0;
        if (ter>=TT_START)
        {
          if (Chfil_c[ter-TT_START]!=2)
          {
E4:         if ((flag&4) && len && string2[len-1]=='|')
            {
              string2[len-1]=',';
              buf[br_buf-2][1]+=2;
            }  
            else  
              string2[len++]='[';
            for(j=0; 1; )  // j<atom_br
            {
              if (!(flag&4) && (atom_buf[j]<=36 || atom_buf[j]>62 || (Pointers[atom_buf[j]]&OBSEG6)))
              {
                string2[len++]='\'';
                string2[len++]=key_oposit[atom_buf[j]];
                string2[len++]='\'';
              }
              else
                string2[len++]=key_oposit[atom_buf[j]];
              if (++j==atom_br)
                break;
              string2[len++]=',';
            }
            atom_br=0;
            if (ter==TT_LIST)
            {
              string2[len++]=']';
              goto E1;
            }
            string2[len++]='|';
            buf[br_buf][0]=0;           /* second */
            buf[br_buf++][1]=1;         /* put ] */
            goto eOK;
          }
          else
            ter-=TT_START;
        }
        else if (ter!=TT_VAR || (flag&1))
          goto E4;
        else
          goto eOK;
      }
    }
    if (Ufil_c1[ter]==TT_VAR && !(flag&1))
    {
      for (j=0, i=t+1; i>t2; )                            
        if ( buf_6[--i]&2 )   /* 2,3,6,7,10 */
        {
          if (buf_6[i]&1)
          {
            m=Buda1[buf_4[i]]-TT_START;
            if (Ufil_vs[m-MEMORY_C]!=M1)
              j=Substi[Ufil_vs[m-MEMORY_C]+j];
            else if (Ufil_c1[m]>=MEMORY_c256)
              j+=Chfil_v[Ufil_c1[m]-MEMORY_c256];
            else if (Ufil_c1[m]==TT_VAR)
              j++;
          }
          j=Link[Buda2[buf_4[i]]+j];
          goto e2;
        }
        else if (buf_6[i]%2)
        {
          if (Ufil_vs[buf_4[i]-MEMORY_c256]!=M1)
            j=Substi[Ufil_vs[buf_4[i]-MEMORY_c256]+j];
          else if (Ufil_c1[buf_4[i]-TT_START]>=MEMORY_c256)
            j+=Chfil_v[Ufil_c1[buf_4[i]-TT_START]-MEMORY_c256];
          else if (Ufil_c1[buf_4[i]-TT_START]==TT_VAR)
            j++;
        }
      if (flag&8)
        j=Link[buda_br2+j];  
      else
        j+=buda_br2;  
e2:   while (Buda1[j]==TT_LINK)
        j=Buda2[j];
      if (Buda1[j]<TT_SET)
      {
        atom_buf[atom_br++]=(BYTE)Buda1[j];
        goto e3;
      }  
    }
    buf[br_buf][0]=2;                        /* ,ter...] */
    buf[br_buf][1]=Ufil_c2[ter];
    bufu6[br_buf++]=t;
    if ((flag&4) && len && string2[len-1]=='|')
    {
      string2[len-1]=',';
      buf[br_buf-2][1]+=2;
    }  
    else  
      string2[len++]='[';
    for(j=0; j<atom_br; j++)
    {
      if (!(flag&4) && (atom_buf[j]<=36 || atom_buf[j]>62 || (Pointers[atom_buf[j]]&OBSEG6)))
      {
        string2[len++]='\'';
        string2[len++]=key_oposit[atom_buf[j]];
        string2[len++]='\'';
      }
      else
        string2[len++]=key_oposit[atom_buf[j]];
      string2[len++]=',';
    }
    atom_br=0;
    ter=buf_4[++t]=Ufil_c1[ter];
    buf_6[t]=0;
    goto eOK;
  }
  else if (atom_br)
  {
    if ((flag&4) && len && string2[len-1]=='|')
    {
      string2[len-1]=',';
      buf[br_buf-2][1]+=2;
    }  
    else  
      string2[len++]='[';
    for(j=0; 1; )  // j<atom_br
    {
      if (!(flag&4) && (atom_buf[j]<=36 || atom_buf[j]>62 || (Pointers[atom_buf[j]]&OBSEG6)))
      {
        string2[len++]='\'';
        string2[len++]=key_oposit[atom_buf[j]];
        string2[len++]='\'';
      }
      else
        string2[len++]=key_oposit[atom_buf[j]];
      if (++j==atom_br)
        break;
      string2[len++]=',';
    }
    atom_br=0;
    string2[len++]='|';
    buf[br_buf][0]=0;           /* second */
    buf[br_buf++][1]=1;         /* put ] */
  }
  bufu6[br_buf]=t;
  buf[br_buf][0]=1;
  buf[br_buf++][1]=Ufil_c2[ter];
  ter=buf_4[++t]=Ufil_c1[ter];
  buf_6[t]=0;
  goto eOK;
  
}

