dotgnu-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[DotGNU]Hello from pnetC


From: Rhys Weatherley
Subject: [DotGNU]Hello from pnetC
Date: Tue, 13 Aug 2002 16:18:23 +1000

After a long couple of weeks hacking away, the Portable.NET
compiler, cscc, can now compile simple C applications,
including everyone's favourite program:

    #include <stdio.h>

    int main(int argc, char *argv[])
    {
        printf("Hello World!\n");
        return 0;
    }

You will need the CVS version of pnet, plus the attached
"stdio.h" file.  Put this file into the directory
"${prefix}/lib/cscc/include" on your system after you
have done a make install on the latest pnet.

A few things are still being worked on in the compiler
and linker:

- Multi-file programs (i.e. everything must be in one
  .c file at the moment).
- Global variable initializers (e.g. int x = 4;).
- Array initializers (e.g. int x[] = {1, 2, 3};).
- Function attributes (for weak and strong aliases).
- "goto" and "switch".
- Conditional expressions (e.g. x ? y : z).
- Bit fields in structs and unions.

And of course, there are the inevitable bugs.  Please bang
on the compiler (hard!) and let me know what you find.

Gopal already found one oddity last night when he became
the first test victim: evaluation order is the reverse of
regular C compilers.

    int i=10;
    printf("%d %d %d",i++,i++,i++);

    gcc : 12 11 10
    cscc: 10 11 12

This is due to the way the CLR works.  It always evaluates
from left to right, instead of the usual C right to left.
I don't think that there is anything that we can do about
this, unfortunately.

Hopefully by this time next week we can get started on the
libc implementation.  There are a bunch of linker issues
that I have to fix first.  Then I have to wave the magic hands,
summon the right sprites, and sacrifice the requisite number
of rubber chickens to set up the autoconf/automake build
system for libc. :-)

Cheers,

Rhys.
#ifndef _STDIO_H
#define _STDIO_H

/* This is a temporary hack until we can get a real libc working */

#ifndef NULL
#define NULL 0
#endif

typedef __builtin_va_list   va_list;
#define va_start            __builtin_va_start
#define va_end(__va)        (__builtin_va_end((__va)))
#define va_arg(__va,__type) (__builtin_va_arg((__va),__type))

typedef __csharp__(System.Console) Console;
typedef __csharp__(System.IntPtr) IntPtr;
typedef __csharp__(System.Runtime.InteropServices.Marshal) Marshal;

int printf(const char *format, ...)
{
        va_list va;
        int posn;
        va_start(va, format);
        while(*format != '\0')
        {
                posn = 0;
                while(format[posn] != '\0' && format[posn] != '%')
                {
                        ++posn;
                }
                if(posn > 0)
                {
                        __invoke__ Console.Write
                                (__invoke__ 
Marshal.PtrToStringAnsi((IntPtr)format, posn));
                        format += posn;
                }
                if(*format == '%')
                {
                        ++format;
                        if(*format == 'd')
                        {
                                int val = va_arg(va, int);
                                __invoke__ Console.Write(val);
                                ++format;
                        }
                        else if(*format == 'u')
                        {
                                unsigned int val = va_arg(va, unsigned int);
                                __invoke__ Console.Write(val);
                                ++format;
                        }
                        else if(*format == 'l' && format[1] == 'd')
                        {
                                long val = va_arg(va, long);
                                __invoke__ Console.Write(val);
                                format += 2;
                        }
                        else if(*format == 'l' && format[1] == 'u')
                        {
                                unsigned long val = va_arg(va, unsigned long);
                                __invoke__ Console.Write(val);
                                format += 2;
                        }
                        else if(*format == 's')
                        {
                                const char *str = va_arg(va, const char *);
                                if(!str)
                                {
                                        str = "(null)";
                                }
                                __invoke__ Console.Write
                                        (__invoke__ 
Marshal.PtrToStringAnsi((IntPtr)str));
                                ++format;
                        }
                        else if(*format == '%')
                        {
                                __invoke__ Console.Write((__wchar__)'%');
                                ++format;
                        }
                }
        }
        va_end(va);
        return 0;
}

#endif /* _STDIO_H */

reply via email to

[Prev in Thread] Current Thread [Next in Thread]