NedoC компилятор как стандартный ANSI-C

Публичный форум для http://www.nedopc.org/nedopc

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:Есть компилятор си-подобного языка в байткод, интерпретатор и транслятор байт-кода, а также простой сишный препроцессор (#ifdef, #define и т.д.).
Вот кстати тот самый простой сишный препроцессор (minicpp), написанный мной для виндовой версии Tunguska CC (компилятор троичного языка си для тунгуски) в 2008 году:

Code: Select all

/* minicpp.c - Alexander Shabarshin <ashabarshin@gmail.com> 
 * Mini C preprocessor (public domain)
 * 21 Nov 2008 - first version
 */

#include <stdio.h>
#include <string.h>
#include "my_text.h"

#define LINESZ 256

Text* macros = NULL;

int miniparse(char* file);

int main(int argc, char** argv)
{
 int r = 0;
 if(argc<1) return -1;
 macros = TextNew();
 r = miniparse(argv[1]);
// TextList(macros);
 TextDel(macros);
 return r;
}

int miniparse(char* file)
{
 Line *s,*l;
 Text *t;
 int i,j,k;
 int f_com = 0;
 int f_if = 0;
 int err = 0;
 char c,*p,*q,*qq,*qqq,str[64],st[LINESZ],st2[LINESZ];
 printf("# 1 "%s"\n",file);
 t = TextNew();
 if(t==NULL) return -2;
 TextLoad(t,file);
 if(t->num<=0) return -3;
 j = 0;
 for(s=t->first;s!=NULL;s=s->next)
 {
   p = s->str;
   while(*p==' '||*p=='\t') p++;
   for(q=p;*q;q++) 
   {
     if(!f_com&&q[0]=='/'&&q[1]=='/'){*q=0;break;}
     if(!f_com&&q[0]=='/'&&q[1]=='*')
     {
       k = strlen(q);
       q[0] = ' ';
       q[1] = ' ';
       for(i=2;i<k;i++)
       {
          if(q[i]=='*'&&q[i+1]=='/')
          {
             q[i] = ' ';
             q[i+1] = ' ';
             break;
          }
          q[i] = ' ';
       }
       if(i==k){*q=0;f_com=1;break;}
     }
     if(f_com&&q[0]=='*'&&q[1]=='/'){p=&q[2];f_com=0;}
   }
   if(f_com < 2)
   {
     q--;
     while(*q==' '||*q=='\t'){*q=0;q--;} 
     if(f_com==1) f_com++;
   }
   else *p = 0;
   if(!*p) continue;
   if(*p=='#')
   {
     if(!strncmp(p,"#include",8))
     {
        p = &p[8];
        while(*p==' '||*p=='\t') p++;
        if(/**p=='<'||*/*p=='"')
        {
          c = *p;
          if(c=='<') c='>';
          p++;
          q = strchr(p,c);
          if(q==NULL) err++;
          else *q = 0;
          err += miniparse(p);
        }
        continue;
     }
     else if(!strncmp(p,"#define",7))
     {
        p = &p[7];
        while(*p==' '||*p=='\t') p++;
        i = 0;
        while(*p!=' '&&*p!='\t'&&*p!=0)
        {
          str[i++] = *p;
          p++;
        }
        while(*p==' '||*p=='\t') p++;
        k = i;
        if(!*p) str[i] = 0;
        else  
        {
          str[i++] = '=';
          while(*p)
          {
            str[i++] = *p;
            p++;
          }
          str[i] = 0;
        }
        l = TextAdd(macros,str);
        if(l==NULL) return -4;
        l->type = 100 - k;
        TextSort(macros,TextFldTyp);
        continue;
     }
     else if(!strncmp(p,"#ifdef",6))
     {
        p = &p[6];
        while(*p==' '||*p=='\t') p++;
        i = 0;
        while(*p!=' '&&*p!='\t'&&*p!=0)
        {
          str[i++] = *p;
          p++;
        }
        str[i] = 0;
        for(l=macros->first;l!=NULL;l=l->next)
        {
          strncpy(st,l->str,LINESZ);
          q = strchr(st,'=');
          if(q!=NULL) *q = 0;
          if(!strcmp(st,str)) break;
        }
        if(l!=NULL) f_if = 2;
        else f_if = 1;
        continue;
     }
     else if(!strncmp(p,"#ifndef",7))
     {
        p = &p[7];
        while(*p==' '||*p=='\t') p++;
        i = 0;
        while(*p!=' '&&*p!='\t'&&*p!=0)
        {
          str[i++] = *p;
          p++;
        }
        str[i] = 0;
        for(l=macros->first;l!=NULL;l=l->next)
        {
          strncpy(st,l->str,LINESZ);
          q = strchr(st,'=');
          if(q!=NULL) *q = 0;
          if(!strcmp(st,str)) break;
        }
        if(l!=NULL) f_if = 1;
        else f_if = 2;
        continue;
     }
     else if(!strncmp(p,"#else",5))
     {
        if(f_if==1) f_if = 2;
        else if(f_if==2) f_if = 1;
        continue;
     }
     else if(!strncmp(p,"#endif",6))
     {
        f_if = 0;
        continue;
     }
   }
   if(f_if==1) continue;
   i = 0;
   while(*p)
   {
     for(l=macros->first;l!=NULL;l=l->next)
     {
        q = strchr(l->str,'=');
        if(q==NULL)
        {
           if(!strncmp(p,l->str,strlen(l->str)))
           {
             p = &p[strlen(l->str)];
             l = NULL;
             break;
           }
        }
        else
        {
           strncpy(st2,l->str,LINESZ);
           q = strchr(st2,'=');
           *q = 0;
           q++;
           if(!strncmp(p,st2,strlen(st2))) break;
        }
     }
     if(l==NULL) 
     {
        st[i++] = *p;
        p++;
     }
     else
     {
        qq = strchr(st2,'(');
        if(qq==NULL)
        {
           strcpy(&st[i],q);
           i += strlen(q);
           p = &p[strlen(st2)];
        }
        else
        {
           *qq = 0;
           qq++;
           qqq = strchr(qq,')');
           if(qqq!=NULL) *qqq = 0;
           /* not yet ready to handle this */
           err++;
        }
     }
   }
   st[i] = 0;
   printf("%s\n",st);
   j++;
 }
 TextDel(t);
 return err;
}
Публик домайн на 236 строк - понимает #include, #define (без аргументов), #ifdef, #ifndef, #else и #endif :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Можно взять за основу SmallC, например в варианте для Linux, расширив структурами, лонгами-даблами, препроцессором, перевести с K&R на ANSI (по сути тоже самое сделать, что уже сделали создатели Z88DK), но оставив поддерживаемые на данный момент 8080, 6809, 68000 и VAX :o, добавив больше процыков в будущем...

P.S. По этому линку также есть версия с поддержкой 8088 и версия с поддержкой структур и флоатов для Z80:
http://www.cpm.z80.de/small_c.html
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: NedoC компилятор как стандартный ANSI-C

Post by Shaos »

Можно ещё потихоньку писать свою опенсорцную реализацию стандартной сишной либы - например вот мой вариант atoi для 32-битных целых чисел:

Code: Select all

#include <stdio.h>
#include <stdlib.h>

int myatoi(const char* A) {
    int m = 0;
    int n = 0;
    int i = 0;
    while(A[i])
    {
        if(n==0 && A[i]=='-') m = 1;
        else
        {
            if(A[i]<'0'||A[i]>'9') break;
            else
            {
                if(n > 214748364)
                {
                    n = 2147483647;
                    break;
                }
                n *= 10;
                n += A[i]-'0';
            }
        }
        i++;
    }
    if(m)
    {
        if(n==2147483647) return -2147483648;
        return -n;
    }
    return n;
}

int main()
{
    printf("0 >>> %i\n",myatoi("0"));
    printf("1 >>> %i\n",myatoi("1"));
    printf("-1 >>> %i\n",myatoi("-1"));
    printf("9 >>> %i\n",myatoi("9"));
    printf("10 >>> %i\n",myatoi("10"));
    printf("-11 >>> %i\n",myatoi("-11"));
    printf("2147483647 >>> %i\n",myatoi("2147483647"));
    printf("-2147483648 >>> %i\n",myatoi("-2147483648"));
    printf("BIG >> %i\n",myatoi("5121478262"));
    return 0;
}
Я тут за главного - если что шлите мыло на me собака shaos точка net