diff --git a/samples/all.sh b/samples/all.sh new file mode 100644 index 000000000000..335a5d65c181 --- /dev/null +++ b/samples/all.sh @@ -0,0 +1,50 @@ + +# Little shell script to compile, link, and run all the samples. +# Use dmd2\windows\bin\shell.exe to execute. + +DMD=..\..\windows\bin\dmd +DFLAGS= +CLEAN=clean.bat + + + +#~ $(DMD) chello $(DFLAGS) # which compilation flags? +#~ chello + +$(DMD) d2html $(DFLAGS) +d2html d2html.d + +$(DMD) dhry $(DFLAGS) +dhry + +$(DMD) hello $(DFLAGS) +hello + +#~ $(DMD) htmlget $(DFLAGS) # broken + +#~ $(DMD) listener $(DFLAGS) # broken + + +$(DMD) pi $(DFLAGS) +pi 1000 + +$(DMD) sieve $(DFLAGS) +sieve + +$(DMD) wc $(DFLAGS) +wc wc.d + +$(DMD) wc2 $(DFLAGS) +wc2 wc2.d + +$(DMD) winsamp gdi32.lib winsamp.def +winsamp + +$(CLEAN) + +#~ broken: +# COM client/server example +#~ $(DMD) -c dserver -release $(DFLAGS) +#~ $(DMD) -c chello $(DFLAGS) +#~ $(DMD) dserver.obj chello.obj uuid.lib ole32.lib advapi32.lib kernel32.lib user32.lib dserver.def -L/map +#~ $(DMD) dclient $(DFLAGS) ole32.lib uuid.lib diff --git a/samples/build.bat b/samples/build.bat new file mode 100644 index 000000000000..3cf2ea594d60 --- /dev/null +++ b/samples/build.bat @@ -0,0 +1 @@ +..\..\windows\bin\shell all.sh diff --git a/samples/chello.d b/samples/chello.d new file mode 100644 index 000000000000..ebd7d61e1dd0 --- /dev/null +++ b/samples/chello.d @@ -0,0 +1,124 @@ + +/* Server for IHello + * Heavily modified from: + */ +/* + * SELFREG.CPP + * Server Self-Registrtation Utility, Chapter 5 + * + * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved + * + * Kraig Brockschmidt, Microsoft + * Internet : kraigb@microsoft.com + * Compuserve: >INTERNET:kraigb@microsoft.com + */ + +// From an example from "Inside OLE" Copyright Microsoft + +import std.c.stdio; +import std.c.stdlib; +import std.string; +import std.c.windows.windows; +import std.c.windows.com; + +GUID CLSID_Hello = { 0x30421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] }; +GUID IID_IHello = { 0x00421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] }; + +interface IHello : IUnknown +{ + extern (Windows) : + int Print(); +} + +// Type for an object-destroyed callback +alias void (*PFNDESTROYED)(); + +/* + * The class definition for an object that singly implements + * IHello in D. + */ +class CHello : ComObject, IHello +{ +protected: + IUnknown m_pUnkOuter; // Controlling unknown + + PFNDESTROYED m_pfnDestroy; // To call on closure + + /* + * pUnkOuter LPUNKNOWN of a controlling unknown. + * pfnDestroy PFNDESTROYED to call when an object + * is destroyed. + */ + public this(IUnknown pUnkOuter, PFNDESTROYED pfnDestroy) + { + m_pUnkOuter = pUnkOuter; + m_pfnDestroy = pfnDestroy; + } + + ~this() + { + MessageBoxA(null, "CHello.~this()", null, MB_OK); + } + + extern (Windows) : + /* + * Performs any intialization of a CHello that's prone to failure + * that we also use internally before exposing the object outside. + * Return Value: + * BOOL true if the function is successful, + * false otherwise. + */ + +public: + BOOL Init() + { + MessageBoxA(null, "CHello.Init()", null, MB_OK); + return true; + } + +public: + HRESULT QueryInterface(const (IID)*riid, LPVOID *ppv) + { + MessageBoxA(null, "CHello.QueryInterface()", null, MB_OK); + + if (IID_IUnknown == *riid) + *ppv = cast(void*) cast(IUnknown) this; + else if (IID_IHello == *riid) + *ppv = cast(void*) cast(IHello) this; + else + { + *ppv = null; + return E_NOINTERFACE; + } + + AddRef(); + return NOERROR; + } + + ULONG Release() + { + MessageBoxA(null, "CHello.Release()", null, MB_OK); + + if (0 != --count) + return count; + + /* + * Tell the housing that an object is going away so it can + * shut down if appropriate. + */ + MessageBoxA(null, "CHello Destroy()", null, MB_OK); + + if (m_pfnDestroy) + (*m_pfnDestroy)(); + + // delete this; + return 0; + } + + // IHello members + HRESULT Print() + { + MessageBoxA(null, "CHello.Print()", null, MB_OK); + return NOERROR; + } +} diff --git a/samples/clean.bat b/samples/clean.bat new file mode 100644 index 000000000000..8d648073b731 --- /dev/null +++ b/samples/clean.bat @@ -0,0 +1,5 @@ +@echo off +setlocal EnableDelayedExpansion +del *.obj +del *.map +del *.res diff --git a/samples/d2html.d b/samples/d2html.d new file mode 100644 index 000000000000..f78f4a4336d0 --- /dev/null +++ b/samples/d2html.d @@ -0,0 +1,401 @@ + +/* + * Copyright (c) 2001 + * Pavel "EvilOne" Minayev + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Author makes no representations about + * the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + */ + +import std.c.stdio; + +import std.conv; +import std.string; +import std.stream; // don't forget to link with stream.obj! + +// colors for syntax highlighting, default values are +// my preferences in Microsoft Visual Studio editor +class Colors +{ + static string keyword = "0000FF"; + static string number = "008000"; + static string astring = "000080"; + static string comment = "808080"; +} + +const int tabsize = 4; // number of spaces in tab +const char[24] symbols = "()[]{}.,;:=<>+-*/%&|^!~?"; +string[] keywords; + +// true if c is whitespace, false otherwise +byte isspace(char c) +{ + return indexOf(whitespace, c) >= 0; +} + +// true if c is a letter or an underscore, false otherwise +byte isalpha(char c) +{ + // underscore doesn't differ from letters in D anyhow... + return c == '_' || indexOf(letters, c) >= 0; +} + +// true if c is a decimal digit, false otherwise +byte isdigit(char c) +{ + return indexOf(digits, c) >= 0; +} + +// true if c is a hexadecimal digit, false otherwise +byte ishexdigit(char c) +{ + return indexOf(hexdigits, c) >= 0; +} + +// true if c is an octal digit, false otherwise +byte isoctdigit(char c) +{ + return indexOf(octdigits, c) >= 0; +} + +// true if c is legal D symbol other than above, false otherwise +byte issymbol(char c) +{ + return indexOf(symbols, c) >= 0; +} + +// true if token is a D keyword, false otherwise +byte iskeyword(string token) +{ + foreach (index, key; keywords) + { + if (!cmp(keywords[index], token)) + return true; + } + + return false; +} + +int main(string[] args) +{ + // need help? + if (args.length < 2 || args.length > 3) + { + printf("D to HTML converter\n" + "Usage: D2HTML .d [.htm]\n"); + return 0; + } + + // auto-name output file + if (args.length == 2) + args ~= args[1] ~ ".htm"; + + // load keywords + File kwd = new File("d2html.kwd"); + + while (!kwd.eof()) + keywords ~= to!string(kwd.readLine()); + + kwd.close(); + + // open input and output files + File src = new File(args[1]), dst = new File; + dst.create(args[2]); + + // write HTML header + dst.writeLine("" ~ args[1] ~ ""); + dst.writeLine("
");
+
+    // the main part is wrapped into try..catch block because
+    // when end of file is reached, an exception is raised;
+    // so we can omit any checks for EOF inside this block...
+    try
+    {
+        ulong linestart = 0;             // for tabs
+        char c;
+        src.read(c);
+
+        while (true)
+        {
+            if (isspace(c))                     // whitespace
+            {
+                do
+                {
+                    if (c == 9)
+                    {
+                        // expand tabs to spaces
+                        auto spaces = tabsize -
+                                     (src.position() - linestart) % tabsize;
+
+                        for (int i = 0; i < spaces; i++)
+                            dst.writeString(" ");
+
+                        linestart = src.position() - tabsize + 1;
+                    }
+                    else
+                    {
+                        // reset line start on newline
+                        if (c == 10 || c == 13)
+                            linestart = src.position() + 1;
+
+                        dst.write(c);
+                    }
+
+                    src.read(c);
+                } while (isspace(c));
+            }
+            else if (isalpha(c))                // keyword or identifier
+            {
+                string token;
+
+                do
+                {
+                    token ~= c;
+                    src.read(c);
+                } while (isalpha(c) || isdigit(c));
+
+                if (iskeyword(token))                   // keyword
+                    dst.writeString("" ~ token ~ "");
+                else                    // simple identifier
+                    dst.writeString(token);
+            }
+            else if (c == '0')                  // binary, octal or hexadecimal number
+            {
+                dst.writeString("");
+                dst.write(c);
+                src.read(c);
+
+                if (c == 'X' || c == 'x')                       // hexadecimal
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (ishexdigit(c))
+                        dst.write(c);
+
+                    // TODO: add support for hexadecimal floats
+                }
+                else if (c == 'B' || c == 'b')                  // binary
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (c == '0' || c == '1')
+                        dst.write(c);
+                }
+                else                    // octal
+                {
+                    do
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    } while (isoctdigit(c));
+                }
+
+                dst.writeString("");
+            }
+            else if (c == '#')                // hash
+            {
+                dst.write(c);
+                src.read(c);
+            }
+            else if (c == '\\')                // backward slash
+            {
+                dst.write(c);
+                src.read(c);
+            }
+            else if (isdigit(c))                // decimal number
+            {
+                dst.writeString("");
+
+                // integral part
+                do
+                {
+                    dst.write(c);
+                    src.read(c);
+                } while (isdigit(c));
+
+                // fractional part
+                if (c == '.')
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (isdigit(c))
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+                }
+
+                // scientific notation
+                if (c == 'E' || c == 'e')
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    if (c == '+' || c == '-')
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+
+                    while (isdigit(c))
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+                }
+
+                // suffices
+                while (c == 'U' || c == 'u' || c == 'L' ||
+                       c == 'l' || c == 'F' || c == 'f')
+                {
+                    dst.write(c);
+                    src.read(c);
+                }
+
+                dst.writeString("");
+            }
+            else if (c == '\'')                 // string without escape sequences
+            {
+                dst.writeString("");
+
+                do
+                {
+                    if (c == '<')                       // special symbol in HTML
+                        dst.writeString("<");
+                    else
+                        dst.write(c);
+
+                    src.read(c);
+                } while (c != '\'');
+                dst.write(c);
+                src.read(c);
+                dst.writeString("");
+            }
+            else if (c == 34)                   // string with escape sequences
+            {
+                dst.writeString("");
+                char prev;                      // used to handle \" properly
+
+                do
+                {
+                    if (c == '<')                       // special symbol in HTML
+                        dst.writeString("<");
+                    else
+                        dst.write(c);
+
+                    prev = c;
+                    src.read(c);
+                } while (!(c == 34 && prev != '\\'));                   // handle \"
+                dst.write(c);
+                src.read(c);
+                dst.writeString("");
+            }
+            else if (issymbol(c))               // either operator or comment
+            {
+                if (c == '<')                   // special symbol in HTML
+                {
+                    dst.writeString("<");
+                    src.read(c);
+                }
+                else if (c == '/')                      // could be a comment...
+                {
+                    src.read(c);
+
+                    if (c == '/')                       // single-line one
+                    {
+                        dst.writeString("/");
+
+                        while (c != 10)
+                        {
+                            if (c == '<')                               // special symbol in HTML
+                                dst.writeString("<");
+                            else if (c == 9)
+                            {
+                                // expand tabs
+                                auto spaces2 = tabsize -
+                                              (src.position() - linestart) % tabsize;
+
+                                for (int i2 = 0; i2 < spaces2; i2++)
+                                    dst.writeString(" ");
+
+                                linestart = src.position() - tabsize + 1;
+                            }
+                            else
+                                dst.write(c);
+
+                            src.read(c);
+                        }
+
+                        dst.writeString("");
+                    }
+                    else if (c == '*')                          // multi-line one
+                    {
+                        dst.writeString("/");
+                        char prev2;
+
+                        do
+                        {
+                            if (c == '<')                               // special symbol in HTML
+                                dst.writeString("<");
+                            else if (c == 9)
+                            {
+                                // expand tabs
+                                auto spaces3 = tabsize -
+                                              (src.position() - linestart) % tabsize;
+
+                                for (int i3 = 0; i3 < spaces3; i3++)
+                                    dst.writeString(" ");
+
+                                linestart = src.position() - tabsize + 1;
+                            }
+                            else
+                            {
+                                // reset line start on newline
+                                if (c == 10 || c == 13)
+                                    linestart = src.position() + 1;
+
+                                dst.write(c);
+                            }
+
+                            prev2 = c;
+                            src.read(c);
+                        } while (!(c == '/' && prev2 == '*'));
+                        dst.write(c);
+                        dst.writeString("");
+                        src.read(c);
+                    }
+                    else                        // just an operator
+                        dst.write(cast(char) '/');
+                }
+                else                    // just an operator
+                {
+                    dst.write(c);
+                    src.read(c);
+                }
+            }
+            else
+                // whatever it is, it's not a valid D token
+                throw new Error("unrecognized token");
+                //~ break;
+        }
+    }
+
+    // if end of file is reached and we try to read something
+    // with typed read(), a ReadError is thrown; in our case,
+    // this means that job is successfully done
+    catch (Exception e)
+    {
+        // write HTML footer
+        dst.writeLine("
"); + } + return 0; +} diff --git a/samples/d2html.d.htm b/samples/d2html.d.htm new file mode 100644 index 000000000000..8187efd84994 --- /dev/null +++ b/samples/d2html.d.htm @@ -0,0 +1,465 @@ +d2html.d +

+
+/*
+ * Copyright (c) 2001
+ * Pavel "EvilOne" Minayev
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Author makes no representations about
+ * the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ */
+
+import std.c.stdio;
+
+import std.conv;
+import std.string;
+import std.stream;    //   don't forget to link with stream.obj!
+
+
+// colors for syntax highlighting, default values are
+
+// my preferences in Microsoft Visual Studio editor
+
+class Colors
+{
+    static string keyword = "0000FF";
+    static string number  = "008000";
+    static string astring = "000080";
+    static string comment = "808080";
+}
+
+const int tabsize = 4;  // number of spaces in tab
+
+const char[24] symbols = "()[]{}.,;:=<>+-*/%&|^!~?";
+string[] keywords;
+
+// true if c is whitespace, false otherwise
+
+byte isspace(char c)
+{
+    return indexOf(whitespace, c) >= 0;
+}
+
+// true if c is a letter or an underscore, false otherwise
+
+byte isalpha(char c)
+{
+    // underscore doesn't differ from letters in D anyhow...
+
+    return c == '_' || indexOf(letters, c) >= 0;
+}
+
+// true if c is a decimal digit, false otherwise
+
+byte isdigit(char c)
+{
+    return indexOf(digits, c) >= 0;
+}
+
+// true if c is a hexadecimal digit, false otherwise
+
+byte ishexdigit(char c)
+{
+    return indexOf(hexdigits, c) >= 0;
+}
+
+// true if c is an octal digit, false otherwise
+
+byte isoctdigit(char c)
+{
+    return indexOf(octdigits, c) >= 0;
+}
+
+// true if c is legal D symbol other than above, false otherwise
+
+byte issymbol(char c)
+{
+    return indexOf(symbols, c) >= 0;
+}
+
+// true if token is a D keyword, false otherwise
+
+byte iskeyword(string token)
+{
+    foreach (index, key; keywords)
+    {
+        if (!cmp(keywords[index], token))
+            return true;
+    }
+
+    return false;
+}
+
+int main(string[] args)
+{
+    // need help?
+
+    if (args.length < 2 || args.length > 3)
+    {
+        printf("D to HTML converter\n"
+               "Usage: D2HTML <program>.d [<file>.htm]\n");
+        return 0;
+    }
+
+    // auto-name output file
+
+    if (args.length == 2)
+        args ~= args[1] ~ ".htm";
+
+    // load keywords
+
+    File kwd = new File("d2html.kwd");
+
+    while (!kwd.eof())
+        keywords ~= to!string(kwd.readLine());
+
+    kwd.close();
+
+    // open input and output files
+
+    File src = new File(args[1]), dst = new File;
+    dst.create(args[2]);
+
+    // write HTML header
+
+    dst.writeLine("<html><head><title>" ~ args[1] ~ "</title></head>");
+    dst.writeLine("<body color='#000000' bgcolor='#FFFFFF'><pre><code>");
+
+    // the main part is wrapped into try..catch block because
+
+    // when end of file is reached, an exception is raised;
+
+    // so we can omit any checks for EOF inside this block...
+
+    try
+    {
+        ulong linestart = 0;             // for tabs
+
+        char c;
+        src.read(c);
+
+        while (true)
+        {
+            if (isspace(c))                     // whitespace
+
+            {
+                do
+                {
+                    if (c == 9)
+                    {
+                        // expand tabs to spaces
+
+                        auto spaces = tabsize -
+                                     (src.position() - linestart) % tabsize;
+
+                        for (int i = 0; i < spaces; i++)
+                            dst.writeString(" ");
+
+                        linestart = src.position() - tabsize + 1;
+                    }
+                    else
+                    {
+                        // reset line start on newline
+
+                        if (c == 10 || c == 13)
+                            linestart = src.position() + 1;
+
+                        dst.write(c);
+                    }
+
+                    src.read(c);
+                } while (isspace(c));
+            }
+            else if (isalpha(c))                // keyword or identifier
+
+            {
+                string token;
+
+                do
+                {
+                    token ~= c;
+                    src.read(c);
+                } while (isalpha(c) || isdigit(c));
+
+                if (iskeyword(token))                   // keyword
+
+                    dst.writeString("<font color='#" ~ Colors.keyword ~
+                                    "'>" ~ token ~ "</font>");
+                else                    // simple identifier
+
+                    dst.writeString(token);
+            }
+            else if (c == '0')                  // binary, octal or hexadecimal number
+
+            {
+                dst.writeString("<font color='#" ~ Colors.number ~ "008000'>");
+                dst.write(c);
+                src.read(c);
+
+                if (c == 'X' || c == 'x')                       // hexadecimal
+
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (ishexdigit(c))
+                        dst.write(c);
+
+                    // TODO: add support for hexadecimal floats
+
+                }
+                else if (c == 'B' || c == 'b')                  // binary
+
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (c == '0' || c == '1')
+                        dst.write(c);
+                }
+                else                    // octal
+
+                {
+                    do
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    } while (isoctdigit(c));
+                }
+
+                dst.writeString("</font>");
+            }
+            else if (c == '#')                // hash
+
+            {
+                dst.write(c);
+                src.read(c);
+            }
+            else if (c == '\\')                // backward slash
+
+            {
+                dst.write(c);
+                src.read(c);
+            }
+            else if (isdigit(c))                // decimal number
+
+            {
+                dst.writeString("<font color='#" ~ Colors.number ~ "'>");
+
+                // integral part
+
+                do
+                {
+                    dst.write(c);
+                    src.read(c);
+                } while (isdigit(c));
+
+                // fractional part
+
+                if (c == '.')
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    while (isdigit(c))
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+                }
+
+                // scientific notation
+
+                if (c == 'E' || c == 'e')
+                {
+                    dst.write(c);
+                    src.read(c);
+
+                    if (c == '+' || c == '-')
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+
+                    while (isdigit(c))
+                    {
+                        dst.write(c);
+                        src.read(c);
+                    }
+                }
+
+                // suffices
+
+                while (c == 'U' || c == 'u' || c == 'L' ||
+                       c == 'l' || c == 'F' || c == 'f')
+                {
+                    dst.write(c);
+                    src.read(c);
+                }
+
+                dst.writeString("</font>");
+            }
+            else if (c == '\'')                 // string without escape sequences
+            {
+                dst.writeString("<font color='#" ~ Colors.astring ~ "'>");
+
+                do
+                {
+                    if (c == '<')                       // special symbol in HTML
+                        dst.writeString("<");
+                    else
+                        dst.write(c);
+
+                    src.read(c);
+                } while (c != '\'');
+                dst.write(c);
+                src.read(c);
+                dst.writeString("</font>");
+            }
+            else if (c == 34)                   // string with escape sequences
+
+            {
+                dst.writeString("<font color='#" ~ Colors.astring ~ "'>");
+                char prev;                      // used to handle \" properly
+
+
+                do
+                {
+                    if (c == '<')                       // special symbol in HTML
+
+                        dst.writeString("<");
+                    else
+                        dst.write(c);
+
+                    prev = c;
+                    src.read(c);
+                } while (!(c == 34 && prev != '\\'));                   // handle \"
+
+                dst.write(c);
+                src.read(c);
+                dst.writeString("</font>");
+            }
+            else if (issymbol(c))               // either operator or comment
+
+            {
+                if (c == '<')                   // special symbol in HTML
+
+                {
+                    dst.writeString("<");
+                    src.read(c);
+                }
+                else if (c == '/')                      // could be a comment...
+
+                {
+                    src.read(c);
+
+                    if (c == '/')                       // single-line one
+
+                    {
+                        dst.writeString("<font color='#" ~ Colors.comment ~ "'>/");
+
+                        while (c != 10)
+                        {
+                            if (c == '<')                               // special symbol in HTML
+
+                                dst.writeString("<");
+                            else if (c == 9)
+                            {
+                                // expand tabs
+
+                                auto spaces2 = tabsize -
+                                              (src.position() - linestart) % tabsize;
+
+                                for (int i2 = 0; i2 < spaces2; i2++)
+                                    dst.writeString(" ");
+
+                                linestart = src.position() - tabsize + 1;
+                            }
+                            else
+                                dst.write(c);
+
+                            src.read(c);
+                        }
+
+                        dst.writeString("</font>");
+                    }
+                    else if (c == '*')                          // multi-line one
+
+                    {
+                        dst.writeString("<font color='#" ~ Colors.comment ~ "'>/");
+                        char prev2;
+
+                        do
+                        {
+                            if (c == '<')                               // special symbol in HTML
+
+                                dst.writeString("<");
+                            else if (c == 9)
+                            {
+                                // expand tabs
+
+                                auto spaces3 = tabsize -
+                                              (src.position() - linestart) % tabsize;
+
+                                for (int i3 = 0; i3 < spaces3; i3++)
+                                    dst.writeString(" ");
+
+                                linestart = src.position() - tabsize + 1;
+                            }
+                            else
+                            {
+                                // reset line start on newline
+
+                                if (c == 10 || c == 13)
+                                    linestart = src.position() + 1;
+
+                                dst.write(c);
+                            }
+
+                            prev2 = c;
+                            src.read(c);
+                        } while (!(c == '/' && prev2 == '*'));
+                        dst.write(c);
+                        dst.writeString("</font>");
+                        src.read(c);
+                    }
+                    else                        // just an operator
+
+                        dst.write(cast(char) '/');
+                }
+                else                    // just an operator
+
+                {
+                    dst.write(c);
+                    src.read(c);
+                }
+            }
+            else
+                // whatever it is, it's not a valid D token
+
+                throw new Error("unrecognized token");
+                //~ break;
+
+        }
+    }
+
+    // if end of file is reached and we try to read something
+
+    // with typed read(), a ReadError is thrown; in our case,
+
+    // this means that job is successfully done
+
+    catch (Exception e)
+    {
+        // write HTML footer
+
+        dst.writeLine("</code></pre></body></html>");
+    }
+    return 0;
+}
+
diff --git a/samples/d2html.kwd b/samples/d2html.kwd new file mode 100644 index 000000000000..4a4220639179 --- /dev/null +++ b/samples/d2html.kwd @@ -0,0 +1,179 @@ +property +abstract +alias +align +asm +assert +auto +body +bool +break +byte +case +cast +catch +cdouble +cent +cfloat +char +class +const +continue +creal +dchar +dstring +debug +default +delegate +delete +deprecated +do +double +else +enum +export +extern +false +final +finally +float +for +foreach +foreach_reverse +function +goto +idouble +if +ifloat +immutable +import +in +inout +int +interface +invariant +ireal +is +lazy +long +macro +mixin +module +new +nothrow +null +out +override +package +pragma +private +protected +public +pure +real +ref +return +scope +shared +short +size_t +static +string +struct +super +switch +synchronized +template +this +throw +true +try +typedef +typeid +typeof +ubyte +ucent +uint +ulong +union +unittest +ushort +version +void +volatile +wchar +wstring +while +with +__FILE__ +__LINE__ +__gshared +__thread +__traits +const_cast +dynamic_cast +explicit +friend +inline +mutable +namespace +operator +register +reinterpret_cast +restrict +signed +sizeof +static_cast +typename +unsigned +using +virtual +int8_t +uint8_t +int16_t +uint16_t +int32_t +uint32_t +int64_t +uint64_t +int_least8_t +uint_least8_t +int_least16_t +uint_least16_t +int_least32_t +uint_least32_t +int_least64_t +uint_least64_t +int_fast8_t +uint_fast8_t +int_fast16_t +uint_fast16_t +int_fast32_t +uint_fast32_t +int_fast64_t +uint_fast64_t +intptr_t +uintptr_t +intmax_t +uintmax_t +wint_t +wchar_t +wctrans_t +time_t +and +and_eq +bitand +bitor +compl +not +not_eq +or +or_eq +xor +xor_eq +wctype_tcomplex +imaginary +_Complex +_Imaginary +_Bool +_Pragma diff --git a/samples/dclient.d b/samples/dclient.d new file mode 100644 index 000000000000..87de01e16c13 --- /dev/null +++ b/samples/dclient.d @@ -0,0 +1,126 @@ + +/* Client for IHello + * Heavily modified from: + */ +/* + * SELFREG.CPP + * Server Self-Registrtation Utility, Chapter 5 + * + * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved + * + * Kraig Brockschmidt, Microsoft + * Internet : kraigb@microsoft.com + * Compuserve: >INTERNET:kraigb@microsoft.com + */ + +import std.c.stdio; +import std.c.stdlib; +import std.c.windows.windows; +import std.c.windows.com; + +GUID CLSID_Hello = { 0x30421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] }; +GUID IID_IHello = { 0x00421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] }; + +interface IHello : IUnknown +{ + extern (Windows) : + int Print(); +} + +int main() +{ + DWORD dwVer; + HRESULT hr; + IHello pIHello; + + // Make sure COM is the right version + dwVer = CoBuildVersion(); + + if (rmm != HIWORD(dwVer)) + { + printf("Incorrect OLE 2 version number\n"); + return EXIT_FAILURE; + } + + hr=CoInitialize(null); // Initialize OLE + + if (FAILED(hr)) + { + printf("OLE 2 failed to initialize\n"); + return EXIT_FAILURE; + } + + printf("OLE 2 initialized\n"); + + if (dll_regserver("dserver.dll", 1) == 0) + { + printf("server registered\n"); + hr=CoCreateInstance(&CLSID_Hello, null, CLSCTX_ALL, &IID_IHello, &pIHello); + + if (FAILED(hr)) + { + printf("Failed to create object x%x\n", hr); + } + else + { + printf("Object created, calling IHello.Print(), IHello = %p\n", pIHello); + + // fflush(stdout); + pIHello.Print(); + pIHello.Release(); + } + + CoFreeUnusedLibraries(); + + if (dll_regserver("dserver.dll", 0)) + printf("server unregister failed\n"); + } + else + printf("server registration failed\n"); + + // Only call this if CoInitialize worked + CoUninitialize(); + return EXIT_SUCCESS; +} + +/************************************** + * Register/unregister a DLL server. + * Input: + * flag !=0: register + * ==0: unregister + * Returns: + * 0 success + * !=0 failure + */ + +extern (Windows) alias HRESULT (*pfn_t)(); + +int dll_regserver(const (char) *dllname, int flag) +{ + char *fn = flag ? cast(char*) "DllRegisterServer" + : cast(char*) "DllUnregisterServer"; + int result = 1; + pfn_t pfn; + HINSTANCE hMod; + + if (SUCCEEDED(CoInitialize(null))) + { + hMod=LoadLibraryA(dllname); + printf("hMod = %d\n", hMod); + + if (hMod > cast(HINSTANCE) HINSTANCE_ERROR) + { + printf("LoadLibraryA() succeeded\n"); + pfn = GetProcAddress(hMod, fn); + printf("pfn = %p, fn = '%s'\n", pfn, fn); + + if (pfn && SUCCEEDED((*pfn)())) + result = 0; + + CoFreeLibrary(hMod); + CoUninitialize(); + } + } + + return result; +} diff --git a/samples/dhry.d b/samples/dhry.d new file mode 100644 index 000000000000..5eed46213bbd --- /dev/null +++ b/samples/dhry.d @@ -0,0 +1,937 @@ + +/* + ************************************************************************* + * + * "DHRYSTONE" Benchmark Program + * ----------------------------- + * + * Version: C, Version 2.1 + * + * File: dhry.h (part 1 of 3) + * + * Date: May 25, 1988 + * + * Author: Reinhold P. Weicker + * Siemens Nixdorf Inf. Syst. + * STM OS 32 + * Otto-Hahn-Ring 6 + * W-8000 Muenchen 83 + * Germany + * Phone: [+49]-89-636-42436 + * (8-17 Central European Time) + * UUCP: weicker@ztivax.uucp@unido.uucp + * Internet: weicker@ztivax.siemens.com + * + * Original Version (in Ada) published in + * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984), + * pp. 1013 - 1030, together with the statistics + * on which the distribution of statements etc. is based. + * + * In this C version, the following C library functions are + * used: + * - strcpy, strcmp (inside the measurement loop) + * - printf, scanf (outside the measurement loop) + * + * Collection of Results: + * Reinhold Weicker (address see above) and + * + * Rick Richardson + * PC Research. Inc. + * 94 Apple Orchard Drive + * Tinton Falls, NJ 07724 + * Phone: (201) 834-1378 (9-17 EST) + * UUCP: ...!uunet!pcrat!rick + * + * Please send results to Rick Richardson and/or Reinhold Weicker. + * Complete information should be given on hardware and software + * used. Hardware information includes: Machine type, CPU, type and + * size of caches; for microprocessors: clock frequency, memory speed + * (number of wait states). Software information includes: Compiler + * (and runtime library) manufacturer and version, compilation + * switches, OS version. The Operating System version may give an + * indication about the compiler; Dhrystone itself performs no OS + * calls in the measurement loop. + * + * The complete output generated by the program should be mailed + * such that at least some checks for correctness can be made. + * + ************************************************************************* + * + * History: This version C/2.1 has been made for two reasons: + * + * 1) There is an obvious need for a common C version of + * Dhrystone, since C is at present the most popular system + * programming language for the class of processors + * (microcomputers, minicomputers) where Dhrystone is used + * most. There should be, as far as possible, only one C + * version of Dhrystone such that results can be compared + * without restrictions. In the past, the C versions + * distributed by Rick Richardson (Version 1.1) and by + * Reinhold Weicker had small (though not significant) + * differences. + * + * 2) As far as it is possible without changes to the + * Dhrystone statistics, optimizing compilers should be + * prevented from removing significant statements. + * + * This C version has been developed in cooperation with + * Rick Richardson (Tinton Falls, NJ), it incorporates many + * ideas from the "Version 1.1" distributed previously by + * him over the UNIX network Usenet. + * I also thank Chaim Benedelac (National Semiconductor), + * David Ditzel (SUN), Earl Killian and John Mashey (MIPS), + * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley) + * for their help with comments on earlier versions of the + * benchmark. + * + * Changes: In the initialization part, this version follows mostly + * Rick Richardson's version distributed via Usenet, not the + * version distributed earlier via floppy disk by Reinhold + * Weicker. As a concession to older compilers, names have + * been made unique within the first 8 characters. Inside the + * measurement loop, this version follows the version + * previously distributed by Reinhold Weicker. + * + * At several places in the benchmark, code has been added, + * but within the measurement loop only in branches that + * are not executed. The intention is that optimizing + * compilers should be prevented from moving code out of the + * measurement loop, or from removing code altogether. Since + * the statements that are executed within the measurement + * loop have NOT been changed, the numbers defining the + * "Dhrystone distribution" (distribution of statements, + * operand types and locality) still hold. Except for + * sophisticated optimizing compilers, execution times for + * this version should be the same as for previous versions. + * + * Since it has proven difficult to subtract the time for the + * measurement loop overhead in a correct way, the loop check + * has been made a part of the benchmark. This does have + * an impact - though a very minor one - on the distribution + * statistics which have been updated for this version. + * + * All changes within the measurement loop are described + * and discussed in the companion paper "Rationale for + * Dhrystone version 2". + * + * Because of the self-imposed limitation that the order and + * distribution of the executed statements should not be + * changed, there are still cases where optimizing compilers + * may not generate code for some statements. To a certain + * degree, this is unavoidable for small synthetic + * benchmarks. Users of the benchmark are advised to check + * code listings whether code is generated for all statements + * of Dhrystone. + * + * Version 2.1 is identical to version 2.0 distributed via + * the UNIX network Usenet in March 1988 except that it + * corrects some minor deficiencies that were found by users + * of version 2.0. The only change within the measurement + * loop is that a non-executed "else" part was added to the + * "if" statement in Func_3, and a non-executed "else" part + * removed from Proc_3. + * + ************************************************************************* + * + * Defines: The following "Defines" are possible: + * -DROPT (default: Not defined) + * As an approximation to what an average C + * programmer might do, the "register" storage class + * is applied (if enabled by -DROPT) + * - for local variables, if they are used + * (dynamically) five or more times + * - for parameters if they are used (dynamically) + * six or more times + * Note that an optimal "register" strategy is + * compiler-dependent, and that "register" + * declarations do not necessarily lead to faster + * execution. + * -DNOSTRUCTASSIGN (default: Not defined) + * Define if the C compiler does not support + * assignment of structures. + * -DNOENUMS (default: Not defined) + * Define if the C compiler does not support + * enumeration types. + * + ************************************************************************* + * + * Compilation model and measurement (IMPORTANT): + * + * This C version of Dhrystone consists of three files: + * - dhry.h (this file, containing global definitions and comments) + * - dhry_1.c (containing the code corresponding to Ada package Pack_1) + * - dhry_2.c (containing the code corresponding to Ada package Pack_2) + * + * The following "ground rules" apply for measurements: + * - Separate compilation + * - No procedure merging + * - Otherwise, compiler optimizations are allowed but should be + * indicated + * - Default results are those without register declarations + * See the companion paper "Rationale for Dhrystone Version 2" for a more + * detailed discussion of these ground rules. + * + * For 16-Bit processors (e.g. 80186, 80286), times for all compilation + * models ("small", "medium", "large" etc.) should be given if possible, + * together with a definition of these models for the compiler system + * used. + * + ************************************************************************* + * + * Dhrystone (C version) statistics: + * + * [Comment from the first distribution, updated for version 2. + * Note that because of language differences, the numbers are slightly + * different from the Ada version.] + * + * The following program contains statements of a high level programming + * language (here: C) in a distribution considered representative: + * + * assignments 52 (51.0 %) + * control statements 33 (32.4 %) + * procedure, function calls 17 (16.7 %) + * + * 103 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * + * - statement type + * - operand type + * - operand locality + * operand global, local, parameter, or constant. + * + * The combination of these three aspects is balanced only approximately. + * + * 1. Statement Type: + * ----------------- number + * + * V1 = V2 9 + * (incl. V1 = F(..) + * V = Constant 12 + * Assignment, 7 + * with array element + * Assignment, 6 + * with record component + * -- + * 34 34 + * + * X = Y +|-|"&&"|"|" Z 5 + * X = Y +|-|"==" Constant 6 + * X = X +|- 1 3 + * X = Y *|/ Z 2 + * X = Expression, 1 + * two operators + * X = Expression, 1 + * three operators + * -- + * 18 18 + * + * if .... 14 + * with "else" 7 + * without "else" 7 + * executed 3 + * not executed 4 + * for ... 7 | counted every time + * while ... 4 | the loop condition + * do ... while 1 | is evaluated + * switch ... 1 + * break 1 + * declaration with 1 + * initialization + * -- + * 34 34 + * + * P (...) procedure call 11 + * user procedure 10 + * library procedure 1 + * X = F (...) + * function call 6 + * user function 5 + * library function 1 + * -- + * 17 17 + * --- + * 103 + * + * The average number of parameters in procedure or function calls + * is 1.82 (not counting the function values as implicit parameters). + * + * + * 2. Operators + * ------------ + * number approximate + * percentage + * + * Arithmetic 32 50.8 + * + * + 21 33.3 + * - 7 11.1 + * * 3 4.8 + * / (int div) 1 1.6 + * + * Comparison 27 42.8 + * + * == 9 14.3 + * /= 4 6.3 + * > 1 1.6 + * < 3 4.8 + * >= 1 1.6 + * <= 9 14.3 + * + * Logic 4 6.3 + * + * && (AND-THEN) 1 1.6 + * | (OR) 1 1.6 + * ! (NOT) 2 3.2 + * + * -- ----- + * 63 100.1 + * + * + * 3. Operand Type (counted once per operand reference): + * --------------- + * number approximate + * percentage + * + * Integer 175 72.3 % + * Character 45 18.6 % + * Pointer 12 5.0 % + * String30 6 2.5 % + * Array 2 0.8 % + * Record 2 0.8 % + * --- ------- + * 242 100.0 % + * + * When there is an access path leading to the final operand (e.g. a + * record component), only the final data type on the access path is + * counted. + * + * + * 4. Operand Locality: + * ------------------- + * number approximate + * percentage + * + * local variable 114 47.1 % + * global variable 22 9.1 % + * parameter 45 18.6 % + * value 23 9.5 % + * reference 22 9.1 % + * function result 6 2.5 % + * constant 55 22.7 % + * --- ------- + * 242 100.0 % + * + * + * The program does not compute anything meaningful, but it is + * syntactically and semantically correct. All variables have a value + * assigned to them before they are used as a source operand. + * + * There has been no explicit effort to account for the effects of a + * cache, or to balance the use of long or short displacements for code + * or data. + * + ************************************************************************* + */ + +import std.c.stdio; +import std.c.string; +import std.c.stdlib; +import std.string; + +/* Compiler and system dependent definitions: */ + +const double Mic_secs_Per_Second = 1000000.0; + +/* Berkeley UNIX C returns process times in seconds/HZ */ + +enum { Ident_1, Ident_2, Ident_3, Ident_4, Ident_5 } +alias int Enumeration; + +/* for boolean and enumeration types in Ada, Pascal */ + +/* General definitions: */ + +const int StrLen = 30; + +alias int One_Thirty; +alias int One_Fifty; +alias char Capital_Letter; +alias bool Boolean; +alias char Str_30 [StrLen]; +alias int Arr_1_Dim [50]; +alias int Arr_2_Dim [50] [50]; + +struct record +{ + record *Ptr_Comp; + Enumeration Discr; + union V + { + struct V1 + { + Enumeration Enum_Comp; + int Int_Comp; + char Str_Comp [StrLen]; + } + V1 var_1; + struct V2 + { + Enumeration E_Comp_2; + char Str_2_Comp [StrLen]; + } + V2 var_2; + struct V3 + { + char Ch_1_Comp; + char Ch_2_Comp; + } + V3 var_3; + } + V variant; +} + +alias record Rec_Type; +alias record *Rec_Pointer; + +/* Global Variables: */ + +Rec_Pointer Ptr_Glob, + Next_Ptr_Glob; +int Int_Glob; +Boolean Bool_Glob; +char Ch_1_Glob, + Ch_2_Glob; +int Arr_1_Glob [50]; +int Arr_2_Glob [50] [50]; + +char[StrLen] Reg_Define = "Register option selected."; + +/* variables for time measurement: */ + +const int Too_Small_Time = 2; + +/* Measurements should last at least 2 seconds */ + +double Begin_Time, + End_Time, + User_Time; + +double Microseconds, + Dhrystones_Per_Second, + Vax_Mips; + +/* end of variables for time measurement */ +void main() + +/*****/ + +/* main program, corresponds to procedures */ +/* Main and Proc_0 in the Ada version */ +{ + One_Fifty Int_1_Loc; + One_Fifty Int_2_Loc; + One_Fifty Int_3_Loc; + char Ch_Index; + Enumeration Enum_Loc; + Str_30 Str_1_Loc; + Str_30 Str_2_Loc; + int Run_Index; + int Number_Of_Runs; + + FILE *Ap; + + /* Initializations */ + + if ((Ap = fopen("dhry.res", "a+")) == null) + { + printf("Can not open dhry.res\n\n"); + exit(1); + } + + Next_Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof); + Ptr_Glob = cast(Rec_Pointer) malloc (Rec_Type.sizeof); + + Ptr_Glob.Ptr_Comp = Next_Ptr_Glob; + Ptr_Glob.Discr = Ident_1; + Ptr_Glob.variant.var_1.Enum_Comp = Ident_3; + Ptr_Glob.variant.var_1.Int_Comp = 40; + + // strcpy (Ptr_Glob.variant.var_1.Str_Comp, + // "DHRYSTONE PROGRAM, SOME STRING"); + // strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + Ptr_Glob.variant.var_1.Str_Comp[] = "DHRYSTONE PROGRAM, SOME STRING"; + Str_1_Loc[] = "DHRYSTONE PROGRAM, 1'ST STRING"; + + Arr_2_Glob [8][7] = 10; + + /* Was missing in published program. Without this statement, */ + /* Arr_2_Glob [8][7] would have an undefined value. */ + /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ + /* overflow may occur for this array element. */ + + printf ("\n"); + printf ("Dhrystone Benchmark, Version 2.1 (Language: D)\n"); + printf ("\n"); + printf ("Please give the number of runs through the benchmark: "); + { + int n; + + // scanf ("%d", &n); + n = 10000000; + Number_Of_Runs = n; + } + printf ("\n"); + + printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); + + /***************/ + /* Start timer */ + /***************/ + + Begin_Time = dtime(); + + for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index) + { + Proc_5(); + Proc_4(); + + /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */ + Int_1_Loc = 2; + Int_2_Loc = 3; + + // strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); + Str_2_Loc[] = "DHRYSTONE PROGRAM, 2'ND STRING"; + Enum_Loc = Ident_2; + Bool_Glob = !Func_2 (Str_1_Loc, Str_2_Loc); + + /* Bool_Glob == 1 */ + while (Int_1_Loc < Int_2_Loc) /* loop body executed once */ + { + Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc; + + /* Int_3_Loc == 7 */ + Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc); + + /* Int_3_Loc == 7 */ + Int_1_Loc += 1; + } /* while */ + + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc); + + /* Int_Glob == 5 */ + Proc_1 (Ptr_Glob); + + for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index) + { + /* loop body executed twice */ + if (Enum_Loc == Func_1 (Ch_Index, 'C')) + { + /* then, not executed */ + Proc_6 (Ident_1, &Enum_Loc); + + // strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING"); + Str_2_Loc[] = "DHRYSTONE PROGRAM, 3'RD STRING"; + Int_2_Loc = Run_Index; + Int_Glob = Run_Index; + } + } + + /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */ + Int_2_Loc = Int_2_Loc * Int_1_Loc; + Int_1_Loc = Int_2_Loc / Int_3_Loc; + Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc; + + /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */ + Proc_2 (&Int_1_Loc); + + /* Int_1_Loc == 5 */ + } /* loop "for Run_Index" */ + + /**************/ + /* Stop timer */ + /**************/ + + End_Time = dtime(); + + printf ("Execution ends\n"); + printf ("\n"); + printf ("Final values of the variables used in the benchmark:\n"); + printf ("\n"); + printf ("Int_Glob: %d\n", Int_Glob); + printf (" should be: %d\n", 5); + printf ("Bool_Glob: %d\n", Bool_Glob); + printf (" should be: %d\n", 1); + printf ("Ch_1_Glob: %c\n", Ch_1_Glob); + printf (" should be: %c\n", cast(int) 'A'); + printf ("Ch_2_Glob: %c\n", Ch_2_Glob); + printf (" should be: %c\n", cast(int) 'B'); + printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]); + printf (" should be: %d\n", 7); + printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]); + printf (" should be: Number_Of_Runs + 10\n"); + printf ("Ptr_Glob.\n"); + printf (" Ptr_Comp: %d\n", cast(int) Ptr_Glob.Ptr_Comp); + printf (" should be: (implementation-dependent)\n"); + printf (" Discr: %d\n", Ptr_Glob.Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Ptr_Glob.variant.var_1.Enum_Comp); + printf (" should be: %d\n", 2); + printf (" Int_Comp: %d\n", Ptr_Glob.variant.var_1.Int_Comp); + printf (" should be: %d\n", 17); + printf (" Str_Comp: %.*s\n", Ptr_Glob.variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Next_Ptr_Glob.\n"); + printf (" Ptr_Comp: %d\n", cast(int) Next_Ptr_Glob.Ptr_Comp); + printf (" should be: (implementation-dependent), same as above\n"); + printf (" Discr: %d\n", Next_Ptr_Glob.Discr); + printf (" should be: %d\n", 0); + printf (" Enum_Comp: %d\n", Next_Ptr_Glob.variant.var_1.Enum_Comp); + printf (" should be: %d\n", 1); + printf (" Int_Comp: %d\n", Next_Ptr_Glob.variant.var_1.Int_Comp); + printf (" should be: %d\n", 18); + printf (" Str_Comp: %.*s\n", Next_Ptr_Glob.variant.var_1.Str_Comp); + printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n"); + printf ("Int_1_Loc: %d\n", Int_1_Loc); + printf (" should be: %d\n", 5); + printf ("Int_2_Loc: %d\n", Int_2_Loc); + printf (" should be: %d\n", 13); + printf ("Int_3_Loc: %d\n", Int_3_Loc); + printf (" should be: %d\n", 7); + printf ("Enum_Loc: %d\n", Enum_Loc); + printf (" should be: %d\n", 1); + printf ("Str_1_Loc: %.*s\n", Str_1_Loc); + printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n"); + printf ("Str_2_Loc: %.*s\n", Str_2_Loc); + printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); + printf ("\n"); + + User_Time = End_Time - Begin_Time; + + if (User_Time < Too_Small_Time) + { + printf ("Measured time too small to obtain meaningful results\n"); + printf ("Please increase number of runs\n"); + printf ("\n"); + } + else + { + Microseconds = User_Time * Mic_secs_Per_Second + / cast(double) Number_Of_Runs; + Dhrystones_Per_Second = cast(double) Number_Of_Runs / User_Time; + Vax_Mips = Dhrystones_Per_Second / 1757.0; + + printf ("Register option selected? NO\n"); + strcpy(Reg_Define.ptr, "Register option not selected."); + printf ("Microseconds for one run through Dhrystone: "); + printf ("%7.1lf \n", Microseconds); + printf ("Dhrystones per Second: "); + printf ("%10.1lf \n", Dhrystones_Per_Second); + printf ("VAX MIPS rating = %10.3lf \n", Vax_Mips); + printf ("\n"); + + fprintf(Ap, "\n"); + fprintf(Ap, "Dhrystone Benchmark, Version 2.1 (Language: D)\n"); + fprintf(Ap, "%.*s\n", Reg_Define); + fprintf(Ap, "Microseconds for one loop: %7.1lf\n", Microseconds); + fprintf(Ap, "Dhrystones per second: %10.1lf\n", Dhrystones_Per_Second); + fprintf(Ap, "VAX MIPS rating: %10.3lf\n", Vax_Mips); + fclose(Ap); + } +} + +void Proc_1(Rec_Pointer Ptr_Val_Par) + +/******************/ + +/* executed once */ +{ + Rec_Pointer Next_Record = Ptr_Val_Par.Ptr_Comp; + + /* == Ptr_Glob_Next */ + /* Local variable, initialized with Ptr_Val_Par.Ptr_Comp, */ + /* corresponds to "rename" in Ada, "with" in Pascal */ + + *Ptr_Val_Par.Ptr_Comp = *Ptr_Glob; + Ptr_Val_Par.variant.var_1.Int_Comp = 5; + Next_Record.variant.var_1.Int_Comp + = Ptr_Val_Par.variant.var_1.Int_Comp; + Next_Record.Ptr_Comp = Ptr_Val_Par.Ptr_Comp; + Proc_3 (&Next_Record.Ptr_Comp); + + /* Ptr_Val_Par.Ptr_Comp.Ptr_Comp + == Ptr_Glob.Ptr_Comp */ + if (Next_Record.Discr == Ident_1) + { + /* then, executed */ + Next_Record.variant.var_1.Int_Comp = 6; + Proc_6 (Ptr_Val_Par.variant.var_1.Enum_Comp, + &Next_Record.variant.var_1.Enum_Comp); + Next_Record.Ptr_Comp = Ptr_Glob.Ptr_Comp; + Proc_7 (Next_Record.variant.var_1.Int_Comp, 10, + &Next_Record.variant.var_1.Int_Comp); + } + else /* not executed */ + *Ptr_Val_Par = *Ptr_Val_Par.Ptr_Comp; +} /* Proc_1 */ +void Proc_2(One_Fifty *Int_Par_Ref) + +/******************/ +/* executed once */ +/* *Int_Par_Ref == 1, becomes 4 */ +{ + One_Fifty Int_Loc; + Enumeration Enum_Loc; + + Int_Loc = *Int_Par_Ref + 10; + + do /* executed once */ + if (Ch_1_Glob == 'A') + { + /* then, executed */ + Int_Loc -= 1; + *Int_Par_Ref = Int_Loc - Int_Glob; + Enum_Loc = Ident_1; + } + + /* if */ + while (Enum_Loc != Ident_1); /* true */ +} /* Proc_2 */ +void Proc_3(Rec_Pointer *Ptr_Ref_Par) + +/******************/ +/* executed once */ +/* Ptr_Ref_Par becomes Ptr_Glob */ +{ + if (Ptr_Glob != null) + /* then, executed */ + *Ptr_Ref_Par = Ptr_Glob.Ptr_Comp; + + Proc_7 (10, Int_Glob, &Ptr_Glob.variant.var_1.Int_Comp); +} /* Proc_3 */ +void Proc_4() /* without parameters */ +/*******/ +/* executed once */ +{ + Boolean Bool_Loc; + + Bool_Loc = Ch_1_Glob == 'A'; + Bool_Glob = Bool_Loc | Bool_Glob; + Ch_2_Glob = 'B'; +} /* Proc_4 */ +void Proc_5() /* without parameters */ +/*******/ +/* executed once */ +{ + Ch_1_Glob = 'A'; + Bool_Glob = false; +} /* Proc_5 */ +void Proc_6(Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par) + +/*********************************/ +/* executed once */ +/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */ +{ + *Enum_Ref_Par = Enum_Val_Par; + + if (!Func_3 (Enum_Val_Par)) + /* then, not executed */ + *Enum_Ref_Par = Ident_4; + + switch (Enum_Val_Par) + { + case Ident_1: + *Enum_Ref_Par = Ident_1; + break; + + case Ident_2: + + if (Int_Glob > 100) + /* then */ + *Enum_Ref_Par = Ident_1; + else *Enum_Ref_Par = Ident_4; + + break; + + case Ident_3: /* executed */ + *Enum_Ref_Par = Ident_2; + break; + + case Ident_4: + break; + + case Ident_5: + *Enum_Ref_Par = Ident_3; + break; + + default: + } /* switch */ + +} /* Proc_6 */ +void Proc_7(One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref) + +/**********************************************/ +/* executed three times */ +/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ +/* Int_Par_Ref becomes 7 */ +/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ +/* Int_Par_Ref becomes 17 */ +/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */ +/* Int_Par_Ref becomes 18 */ +{ + One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 2; + *Int_Par_Ref = Int_2_Par_Val + Int_Loc; +} /* Proc_7 */ +void Proc_8(ref Arr_1_Dim Arr_1_Par_Ref, ref Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val) + +/*********************************************************************/ +/* executed once */ +/* Int_Par_Val_1 == 3 */ +/* Int_Par_Val_2 == 7 */ +{ + One_Fifty Int_Index; + One_Fifty Int_Loc; + + Int_Loc = Int_1_Par_Val + 5; + Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val; + Arr_1_Par_Ref [Int_Loc + 1] = Arr_1_Par_Ref [Int_Loc]; + Arr_1_Par_Ref [Int_Loc + 30] = Int_Loc; + + for (Int_Index = Int_Loc; Int_Index <= Int_Loc + 1; ++Int_Index) + Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc; + + Arr_2_Par_Ref [Int_Loc] [Int_Loc - 1] += 1; + Arr_2_Par_Ref [Int_Loc + 20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc]; + Int_Glob = 5; +} /* Proc_8 */ +Enumeration Func_1(Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) + +/*************************************************/ +/* executed three times */ +/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */ +/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */ +/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */ +{ + Capital_Letter Ch_1_Loc; + Capital_Letter Ch_2_Loc; + + Ch_1_Loc = Ch_1_Par_Val; + Ch_2_Loc = Ch_1_Loc; + + if (Ch_2_Loc != Ch_2_Par_Val) + /* then, executed */ + return (Ident_1); + else /* not executed */ + { + Ch_1_Glob = Ch_1_Loc; + return (Ident_2); + } +} /* Func_1 */ +Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref) + +/*************************************************/ +/* executed once */ +/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */ +/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */ +{ + One_Thirty Int_Loc; + Capital_Letter Ch_Loc; + + Int_Loc = 2; + + while (Int_Loc <= 2) /* loop body executed once */ + if (Func_1 (Str_1_Par_Ref[Int_Loc], + Str_2_Par_Ref[Int_Loc + 1]) == Ident_1) + { + /* then, executed */ + Ch_Loc = 'A'; + Int_Loc += 1; + } + + /* if, while */ + + if (Ch_Loc >= 'W' && Ch_Loc < 'Z') + /* then, not executed */ + Int_Loc = 7; + + if (Ch_Loc == 'R') + /* then, not executed */ + return (true); + else /* executed */ + { + // if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0) + // if (memcmp (Str_1_Par_Ref, Str_2_Par_Ref, 30) > 0) + if (Str_1_Par_Ref > Str_2_Par_Ref) + { + /* then, not executed */ + Int_Loc += 7; + Int_Glob = Int_Loc; + return (true); + } + else /* executed */ + return (false); + } /* if Ch_Loc */ + +} /* Func_2 */ +Boolean Func_3(Enumeration Enum_Par_Val) + +/***************************/ +/* executed once */ +/* Enum_Par_Val == Ident_3 */ +{ + Enumeration Enum_Loc; + + Enum_Loc = Enum_Par_Val; + + if (Enum_Loc == Ident_3) + /* then, executed */ + return (true); + else /* not executed */ + return (false); +} /* Func_3 */ + +version (Win32) +{ + import std.c.windows.windows; + + double dtime() + { + double q; + + q = cast(double) GetTickCount() * 1.0e-03; + + return q; + } +} + +version (linux) +{ + import std.c.linux.linux; + + double dtime() + { + double q; + + q = cast(double) time(null); + + return q; + } +} + +version (OSX) // supplied by Anders F Bjorklund +{ + import std.c.linux.linux; + + double dtime() + { + double q; + timeval tv; + + gettimeofday(&tv, null); + q = cast(double) tv.tv_sec + cast(double) tv.tv_usec * 1.0e-6; + + return q; + } +} diff --git a/samples/dserver.d b/samples/dserver.d new file mode 100644 index 000000000000..3b8d17b08b24 --- /dev/null +++ b/samples/dserver.d @@ -0,0 +1,412 @@ + +/* + * Hello Object DLL Self-Registering Server + * Heavily modified from: + */ +/* + * SELFREG.CPP + * Server Self-Registrtation Utility, Chapter 5 + * + * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved + * + * Kraig Brockschmidt, Microsoft + * Internet : kraigb@microsoft.com + * Compuserve: >INTERNET:kraigb@microsoft.com + */ + +import std.c.stdio; +import std.c.stdlib; +import std.c.string; +import std.string; +import std.c.windows.windows; +import std.c.windows.com; + +import chello; + +// This class factory object creates Hello objects. + +class CHelloClassFactory : ComObject, IClassFactory +{ +public: + this() + { + MessageBoxA(null, "CHelloClassFactory()", null, MB_OK); + } + + ~this() + { + MessageBoxA(null, "~CHelloClassFactory()", null, MB_OK); + } + + extern (Windows) : + + // IUnknown members + HRESULT QueryInterface(const (IID)*riid, LPVOID *ppv) + { + MessageBoxA(null, "CHelloClassFactory.QueryInterface()", null, MB_OK); + + if (IID_IUnknown == *riid) + { + MessageBoxA(null, "IUnknown", null, MB_OK); + *ppv = cast(void*) cast(IUnknown) this; + } + else if (IID_IClassFactory == *riid) + { + MessageBoxA(null, "IClassFactory", null, MB_OK); + *ppv = cast(void*) cast(IClassFactory) this; + } + else + { + *ppv = null; + return E_NOINTERFACE; + } + + AddRef(); + return NOERROR; + } + + // IClassFactory members + HRESULT CreateInstance(IUnknown pUnkOuter, IID*riid, LPVOID *ppvObj) + { + CHello pObj; + HRESULT hr; + + MessageBoxA(null, "CHelloClassFactory.CreateInstance()", null, MB_OK); + *ppvObj = null; + hr = E_OUTOFMEMORY; + + // Verify that a controlling unknown asks for IUnknown + if (null !is pUnkOuter && memcmp(&IID_IUnknown, riid, IID.sizeof)) + return CLASS_E_NOAGGREGATION; + + // Create the object passing function to notify on destruction. + pObj = new CHello(pUnkOuter, &ObjectDestroyed); + + if (!pObj) + return hr; + + if (pObj.Init()) + { + hr = pObj.QueryInterface(riid, ppvObj); + } + + // Kill the object if initial creation or Init failed. + if (FAILED(hr)) + delete pObj; + else + g_cObj++; + + return hr; + } + + HRESULT LockServer(BOOL fLock) + { + MessageBoxA(null, "CHelloClassFactory.LockServer()", null, MB_OK); + + if (fLock) + g_cLock++; + else + g_cLock--; + + return NOERROR; + } +}; + +// Count number of objects and number of locks. +ULONG g_cObj =0; +ULONG g_cLock=0; + +HINSTANCE g_hInst; + +extern (C) +{ +void *_atopsp; +void gc_init(); +void gc_term(); +void _minit(); +void _moduleCtor(); +void _moduleUnitTests(); +} + +extern (Windows) : + +BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) +{ + // _atopsp = (void*)&hInstance; + + switch (ulReason) + { + case DLL_PROCESS_ATTACH: + gc_init(); + _minit(); + _moduleCtor(); + + // _moduleUnitTests(); + MessageBoxA(null, "ATTACH", null, MB_OK); + break; + + case DLL_PROCESS_DETACH: + MessageBoxA(null, "DETACH", null, MB_OK); + gc_term(); + break; + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + + // Multiple threads not supported yet + MessageBoxA(null, "THREAD", null, MB_OK); + return false; + + default: + assert(0); + } + + g_hInst=hInstance; + return true; +} + +/* + * DllGetClassObject + * + * Purpose: + * Provides an IClassFactory for a given CLSID that this DLL is + * registered to support. This DLL is placed under the CLSID + * in the registration database as the InProcServer. + * + * Parameters: + * clsID REFCLSID that identifies the class factory + * desired. Since this parameter is passed this + * DLL can handle any number of objects simply + * by returning different class factories here + * for different CLSIDs. + * + * riid REFIID specifying the interface the caller wants + * on the class object, usually IID_ClassFactory. + * + * ppv LPVOID * in which to return the interface + * pointer. + * + * Return Value: + * HRESULT NOERROR on success, otherwise an error code. + */ +HRESULT DllGetClassObject(CLSID*rclsid, IID*riid, LPVOID *ppv) +{ + HRESULT hr; + CHelloClassFactory pObj; + + MessageBoxA(null, "DllGetClassObject()", null, MB_OK); + + // printf("DllGetClassObject()\n"); + + if (CLSID_Hello != *rclsid) + return E_FAIL; + + pObj = new CHelloClassFactory(); + + if (!pObj) + return E_OUTOFMEMORY; + + hr = pObj.QueryInterface(riid, ppv); + + if (FAILED(hr)) + delete pObj; + + return hr; +} + +/* + * Answers if the DLL can be freed, that is, if there are no + * references to anything this DLL provides. + * + * Return Value: + * BOOL true if nothing is using us, false otherwise. + */ +HRESULT DllCanUnloadNow() +{ + SCODE sc; + + MessageBoxA(null, "DllCanUnloadNow()", null, MB_OK); + + // Any locks or objects? + sc = (0 == g_cObj && 0 == g_cLock) ? S_OK : S_FALSE; + return sc; +} + +/* + * Instructs the server to create its own registry entries + * + * Return Value: + * HRESULT NOERROR if registration successful, error + * otherwise. + */ +HRESULT DllRegisterServer() +{ + char szID[128]; + char szCLSID[128]; + char szModule[512]; + + MessageBoxA(null, "DllRegisterServer()", null, MB_OK); + + // Create some base key strings. + StringFromGUID2(&CLSID_Hello, cast(LPOLESTR) szID, 128); + unicode2ansi(szID.ptr); + strcpy(szCLSID.ptr, "CLSID\\"); + strcat(szCLSID.ptr, szID.ptr); + + // Create ProgID keys + SetKeyAndValue("Hello1.0", null, "Hello Object"); + SetKeyAndValue("Hello1.0", "CLSID", szID.ptr); + + // Create VersionIndependentProgID keys + SetKeyAndValue("Hello", null, "Hello Object"); + SetKeyAndValue("Hello", "CurVer", "Hello1.0"); + SetKeyAndValue("Hello", "CLSID", szID.ptr); + + // Create entries under CLSID + SetKeyAndValue(szCLSID.ptr, null, "Hello Object"); + SetKeyAndValue(szCLSID.ptr, "ProgID", "Hello1.0"); + SetKeyAndValue(szCLSID.ptr, "VersionIndependentProgID", "Hello"); + SetKeyAndValue(szCLSID.ptr, "NotInsertable", null); + + GetModuleFileNameA(g_hInst, szModule.ptr, szModule.length); + + SetKeyAndValue(szCLSID.ptr, "InprocServer32", szModule.ptr); + return NOERROR; +} + +/* + * Purpose: + * Instructs the server to remove its own registry entries + * + * Return Value: + * HRESULT NOERROR if registration successful, error + * otherwise. + */ +HRESULT DllUnregisterServer() +{ + char szID[128]; + char szCLSID[128]; + char szTemp[256]; + + MessageBoxA(null, "DllUnregisterServer()", null, MB_OK); + + // Create some base key strings. + StringFromGUID2(&CLSID_Hello, cast(LPOLESTR) szID, 128); + unicode2ansi(szID.ptr); + strcpy(szCLSID.ptr, "CLSID\\"); + strcat(szCLSID.ptr, szID.ptr); + + RegDeleteKeyA(HKEY_CLASSES_ROOT, "Hello\\CurVer"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, "Hello\\CLSID"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, "Hello"); + + RegDeleteKeyA(HKEY_CLASSES_ROOT, "Hello1.0\\CLSID"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, "Hello1.0"); + + strcpy(szTemp.ptr, szCLSID.ptr); + strcat(szTemp.ptr, "\\"); + strcat(szTemp.ptr, "ProgID"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp.ptr); + + strcpy(szTemp.ptr, szCLSID.ptr); + strcat(szTemp.ptr, "\\"); + strcat(szTemp.ptr, "VersionIndependentProgID"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp.ptr); + + strcpy(szTemp.ptr, szCLSID.ptr); + strcat(szTemp.ptr, "\\"); + strcat(szTemp.ptr, "NotInsertable"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp.ptr); + + strcpy(szTemp.ptr, szCLSID.ptr); + strcat(szTemp.ptr, "\\"); + strcat(szTemp.ptr, "InprocServer32"); + RegDeleteKeyA(HKEY_CLASSES_ROOT, szTemp.ptr); + + RegDeleteKeyA(HKEY_CLASSES_ROOT, szCLSID.ptr); + return NOERROR; +} + +/* + * SetKeyAndValue + * + * Purpose: + * Private helper function for DllRegisterServer that creates + * a key, sets a value, and closes that key. + * + * Parameters: + * pszKey LPTSTR to the name of the key + * pszSubkey LPTSTR ro the name of a subkey + * pszValue LPTSTR to the value to store + * + * Return Value: + * BOOL true if successful, false otherwise. + */ +BOOL SetKeyAndValue(LPCSTR pszKey, LPCSTR pszSubkey, LPCSTR pszValue) +{ + HKEY hKey; + char szKey[256]; + BOOL result; + + strcpy(szKey.ptr, pszKey); + + if (pszSubkey) + { + strcat(szKey.ptr, "\\"); + strcat(szKey.ptr, pszSubkey); + } + + result = true; + + if (ERROR_SUCCESS != RegCreateKeyExA(HKEY_CLASSES_ROOT, + szKey.ptr, 0, null, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, null, &hKey, null)) + result = false; + else + { + if (null != pszValue) + { + if (RegSetValueExA(hKey, null, 0, REG_SZ, cast(BYTE *) pszValue, + (strlen(pszValue) + 1) * char.sizeof) != ERROR_SUCCESS) + result = false; + } + + if (RegCloseKey(hKey) != ERROR_SUCCESS) + result = false; + } + + if (!result) + MessageBoxA(null, "SetKeyAndValue() failed", null, MB_OK); + + return result; +} + +/* + * ObjectDestroyed + * + * Purpose: + * Function for the Hello object to call when it gets destroyed. + * Since we're in a DLL we only track the number of objects here, + * letting DllCanUnloadNow take care of the rest. + */ + +extern (D) void ObjectDestroyed() +{ + MessageBoxA(null, "ObjectDestroyed()", null, MB_OK); + g_cObj--; +} + +void unicode2ansi(char *s) +{ + wchar *w; + + for (w = cast(wchar *) s; *w; w++) + *s++ = *w; + + *s = 0; +} + +extern (C) int printf(char *format, ...) +{ + return 0; +} diff --git a/samples/hello.d b/samples/hello.d new file mode 100644 index 000000000000..d0446afcfe24 --- /dev/null +++ b/samples/hello.d @@ -0,0 +1,13 @@ + +import std.stdio; + +void main(string[] args) +{ + writeln("hello world"); + writefln("args.length = %d", args.length); + + foreach (index, arg; args) + { + writefln("args[%d] = '%s'", index, arg); + } +} diff --git a/samples/htmlget.d b/samples/htmlget.d new file mode 100644 index 000000000000..6970e1dc1a8c --- /dev/null +++ b/samples/htmlget.d @@ -0,0 +1,124 @@ + +/* + HTMLget written by Christopher E. Miller + This code is public domain. + You may use it for any purpose. + This code has no warranties and is provided 'as-is'. + */ + +// debug = HTMLGET; + +import std.string, std.conv, std.stream; +import std.socket, std.socketstream; +import core.stdc.stdio; + +int main(char[][] args) +{ + if (args.length < 2) + { + printf("Usage:\n htmlget \n"); + return 0; + } + + char[] url = args[1]; + int i; + + i = std.string.find(url, "://"); + + if (i != -1) + { + if (icmp(url[0 .. i], "http")) + throw new Exception("http:// expected"); + } + + i = std.string.find(url, '#'); + + if (i != -1) // Remove anchor ref. + url = url[0 .. i]; + + i = std.string.find(url, '/'); + char[] domain; + + if (i == -1) + { + domain = url; + url = "/"; + } + else + { + domain = url[0 .. i]; + url = url[i .. url.length]; + } + + uint port; + i = std.string.find(domain, ':'); + + if (i == -1) + { + port = 80; // Default HTTP port. + } + else + { + port = std.conv.toUshort(domain[i + 1 .. domain.length]); + domain = domain[0 .. i]; + } + + debug (HTMLGET) + printf("Connecting to " ~ domain ~ " on port " ~ std.string.toString(port) ~ "...\n"); + + auto Socket sock = new TcpSocket(new InternetAddress(domain, port)); + Stream ss = new SocketStream(sock); + + debug (HTMLGET) + printf("Connected!\nRequesting URL \"" ~ url ~ "\"...\n"); + + if (port != 80) + domain = domain ~ ":" ~ std.string.toString(port); + + ss.writeString("GET " ~ url ~ " HTTP/1.1\r\n" + "Host: " ~ domain ~ "\r\n" + "\r\n"); + + // Skip HTTP header. + char[] line; + + for (;;) + { + line = ss.readLine(); + + if (!line.length) + break; + + const char[] CONTENT_TYPE_NAME = "Content-Type: "; + + if (line.length > CONTENT_TYPE_NAME.length && + !icmp(CONTENT_TYPE_NAME, line[0 .. CONTENT_TYPE_NAME.length])) + { + char[] type; + type = line[CONTENT_TYPE_NAME.length .. line.length]; + + if (type.length <= 5 || icmp("text/", type[0 .. 5])) + throw new Exception("URL is not text"); + } + } + +print_lines: + + while (!ss.eof()) + { + line = ss.readLine(); + printf("%.*s\n", line); + + // if(std.string.ifind(line, "") != -1) + // break; + size_t iw; + + for (iw = 0; iw != line.length; iw++) + { + if (!icmp("", line[iw .. line.length])) + break print_lines; + } + } + + return 0; +} diff --git a/samples/listener.d b/samples/listener.d new file mode 100644 index 000000000000..c3552f7ea1c1 --- /dev/null +++ b/samples/listener.d @@ -0,0 +1,133 @@ + +/* + D listener written by Christopher E. Miller + This code is public domain. + You may use it for any purpose. + This code has no warranties and is provided 'as-is'. + */ + +import std.conv; +import std.socket; + +int main(char[][] args) +{ + ushort port; + + if (args.length >= 2) + { + port = std.conv.toUshort(args[1]); + } + else + { + port = 4444; + } + + Socket listener = new TcpSocket; + assert(listener.isAlive); + listener.blocking = false; + listener.bind(new InternetAddress(port)); + listener.listen(10); + printf("Listening on port %d.\n", cast(int) port); + + const int MAX_CONNECTIONS = 60; + SocketSet sset = new SocketSet(MAX_CONNECTIONS + 1); // Room for listener. + Socket[] reads; + + for (;; sset.reset()) + { + sset.add(listener); + + foreach (Socket each; reads) + { + sset.add(each); + } + + Socket.select(sset, null, null); + + int i; + + for (i = 0;; i++) + { +next: + if (i == reads.length) + break; + + if (sset.isSet(reads[i])) + { + char[1024] buf; + int read = reads[i].receive(buf); + + if (Socket.ERROR == read) + { + printf("Connection error.\n"); + goto sock_down; + } + else if (0 == read) + { + try + { + // if the connection closed due to an error, remoteAddress() could fail + printf("Connection from %.*s closed.\n", reads[i].remoteAddress().toString()); + } + catch + { + } + +sock_down: + reads[i].close(); // release socket resources now + + // remove from -reads- + if (i != reads.length - 1) + reads[i] = reads[reads.length - 1]; + + reads = reads[0 .. reads.length - 1]; + + printf("\tTotal connections: %d\n", reads.length); + + goto next; // -i- is still the next index + } + else + { + printf("Received %d bytes from %.*s: \"%.*s\"\n", read, reads[i].remoteAddress().toString(), buf[0 .. read]); + } + } + } + + if (sset.isSet(listener)) // connection request + { + Socket sn; + try + { + if (reads.length < MAX_CONNECTIONS) + { + sn = listener.accept(); + printf("Connection from %.*s established.\n", sn.remoteAddress().toString()); + assert(sn.isAlive); + assert(listener.isAlive); + + reads ~= sn; + printf("\tTotal connections: %d\n", reads.length); + } + else + { + sn = listener.accept(); + printf("Rejected connection from %.*s; too many connections.\n", sn.remoteAddress().toString()); + assert(sn.isAlive); + + sn.close(); + assert(!sn.isAlive); + assert(listener.isAlive); + } + } + catch (Exception e) + { + printf("Error accepting: %.*s\n", e.toString()); + + if (sn) + sn.close(); + } + } + } + + return 0; +} diff --git a/samples/mydll/build.bat b/samples/mydll/build.bat new file mode 100644 index 000000000000..8e6f29a627c6 --- /dev/null +++ b/samples/mydll/build.bat @@ -0,0 +1,2 @@ +..\..\..\windows\bin\dmd -ofmydll.dll -L/IMPLIB mydll.d dll.d mydll.def +..\..\..\windows\bin\dmd test.d mydll.lib diff --git a/samples/mydll/dll.d b/samples/mydll/dll.d new file mode 100644 index 000000000000..b58e16ea3679 --- /dev/null +++ b/samples/mydll/dll.d @@ -0,0 +1,36 @@ + +// Public Domain + +import std.c.windows.windows; +import core.sys.windows.dll; + +__gshared HINSTANCE g_hInst; + +extern (Windows) +BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) +{ + switch (ulReason) + { + case DLL_PROCESS_ATTACH: + g_hInst = hInstance; + dll_process_attach( hInstance, true ); + break; + + case DLL_PROCESS_DETACH: + dll_process_detach( hInstance, true ); + break; + + case DLL_THREAD_ATTACH: + dll_thread_attach( true, true ); + break; + + case DLL_THREAD_DETACH: + dll_thread_detach( true, true ); + break; + + default: + assert(0); + } + + return true; +} diff --git a/samples/mydll/mydll.d b/samples/mydll/mydll.d new file mode 100644 index 000000000000..5f5112a45467 --- /dev/null +++ b/samples/mydll/mydll.d @@ -0,0 +1,5 @@ + +module mydll; +import std.c.stdio; + +export void dllprint() { printf("hello dll world\n"); } diff --git a/samples/mydll/mydll.def b/samples/mydll/mydll.def new file mode 100644 index 000000000000..c15d4bc8a46e --- /dev/null +++ b/samples/mydll/mydll.def @@ -0,0 +1,6 @@ +LIBRARY "mydll.dll" +EXETYPE NT +SUBSYSTEM WINDOWS +CODE SHARED EXECUTE +DATA WRITE + diff --git a/samples/mydll/mydll.di b/samples/mydll/mydll.di new file mode 100644 index 000000000000..b943b883346b --- /dev/null +++ b/samples/mydll/mydll.di @@ -0,0 +1 @@ +export void dllprint(); diff --git a/samples/mydll/test.d b/samples/mydll/test.d new file mode 100644 index 000000000000..0054e8b53e6b --- /dev/null +++ b/samples/mydll/test.d @@ -0,0 +1,8 @@ + +import mydll; + +int main() +{ + mydll.dllprint(); + return 0; +} diff --git a/samples/pi.d b/samples/pi.d new file mode 100644 index 000000000000..c26b0e739ec4 --- /dev/null +++ b/samples/pi.d @@ -0,0 +1,188 @@ + +import std.stdio; +import std.conv; +import std.c.stdlib; +import std.c.time; + +const int LONG_TIME = 4000; + +byte[] p; +byte[] t; +int q; + +int main(string[] args) +{ + int startime, endtime; + int i; + + if (args.length == 2) + { + q = to!int(args[1]); + } + else + { + writeln("Usage: pi [precision]"); + exit(55); + } + + if (q < 0) + { + writeln("Precision was too low, running with precision of 0."); + q = 0; + } + + if (q > LONG_TIME) + { + writeln("Be prepared to wait a while..."); + } + + // Compute one more digit than we display to compensate for rounding + q++; + + p.length = q + 1; + t.length = q + 1; + + /* compute pi */ + std.c.time.time(&startime); + arctan(2); + arctan(3); + mul4(); + std.c.time.time(&endtime); + + // Return to the number of digits we want to display + q--; + + /* print pi */ + + writef("pi = %d.", cast(int) (p[0])); + + for (i = 1; i <= q; i++) + writef("%d", cast(int) (p[i])); + + writeln(); + writefln("%s seconds to compute pi with a precision of %s digits.", endtime - startime, q); + + return 0; +} + +void arctan(int s) +{ + int n; + + t[0] = 1; + div(s); /* t[] = 1/s */ + add(); + n = 1; + + do + { + mul(n); + div(s * s); + div(n += 2); + + if (((n - 1) / 2) % 2 == 0) + add(); + else + sub(); + } while (!tiszero()); +} + +void add() +{ + int j; + + for (j = q; j >= 0; j--) + { + if (t[j] + p[j] > 9) + { + p[j] += t[j] - 10; + p[j - 1] += 1; + } + else + p[j] += t[j]; + } +} + +void sub() +{ + int j; + + for (j = q; j >= 0; j--) + { + if (p[j] < t[j]) + { + p[j] -= t[j] - 10; + p[j - 1] -= 1; + } + else + p[j] -= t[j]; + } + +} + +void mul(int multiplier) +{ + int b; + int i; + int carry = 0, digit = 0; + + for (i = q; i >= 0; i--) + { + b = (t[i] * multiplier + carry); + digit = b % 10; + carry = b / 10; + t[i] = cast(byte) digit; + } +} + +/* t[] /= l */ +void div(int divisor) +{ + int i, b; + int quotient, remainder = 0; + + foreach (ref x; t) + { + b = (10 * remainder + x); + quotient = b / divisor; + remainder = b % divisor; + x = cast(byte) quotient; + } +} + +void div4() +{ + int i, c, d = 0; + + for (i = 0; i <= q; i++) + { + c = (10 * d + p[i]) / 4; + d = (10 * d + p[i]) % 4; + p[i] = cast(byte) c; + } +} + +void mul4() +{ + int i, c, d; + + d = c = 0; + + for (i = q; i >= 0; i--) + { + d = (p[i] * 4 + c) % 10; + c = (p[i] * 4 + c) / 10; + p[i] = cast(byte) d; + } +} + +int tiszero() +{ + int k; + + for (k = 0; k <= q; k++) + if (t[k] != 0) + return false; + + return true; +} diff --git a/samples/sieve.d b/samples/sieve.d new file mode 100644 index 000000000000..628e0aa9a5b7 --- /dev/null +++ b/samples/sieve.d @@ -0,0 +1,41 @@ + +/* Eratosthenes Sieve prime number calculation. */ + +import std.stdio; + +bool flags[8191]; + +int main() +{ + int i, prime, k, count, iter; + + writefln("10 iterations"); + + for (iter = 1; + iter <= 10; + iter++) + { + count = 0; + flags[] = true; + + for (i = 0; i < flags.length; i++) + { + if (flags[i]) + { + prime = i + i + 3; + k = i + prime; + + while (k < flags.length) + { + flags[k] = false; + k += prime; + } + + count += 1; + } + } + } + + writefln("%d primes", count); + return 0; +} diff --git a/samples/wc.d b/samples/wc.d new file mode 100644 index 000000000000..a714f3df9c33 --- /dev/null +++ b/samples/wc.d @@ -0,0 +1,54 @@ + +import std.stdio; +import std.file; +import std.conv; + +int main(string[] args) +{ + int w_total; + int l_total; + int c_total; + + writeln(" lines words bytes file"); + + foreach (arg; args[1 .. $]) + { + string input; + int w_cnt, l_cnt, c_cnt; + int inword; + + input = to!string(std.file.read(arg)); + + foreach (char c; input) + { + if (c == '\n') + ++l_cnt; + + if (c != ' ') + { + if (!inword) + { + inword = 1; + ++w_cnt; + } + } + else + inword = 0; + + ++c_cnt; + } + + writefln("%8s%8s%8s %s\n", l_cnt, w_cnt, c_cnt, arg); + l_total += l_cnt; + w_total += w_cnt; + c_total += c_cnt; + } + + if (args.length > 2) + { + writefln("--------------------------------------\n%8s%8s%8s total", + l_total, w_total, c_total); + } + + return 0; +} diff --git a/samples/wc2.d b/samples/wc2.d new file mode 100644 index 000000000000..249cc74d2aaf --- /dev/null +++ b/samples/wc2.d @@ -0,0 +1,117 @@ +import std.stdio; +import std.stream; + +int main (string[] args) +{ + int w_total; + int l_total; + ulong c_total; + int[string] dictionary; + + writefln(" lines words bytes file"); + foreach (arg; args[1 .. $]) + { + int w_cnt, l_cnt; + bool inword; + auto c_cnt = std.file.getSize(arg); + + if (c_cnt < 10_000_000) + { + size_t wstart; + auto input = cast(string)std.file.read(arg); + + foreach (j, c; input) + { + if (c == '\n') + ++l_cnt; + if (c >= '0' && c <= '9') + { + } + else if (c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z') + { + if (!inword) + { + wstart = j; + inword = true; + ++w_cnt; + } + } + else if (inword) + { + auto word = input[wstart .. j]; + dictionary[word]++; + inword = false; + } + } + if (inword) + { + auto w = input[wstart .. input.length]; + dictionary[w]++; + } + } + else + { + auto f = new BufferedFile(arg); + string buf; + + while (!f.eof()) + { + char c; + f.read(c); + + if (c == '\n') + ++l_cnt; + + if (c >= '0' && c <= '9') + { + if (inword) + buf ~= c; + } + else if (c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z') + { + if (!inword) + { + buf.length = 0; + buf ~= c; + inword = 1; + ++w_cnt; + } + else + buf ~= c; + } + else if (inword) + { + if (++dictionary[buf] == 1) + buf = null; + inword = 0; + } + } + + if (inword) + { + dictionary[buf]++; + } + } + + writefln("%8s%8s%8s %s\n", l_cnt, w_cnt, c_cnt, arg); + l_total += l_cnt; + w_total += w_cnt; + c_total += c_cnt; + } + + if (args.length > 2) + { + writefln("--------------------------------------\n%8s%8s%8s total", + l_total, w_total, c_total); + } + + writefln("--------------------------------------"); + + foreach (word1; dictionary.keys.sort) + { + writefln("%3s %s", dictionary[word1], word1); + } + return 0; +} diff --git a/samples/winsamp.d b/samples/winsamp.d new file mode 100644 index 000000000000..000fec028c2f --- /dev/null +++ b/samples/winsamp.d @@ -0,0 +1,165 @@ +module winsamp; + +/+ Compile with: + + dmd winsamp winsamp.def + + or: + + dmd winsamp -L-Subsystem:Windows + +/ + +pragma(lib, "gdi32.lib"); +import core.runtime; +import std.c.windows.windows; +import std.string; + +enum IDC_BTNCLICK = 101; +enum IDC_BTNDONTCLICK = 102; + +extern(Windows) +int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) +{ + int result; + void exceptionHandler(Throwable e) { throw e; } + + try + { + Runtime.initialize(&exceptionHandler); + result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow); + Runtime.terminate(&exceptionHandler); + } + catch (Throwable e) + { + MessageBoxA(null, e.toString().toStringz, "Error", MB_OK | MB_ICONEXCLAMATION); + result = 0; + } + + return result; +} + +int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) +{ + string caption = "The Hello Program"; + string className = "DWndClass"; + HWND hWnd, btnClick, btnDontClick; + MSG msg; + WNDCLASS wndclass; + + wndclass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = &WindowProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIconA(null, IDI_APPLICATION); + wndclass.hCursor = LoadCursorA(null, IDC_CROSS); + wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = null; + wndclass.lpszClassName = className.toStringz; + + if (!RegisterClassA(&wndclass)) + { + MessageBoxA(null, "Couldn't register Window Class!", caption.toStringz, MB_ICONERROR); + return 0; + } + + hWnd = CreateWindowA(className.toStringz, // window class name + caption.toStringz, // window caption + WS_THICKFRAME | + WS_MAXIMIZEBOX | + WS_MINIMIZEBOX | + WS_SYSMENU | + WS_VISIBLE, // window style + CW_USEDEFAULT, // initial x position + CW_USEDEFAULT, // initial y position + 600, // initial x size + 400, // initial y size + HWND_DESKTOP, // parent window handle + null, // window menu handle + hInstance, // program instance handle + null); // creation parameters + + if (hWnd is null) + { + MessageBoxA(null, "Couldn't create window.", caption.toStringz, MB_ICONERROR); + return 0; + } + + btnClick = CreateWindowA("BUTTON", "Click Me", WS_CHILD | WS_VISIBLE, + 0, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNCLICK, hInstance, null); + + btnDontClick = CreateWindowA("BUTTON", "DON'T CLICK!", WS_CHILD | WS_VISIBLE, + 110, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNDONTCLICK, hInstance, null); + + ShowWindow(hWnd, iCmdShow); + UpdateWindow(hWnd); + + while (GetMessageA(&msg, null, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + return msg.wParam; +} + +int* p; +extern(Windows) +LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_BTNCLICK: + if (HIWORD(wParam) == BN_CLICKED) + MessageBoxA(hWnd, "Hello, world!", "Greeting", + MB_OK | MB_ICONINFORMATION); + + break; + + case IDC_BTNDONTCLICK: + if (HIWORD(wParam) == BN_CLICKED) + { + MessageBoxA(hWnd, "You've been warned...", "Prepare to GP fault", + MB_OK | MB_ICONEXCLAMATION); + *p = 1; + } + + break; + + default: + } + + break; + } + + case WM_PAINT: + { + enum text = "D Does Windows"; + PAINTSTRUCT ps; + + HDC dc = BeginPaint(hWnd, &ps); + scope(exit) EndPaint(hWnd, &ps); + RECT r; + GetClientRect(hWnd, &r); + HFONT font = CreateFontA(80, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, + FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); + HGDIOBJ old = SelectObject(dc, cast(HGDIOBJ) font); + SetTextAlign(dc, TA_CENTER | TA_BASELINE); + TextOutA(dc, r.right / 2, r.bottom / 2, text.toStringz, text.length); + DeleteObject(SelectObject(dc, old)); + + break; + } + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + break; + } + + return DefWindowProcA(hWnd, message, wParam, lParam); +} diff --git a/samples/winsamp.def b/samples/winsamp.def new file mode 100644 index 000000000000..40b796c77a73 --- /dev/null +++ b/samples/winsamp.def @@ -0,0 +1,2 @@ +EXETYPE NT +SUBSYSTEM WINDOWS diff --git a/src/attrib.h b/src/attrib.h index 3b010c6e4ba8..a8cb333eec2f 100644 --- a/src/attrib.h +++ b/src/attrib.h @@ -23,9 +23,7 @@ struct LabelDsymbol; struct Initializer; struct Module; struct Condition; -#ifdef _DH struct HdrGenState; -#endif /**************************************************************/ diff --git a/src/backend/cc.h b/src/backend/cc.h index 152a88338c24..060eef349910 100644 --- a/src/backend/cc.h +++ b/src/backend/cc.h @@ -98,41 +98,10 @@ enum LANG LANGjapanese, }; -#if __I86__ - #include "cdef.h" // host and target compiler definition #define INITIALIZED_STATIC_DEF static -#else -#include "TGcc.h" -#include "str4.h" - -#if MULTI_FILE -/* Make statics that require re-initialization available */ -#define INITIALIZED_STATIC_DEF -#define INITIALIZED_STATIC_REF extern -#else -#define INITIALIZED_STATIC_DEF STATIC -#define INITIALIZED_STATIC_REF error -#endif - -#ifndef PASCAL -#define PASCAL pascal -#endif - -#define TOOLKIT_H - -/* Segments */ -#define CODE 1 /* code segment */ -#define DATA 2 /* initialized data */ -#define CDATA 3 /* constant data */ -#define UDATA 4 /* uninitialized data */ -#ifndef UNKNOWN -#define UNKNOWN -1 /* unknown segment */ -#endif -#endif - #if MEMMODELS == 1 #define LARGEDATA 0 /* don't want 48 bit pointers */ #define LARGECODE 0 diff --git a/src/backend/cdef.h b/src/backend/cdef.h index 600b9f82eb89..b17ce88b466e 100644 --- a/src/backend/cdef.h +++ b/src/backend/cdef.h @@ -606,6 +606,15 @@ typedef int bool; #define __near #endif +// gcc defines this for us, dmc doesn't, so look for it's __I86__ +#if ! (defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN) ) +#if defined(__I86__) || defined(i386) || defined(__x86_64__) +#define LITTLE_ENDIAN 1 +#else +#error unknown platform, so unknown endianness +#endif +#endif + #if _WINDLL #define COPYRIGHT "Copyright © 2001 Digital Mars" #else diff --git a/src/backend/mach.h b/src/backend/mach.h index 2360e4f3a7b7..f862f7e9dd90 100644 --- a/src/backend/mach.h +++ b/src/backend/mach.h @@ -289,21 +289,20 @@ struct relocation_info struct scattered_relocation_info { - #if __LITTLE_ENDIAN__ || __I86__ || __i386 || __i386__ || __x86_64__ + #if LITTLE_ENDIAN uint32_t r_address:24, r_type:4, r_length:2, r_pcrel:1, r_scattered:1; int32_t r_value; - #elif __BIG_ENDIAN__ + #elif BIG_ENDIAN uint32_t r_scattered:1, r_pcrel:1, r_length:2, r_type:4, r_address:24; int32_t r_value; - #else #endif }; diff --git a/src/backend/strtold.c b/src/backend/strtold.c index 74ea163c0309..190d557771f9 100644 --- a/src/backend/strtold.c +++ b/src/backend/strtold.c @@ -537,7 +537,7 @@ long double strtold(const char *p,char **endp) L1: if (endp) { - *endp = (void *) p; + *endp = (char *) p; } L3: #if _WIN32 diff --git a/src/cond.c b/src/cond.c index e2f962793471..29488bd856ee 100644 --- a/src/cond.c +++ b/src/cond.c @@ -20,10 +20,8 @@ #include "module.h" #include "template.h" #include "lexer.h" -#ifdef _DH #include "mtype.h" #include "scope.h" -#endif int findCondition(Array *ids, Identifier *ident) { diff --git a/src/cond.h b/src/cond.h index 8302c23df7a9..e3cde4536824 100644 --- a/src/cond.h +++ b/src/cond.h @@ -18,13 +18,9 @@ struct Module; struct Scope; struct ScopeDsymbol; struct DebugCondition; -#ifdef _DH #include "lexer.h" // dmdhg -#endif enum TOK; -#ifdef _DH struct HdrGenState; -#endif int findCondition(Array *ids, Identifier *ident); diff --git a/src/constfold.c b/src/constfold.c index 24c04eb47566..d2909bd035c4 100644 --- a/src/constfold.c +++ b/src/constfold.c @@ -864,11 +864,11 @@ Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) cmp = (es1->var == es2->var && es1->offset == es2->offset); } - else if (e1->isConst() == 1 && e2->isConst() == 1) + else + { return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, type, e1, e2); - else - assert(0); + } if (op == TOKnotidentity) cmp ^= 1; return new IntegerExp(loc, cmp, type); diff --git a/src/declaration.c b/src/declaration.c index 10a0c91fa6f8..0bcc34b33e9b 100644 --- a/src/declaration.c +++ b/src/declaration.c @@ -254,10 +254,8 @@ TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, this->type = new TypeTypedef(this); this->basetype = basetype->toBasetype(); this->init = init; -#ifdef _DH this->htype = NULL; this->hbasetype = NULL; -#endif this->loc = loc; this->sinit = NULL; } @@ -273,7 +271,7 @@ Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) assert(!s); TypedefDeclaration *st; st = new TypedefDeclaration(loc, ident, basetype, init); -#ifdef _DH + // Syntax copy for header file if (!htype) // Don't overwrite original { if (type) // Make copy for both old and new instances @@ -291,7 +289,7 @@ Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) } else st->hbasetype = hbasetype->syntaxCopy(); -#endif + return st; } @@ -368,10 +366,8 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) this->loc = loc; this->type = type; this->aliassym = NULL; -#ifdef _DH this->htype = NULL; this->haliassym = NULL; -#endif this->overnext = NULL; this->inSemantic = 0; assert(type); @@ -385,10 +381,8 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) this->loc = loc; this->type = NULL; this->aliassym = s; -#ifdef _DH this->htype = NULL; this->haliassym = NULL; -#endif this->overnext = NULL; this->inSemantic = 0; assert(s); @@ -403,7 +397,7 @@ Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); else sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL)); -#ifdef _DH + // Syntax copy for header file if (!htype) // Don't overwrite original { if (type) // Make copy for both old and new instances @@ -421,7 +415,7 @@ Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) } else sa->haliassym = haliassym->syntaxCopy(s); -#endif + return sa; } @@ -606,7 +600,7 @@ Dsymbol *AliasDeclaration::toAlias() void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { buf->writestring("alias "); -#if 0 && _DH +#if 0 if (hgs->hdrgen) { if (haliassym) @@ -649,10 +643,8 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer assert(type || init); this->type = type; this->init = init; -#ifdef _DH this->htype = NULL; this->hinit = NULL; -#endif this->loc = loc; offset = 0; noscope = 0; @@ -693,7 +685,7 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); sv->storage_class = storage_class; } -#ifdef _DH + // Syntax copy for header file if (!htype) // Don't overwrite original { if (type) // Make copy for both old and new instances @@ -711,7 +703,7 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) } else sv->hinit = hinit->syntaxCopy(); -#endif + return sv; } diff --git a/src/declaration.h b/src/declaration.h index cec6c6f25839..42f1d4255115 100644 --- a/src/declaration.h +++ b/src/declaration.h @@ -190,10 +190,8 @@ struct TypedefDeclaration : Declaration const char *kind(); Type *getType(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -#ifdef _DH Type *htype; Type *hbasetype; -#endif void toDocBuffer(OutBuffer *buf); @@ -224,10 +222,8 @@ struct AliasDeclaration : Declaration Type *getType(); Dsymbol *toAlias(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -#ifdef _DH Type *htype; Dsymbol *haliassym; -#endif void toDocBuffer(OutBuffer *buf); @@ -277,10 +273,8 @@ struct VarDeclaration : Declaration void semantic2(Scope *sc); const char *kind(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -#ifdef _DH Type *htype; Initializer *hinit; -#endif AggregateDeclaration *isThis(); int needThis(); int isImportedSymbol(); @@ -857,9 +851,7 @@ struct DeleteDeclaration : FuncDeclaration int isVirtual(); int addPreInvariant(); int addPostInvariant(); -#ifdef _DH DeleteDeclaration *isDeleteDeclaration() { return this; } -#endif }; #endif /* DMD_DECLARATION_H */ diff --git a/src/dsymbol.h b/src/dsymbol.h index 6e0896ebb9e2..065a3375f38a 100644 --- a/src/dsymbol.h +++ b/src/dsymbol.h @@ -154,10 +154,8 @@ struct Dsymbol : Object Dsymbol *search_correct(Identifier *id); Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id); virtual int overloadInsert(Dsymbol *s); -#ifdef _DH char *toHChars(); virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs); -#endif virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); virtual void toDocBuffer(OutBuffer *buf); virtual void toJsonBuffer(OutBuffer *buf); @@ -236,9 +234,7 @@ struct Dsymbol : Object virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } virtual Import *isImport() { return NULL; } virtual EnumDeclaration *isEnumDeclaration() { return NULL; } -#ifdef _DH virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } -#endif virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } virtual AttribDeclaration *isAttribDeclaration() { return NULL; } virtual OverloadSet *isOverloadSet() { return NULL; } diff --git a/src/enum.h b/src/enum.h index c7ed41d98eaf..0c82575a1eed 100644 --- a/src/enum.h +++ b/src/enum.h @@ -21,9 +21,7 @@ struct Identifier; struct Type; struct Expression; -#ifdef _DH struct HdrGenState; -#endif struct EnumDeclaration : ScopeDsymbol diff --git a/src/expression.c b/src/expression.c index 158d230c75fe..fa20ecd231f7 100644 --- a/src/expression.c +++ b/src/expression.c @@ -8142,8 +8142,7 @@ Expression *CastExp::semantic(Scope *sc) Type *t1b = e1->type->toBasetype(); Type *tob = to->toBasetype(); if (tob->ty == Tstruct && - !tob->equals(t1b) && - ((TypeStruct *)tob)->sym->search(0, Id::call, 0) + !tob->equals(t1b) ) { /* Look to replace: @@ -8154,10 +8153,10 @@ Expression *CastExp::semantic(Scope *sc) // Rewrite as to.call(e1) e = new TypeExp(loc, to); - e = new DotIdExp(loc, e, Id::call); e = new CallExp(loc, e, e1); - e = e->semantic(sc); - return e; + e = e->trySemantic(sc); + if (e) + return e; } // Struct casts are possible only when the sizes match diff --git a/src/expression.h b/src/expression.h index 385bd6e53e43..365554e94f98 100644 --- a/src/expression.h +++ b/src/expression.h @@ -260,9 +260,7 @@ struct ComplexExp : Expression int isBool(int result); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void toMangleBuffer(OutBuffer *buf); -#ifdef _DH OutBuffer hexp; -#endif elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); }; @@ -1542,6 +1540,7 @@ struct InExp : BinExp { InExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); + Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); int isBit(); // For operator overloading diff --git a/src/freebsd.mak b/src/freebsd.mak index cf87df973fdf..d0ea1438181e 100644 --- a/src/freebsd.mak +++ b/src/freebsd.mak @@ -17,8 +17,8 @@ WARNINGS=-Wno-deprecated -Wstrict-aliasing #GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 -CFLAGS = $(GFLAGS) -I$(ROOT) -D__I86__=1 -DMARS=1 -DTARGET_FREEBSD=1 -D_DH -MFLAGS = $(GFLAGS) -I$C -I$(TK) -D__I86__=1 -DMARS=1 -DTARGET_FREEBSD=1 -D_DH +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_FREEBSD=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_FREEBSD=1 CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ $C/dt.h $C/cgcv.h $C/el.h $C/iasm.h @@ -174,7 +174,7 @@ builtin.o: builtin.c $(CC) -c $(CFLAGS) $< cast.o: cast.c - $(CC) -c $(CFLAGS) $< + $(CC) -c $(CFLAGS) $< cg.o: fltables.c $C/cg.c $(CC) -c $(MFLAGS) -I. $C/cg.c @@ -403,7 +403,7 @@ mars.o: mars.c rmem.o: $(ROOT)/rmem.c $(CC) -c $(GFLAGS) -I$(ROOT) $(ROOT)/rmem.c - + module.o: $(TOTALH) $C/html.h module.c $(CC) -c $(CFLAGS) -I$C module.c diff --git a/src/func.c b/src/func.c index fe67e42b1e28..5b99d351520a 100644 --- a/src/func.c +++ b/src/func.c @@ -1463,15 +1463,10 @@ void FuncDeclaration::semantic3(Scope *sc) // Merge contracts together with body into one compound statement -#ifdef _DH if (frequire && global.params.useIn) { frequire->incontract = 1; a->push(frequire); } -#else - if (frequire && global.params.useIn) - a->push(frequire); -#endif // Precondition invariant if (addPreInvariant()) diff --git a/src/hdrgen.c b/src/hdrgen.c index 63d70667b2a8..e11c212f9912 100644 --- a/src/hdrgen.c +++ b/src/hdrgen.c @@ -10,8 +10,6 @@ // Routines to emit header files -#ifdef _DH - #define PRETTY_PRINT #define TEST_EMIT_ALL 0 // For Testing @@ -100,5 +98,3 @@ void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs) /*************************************/ - -#endif // #ifdef _DH diff --git a/src/iasm.c b/src/iasm.c index 2a47a3741d59..ad6d23119a7c 100644 --- a/src/iasm.c +++ b/src/iasm.c @@ -54,8 +54,6 @@ #include "iasm.h" #include "cpp.h" -#undef _DH - // I32 isn't set correctly yet because this is the front end, and I32 // is a backend flag #undef I16 diff --git a/src/identifier.h b/src/identifier.h index c397f23b8d6e..b786fca96deb 100644 --- a/src/identifier.h +++ b/src/identifier.h @@ -29,9 +29,7 @@ struct Identifier : Object int compare(Object *o); void print(); char *toChars(); -#ifdef _DH char *toHChars(); -#endif const char *toHChars2(); int dyncast(); diff --git a/src/import.h b/src/import.h index c7a4af054693..4f442de5f67a 100644 --- a/src/import.h +++ b/src/import.h @@ -24,9 +24,7 @@ struct OutBuffer; struct Module; struct Package; struct AliasDeclaration; -#ifdef _DH struct HdrGenState; -#endif struct Import : Dsymbol { diff --git a/src/init.h b/src/init.h index a6c84e468c09..1bd8cd870b64 100644 --- a/src/init.h +++ b/src/init.h @@ -26,9 +26,8 @@ struct VoidInitializer; struct StructInitializer; struct ArrayInitializer; struct ExpInitializer; -#ifdef _DH struct HdrGenState; -#endif + struct Initializer : Object { diff --git a/src/interpret.c b/src/interpret.c index e60c37f46b33..8a02ddd7d698 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -59,6 +59,7 @@ VarDeclaration *findParentVar(Expression *e, Expression *thisval); void addVarToInterstate(InterState *istate, VarDeclaration *v); bool needToCopyLiteral(Expression *expr); Expression *copyLiteral(Expression *e); +Expression *paintTypeOntoLiteral(Type *type, Expression *lit); // Used for debugging only @@ -180,12 +181,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument return NULL; } - // Evaluate 'this', if present. - if (thisarg && thisarg->op != TOKvar) - thisarg = thisarg->interpret(istate, ctfeNeedLvalue); - if (thisarg == EXP_CANT_INTERPRET) - return NULL; - InterState istatex; istatex.caller = istate; istatex.fd = this; @@ -610,7 +605,13 @@ Expression *ReturnStatement::interpret(InterState *istate) } } #endif - Expression *e = exp->interpret(istate); + // We need to treat pointers specially, because TOKsymoff can be used to + // return a value OR a pointer + Expression *e; + if ((exp->type->ty == Tpointer && exp->type->nextOf()->ty != Tfunction)) + e = exp->interpret(istate, ctfeNeedLvalue); + else + e = exp->interpret(istate); if (e == EXP_CANT_INTERPRET) return e; if (!istate->caller) @@ -998,6 +999,8 @@ Expression *SwitchStatement::interpret(InterState *istate) Expression *econdition = condition->interpret(istate); if (econdition == EXP_CANT_INTERPRET) return EXP_CANT_INTERPRET; + if (econdition->op == TOKslice) + econdition = resolveSlice(econdition); Statement *s = NULL; if (cases) @@ -1160,6 +1163,7 @@ Expression *AsmStatement::interpret(InterState *istate) return EXP_CANT_INTERPRET; } +#if DMDV2 Expression *ImportStatement::interpret(InterState *istate) { #if LOG @@ -1168,6 +1172,7 @@ Expression *ImportStatement::interpret(InterState *istate) START(); return NULL; } +#endif /******************************** Expression ***************************/ @@ -1317,24 +1322,13 @@ Expression *AddrExp::interpret(InterState *istate, CtfeGoal goal) #if LOG printf("AddrExp::interpret() %s\n", toChars()); #endif - if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef) - { - Expression *e = e1->interpret(istate, goal); - if (e == EXP_CANT_INTERPRET) - return e; - if (e->op == TOKindex) - { - IndexExp *ie = (IndexExp *)e; - e = new IndexExp(ie->loc, ie->e1, ie->e2); - e->type = type; - return e; - } - e = new AddrExp(loc, e); - e->type = type; + Expression *e = e1->interpret(istate, goal); + if (e == EXP_CANT_INTERPRET) return e; - } - error("Cannot interpret %s at compile time", toChars()); - return EXP_CANT_INTERPRET; + // Return a simplified address expression + e = new AddrExp(loc, e); + e->type = type; + return e; } Expression *DelegateExp::interpret(InterState *istate, CtfeGoal goal) @@ -1514,16 +1508,8 @@ Expression *VarExp::interpret(InterState *istate, CtfeGoal goal) } Expression *e = getVarExp(loc, istate, var, goal); // A VarExp may include an implicit cast. It must be done explicitly. - if (e != EXP_CANT_INTERPRET && e->type != type - && e->implicitConvTo(type) == MATCHexact) - { - if (goal == ctfeNeedLvalue && e->op==TOKarrayliteral) - { - return e; - } - e = e->implicitCastTo(0, type); - e = e->interpret(istate, goal); - } + if (e != EXP_CANT_INTERPRET) + e = paintTypeOntoLiteral(type, e); return e; } @@ -1889,6 +1875,28 @@ Expression *NewExp::interpret(InterState *istate, CtfeGoal goal) ((TypeArray *)newtype)->next->defaultInitLiteral(), lenExpr->toInteger()); } + if (newtype->toBasetype()->ty == Tstruct) + { + Expression *se = newtype->defaultInitLiteral(); +#if DMDV2 + if (member) + { + int olderrors = global.errors; + member->interpret(istate, arguments, se); + if (olderrors != global.errors) + { + error("cannot evaluate %s at compile time", toChars()); + return EXP_CANT_INTERPRET; + } + } +#else // The above code would fail on D1 because it doesn't use STRUCTTHISREF, + // but that's OK because D1 doesn't have struct constructors anyway. + assert(!member); +#endif + Expression *e = new AddrExp(loc, se); + e->type = type; + return e; + } if (newtype->ty == Tclass) { error("classes are not yet supported in CTFE"); @@ -1908,9 +1916,6 @@ Expression *UnaExp::interpretCommon(InterState *istate, CtfeGoal goal, Expressi e1 = this->e1->interpret(istate); if (e1 == EXP_CANT_INTERPRET) goto Lcant; - if (e1->isConst() != 1) - goto Lcant; - e = (*fp)(type, e1); return e; @@ -1989,12 +1994,12 @@ Expression *pointerArithmetic(Loc loc, enum TOK op, Type *type, dinteger_t ofs1, ofs2; if (eptr->op == TOKaddress) eptr = ((AddrExp *)eptr)->e1; - if (eptr->op != TOKindex && eptr->op!=TOKstring && eptr->op!=TOKarrayliteral) + Expression *agg1 = getAggregateFromPointer(eptr, &ofs1); + if (agg1->op != TOKstring && agg1->op != TOKarrayliteral) { error(loc, "cannot perform pointer arithmetic on non-arrays at compile time"); return EXP_CANT_INTERPRET; } - Expression *agg1 = getAggregateFromPointer(eptr, &ofs1); ofs2 = e2->toInteger(); Type *pointee = ((TypePointer *)agg1->type)->next; dinteger_t sz = pointee->size(); @@ -2494,6 +2499,49 @@ Expression *copyLiteral(Expression *e) return r; } +/* Deal with type painting. + * Type painting is a major nuisance: we can't just set + * e->type = type, because that would change the original literal. + * But, we can't simply copy the literal either, because that would change + * the values of any pointers. + */ +Expression *paintTypeOntoLiteral(Type *type, Expression *lit) +{ + if (lit->type == type) + return lit; + Expression *e; + if (lit->op == TOKslice) + { + SliceExp *se = (SliceExp *)lit; + e = new SliceExp(lit->loc, se->e1, se->lwr, se->upr); + } + else if (lit->op == TOKindex) + { + IndexExp *ie = (IndexExp *)lit; + e = new IndexExp(lit->loc, ie->e1, ie->e2); + } + else if (lit->op == TOKarrayliteral) + { + ArrayLiteralExp *ae = (ArrayLiteralExp *)lit; + e = new ArrayLiteralExp(lit->loc, ae->elements); + } + else if (lit->op == TOKstring) + { + // For strings, we need to introduce another level of indirection + e = new SliceExp(lit->loc, lit, + new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, lit)); + } + else if (lit->op == TOKassocarrayliteral) + { + AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)lit; + e = new AssocArrayLiteralExp(lit->loc, aae->keys, aae->values); + } + else + e = copyLiteral(lit); + e->type = type; + return e; +} + /* Set a slice of char array literal 'existingAE' from a string 'newval'. * existingAE[firstIndex..firstIndex+newval.length] = newval. */ @@ -2759,6 +2807,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ e1 = new SliceExp(loc, e1, new IntegerExp(0, 0, Type::tsize_t), ArrayLength(Type::tsize_t, e1)); + e1->type = type; } } if (e1->op == TOKstar) @@ -2777,13 +2826,16 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_ Expression * newval = NULL; if (!wantRef) - if ((e1->type->toBasetype()->ty == Tpointer && e1->type->nextOf()->ty != Tfunction)) + // We need to treat pointers specially, because TOKsymoff can be used to + // return a value OR a pointer + assert(e1); + assert(e1->type); + if ((e1->type->ty == Tpointer && e1->type->nextOf()->ty != Tfunction) && (e2->op == TOKsymoff || e2->op==TOKaddress || e2->op==TOKvar)) // && (e1->op==TOKaddress)) //TOKsymoff || e1->op==TOKdotvar)) newval = this->e2->interpret(istate, ctfeNeedLvalue); else newval = this->e2->interpret(istate); if (newval == EXP_CANT_INTERPRET) return newval; - // ---------------------------------------------------- // Deal with read-modify-write assignments. // Set 'newval' to the final assignment value @@ -3655,6 +3707,14 @@ Expression *CallExp::interpret(InterState *istate, CtfeGoal goal) pthis = istate ? istate->localThis : NULL; else if (pthis->op == TOKcomma) pthis = pthis->interpret(istate); + if (pthis == EXP_CANT_INTERPRET) + return NULL; + // Evaluate 'this' + if (pthis->op != TOKvar) + pthis = pthis->interpret(istate, ctfeNeedLvalue); + if (pthis == EXP_CANT_INTERPRET) + return NULL; + if (!fd->fbody) { error("%s cannot be interpreted at compile time," @@ -3838,6 +3898,33 @@ Expression *ArrayLengthExp::interpret(InterState *istate, CtfeGoal goal) return EXP_CANT_INTERPRET; } +/* Given an AA literal 'ae', and a key 'e2': + * Return ae[e2] if present, or NULL if not found. + * Return EXP_CANT_INTERPRET on error. + */ +Expression *findKeyInAA(AssocArrayLiteralExp *ae, Expression *e2) +{ + /* Search the keys backwards, in case there are duplicate keys + */ + for (size_t i = ae->keys->dim; i;) + { + i--; + Expression *ekey = (Expression *)ae->keys->data[i]; + Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); + if (ex == EXP_CANT_INTERPRET) + { + error("cannot evaluate %s==%s at compile time", + ekey->toChars(), e2->toChars()); + return ex; + } + if (ex->isBool(TRUE)) + { + return (Expression *)ae->values->data[i]; + } + } + return NULL; +} + Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal) { Expression *e = NULL; Expression *e1 = NULL; @@ -3915,7 +4002,24 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal) e->type = type; return e; } - e = Index(type, e1, e2); + if (e1->op == TOKassocarrayliteral) + { + e = findKeyInAA((AssocArrayLiteralExp *)e1, e2); + if (!e) + { + error("key %s not found in associative array %s", + e2->toChars(), this->e1->toChars()); + return EXP_CANT_INTERPRET; + } + if (e == EXP_CANT_INTERPRET) + return e; + assert(!e->checkSideEffect(2)); + e = paintTypeOntoLiteral(type, e); + } + else + { + e = Index(type, e1, e2); + } if (e == EXP_CANT_INTERPRET) { error("%s cannot be interpreted at compile time", toChars()); @@ -4049,6 +4153,37 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal) return EXP_CANT_INTERPRET; } +Expression *InExp::interpret(InterState *istate, CtfeGoal goal) +{ Expression *e = EXP_CANT_INTERPRET; + +#if LOG + printf("InExp::interpret() %s\n", toChars()); +#endif + Expression *e1 = this->e1->interpret(istate); + if (e1 == EXP_CANT_INTERPRET) + return e1; + Expression *e2 = this->e2->interpret(istate); + if (e2 == EXP_CANT_INTERPRET) + return e2; + if (e2->op == TOKnull) + { + error("cannot use 'in' on a null associative array"); + return EXP_CANT_INTERPRET; + } + if (e2->op != TOKassocarrayliteral) + { + error(" %s cannot be interpreted at compile time", toChars()); + return EXP_CANT_INTERPRET; + } + e = findKeyInAA((AssocArrayLiteralExp *)e2, e1); + if (e == EXP_CANT_INTERPRET) + return e; + if (!e) + return new NullExp(loc, type); + e = new IndexExp(loc, e2, e1); + e->type = type; + return e; +} Expression *CatExp::interpret(InterState *istate, CtfeGoal goal) { Expression *e; @@ -4103,6 +4238,12 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal) e->type = type; return e; } + if (e1->op == TOKarrayliteral) + { + e = new IndexExp(loc, e1, new IntegerExp(loc, 0, Type::tsize_t)); + e->type = type; + return e; + } if (e1->op == TOKstring) { return e1; @@ -4115,8 +4256,28 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal) e1->type = to; return e1; } + // Disallow array type painting, except for conversions between built-in + // types of identical size. + if ((to->ty == Tsarray || to->ty == Tarray) && + (e1->type->ty == Tsarray || e1->type->ty == Tarray) && +#if DMDV2 + e1->type->nextOf()->castMod(0) != to->nextOf()->castMod(0) +#else + e1->type->nextOf() != to->nextOf() +#endif + && !(to->nextOf()->isTypeBasic() && e1->type->nextOf()->isTypeBasic() + && to->nextOf()->size() == e1->type->nextOf()->size()) ) + { + error("array cast from %s to %s is not supported at compile time", e1->type->toChars(), to->toChars()); + return EXP_CANT_INTERPRET; + } if (to->ty == Tsarray && e1->op == TOKslice) e1 = resolveSlice(e1); + if (to->toBasetype()->ty == Tbool && e1->type->ty==Tpointer) + { + return new IntegerExp(loc, e1->op != TOKnull, to); + } + e = Cast(type, to, e1); if (e == EXP_CANT_INTERPRET) error("%s cannot be interpreted at compile time", toChars()); @@ -4149,7 +4310,7 @@ Expression *AssertExp::interpret(InterState *istate, CtfeGoal goal) } } // Deal with pointers (including compiler-inserted assert(&this, "null this")) - if (this->e1->op == TOKaddress || this->e1->op == TOKsymoff) + if (this->e1->type->ty == Tpointer && this->e1->type->nextOf()->ty != Tfunction) { e1 = this->e1->interpret(istate, ctfeNeedLvalue); if (e1 == EXP_CANT_INTERPRET) @@ -4249,9 +4410,14 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal) toChars(), len); return EXP_CANT_INTERPRET; } + return Index(type, ie->e1, ie->e2); } } - e = e->interpret(istate, goal); + if (e->op == TOKstructliteral) + return e; + e = e1->interpret(istate, goal); + if (e->op == TOKaddress) + e = ((AddrExp*)e)->e1; if (e == EXP_CANT_INTERPRET) return e; e->type = type; @@ -4280,6 +4446,8 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal) Expression *ex = e1->interpret(istate); if (ex != EXP_CANT_INTERPRET) { + if (ex->op == TOKaddress) + ex = ((AddrExp *)ex)->e1; if (ex->op == TOKstructliteral) { StructLiteralExp *se = (StructLiteralExp *)ex; VarDeclaration *v = var->isVarDeclaration(); @@ -4301,7 +4469,14 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal) if ((type->ty == Tsarray || goal == ctfeNeedLvalue) && ( e->op == TOKarrayliteral || e->op == TOKassocarrayliteral || e->op == TOKstring || - e->op == TOKslice || e->type->ty == Tpointer)) + e->op == TOKslice)) + return e; + /* Element is an allocated pointer, which was created in + * CastExp. + */ + if (goal == ctfeNeedLvalue && e->op == TOKindex && + e->type == type && + (type->ty == Tpointer && type->nextOf()->ty != Tfunction)) return e; // ...Otherwise, just return the (simplified) dotvar expression e = new DotVarExp(loc, ex, v); @@ -4318,6 +4493,11 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal) if (e->op == TOKstructliteral || e->op == TOKarrayliteral || e->op == TOKassocarrayliteral || e->op == TOKstring) return e; + if (type->ty == Tpointer && type->nextOf()->ty != Tfunction) + { + assert(e->type == type); + return e; + } return e->interpret(istate, goal); } } @@ -4362,10 +4542,10 @@ Expression *interpret_aaKeys(InterState *istate, Expressions *arguments) earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; - if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) - return NULL; if (earg->op == TOKnull) return new NullExp(earg->loc); + if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) + return NULL; AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); Type *elemType = ((TypeAArray *)aae->type)->index; @@ -4384,10 +4564,10 @@ Expression *interpret_aaValues(InterState *istate, Expressions *arguments) earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; - if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) - return NULL; if (earg->op == TOKnull) return new NullExp(earg->loc); + if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) + return NULL; AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; Expression *e = new ArrayLiteralExp(aae->loc, aae->values); Type *elemType = ((TypeAArray *)aae->type)->next; @@ -4421,10 +4601,10 @@ Expression *interpret_keys(InterState *istate, Expression *earg, FuncDeclaration earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; - if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) - return NULL; if (earg->op == TOKnull) return new NullExp(earg->loc); + if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) + return NULL; assert(earg->op == TOKassocarrayliteral); AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; Expression *e = new ArrayLiteralExp(aae->loc, aae->keys); @@ -4443,10 +4623,10 @@ Expression *interpret_values(InterState *istate, Expression *earg, FuncDeclarati earg = earg->interpret(istate); if (earg == EXP_CANT_INTERPRET) return NULL; - if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) - return NULL; if (earg->op == TOKnull) return new NullExp(earg->loc); + if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray) + return NULL; assert(earg->op == TOKassocarrayliteral); AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)earg; Expression *e = new ArrayLiteralExp(aae->loc, aae->values); diff --git a/src/linux.mak b/src/linux.mak index ba0e24408bd7..d6f1fb03c60f 100644 --- a/src/linux.mak +++ b/src/linux.mak @@ -17,8 +17,8 @@ WARNINGS=-Wno-deprecated -Wstrict-aliasing #GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 -CFLAGS = $(GFLAGS) -I$(ROOT) -D__I86__=1 -DMARS=1 -DTARGET_LINUX=1 -D_DH -MFLAGS = $(GFLAGS) -I$C -I$(TK) -D__I86__=1 -DMARS=1 -DTARGET_LINUX=1 -D_DH +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_LINUX=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_LINUX=1 LDFLAGS = -lm -lstdc++ -lpthread CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ @@ -175,7 +175,7 @@ builtin.o: builtin.c $(CC) -c $(CFLAGS) $< cast.o: cast.c - $(CC) -c $(CFLAGS) $< + $(CC) -c $(CFLAGS) $< cg.o: fltables.c $C/cg.c $(CC) -c $(MFLAGS) -I. $C/cg.c @@ -404,7 +404,7 @@ mars.o: mars.c rmem.o: $(ROOT)/rmem.c $(CC) -c $(GFLAGS) -I$(ROOT) $(ROOT)/rmem.c - + module.o: $(TOTALH) $C/html.h module.c $(CC) -c $(CFLAGS) -I$C module.c diff --git a/src/mars.c b/src/mars.c index 1c2e1b00e06f..e022c5aea780 100644 --- a/src/mars.c +++ b/src/mars.c @@ -546,7 +546,6 @@ int main(int argc, char *argv[]) goto Lerror; } } -#ifdef _DH else if (p[1] == 'H') { global.params.doHdrGeneration = 1; switch (p[2]) @@ -570,7 +569,6 @@ int main(int argc, char *argv[]) goto Lerror; } } -#endif else if (p[1] == 'X') { global.params.doXGeneration = 1; switch (p[2]) @@ -1154,7 +1152,6 @@ int main(int argc, char *argv[]) } if (global.errors) fatal(); -#ifdef _DH if (global.params.doHdrGeneration) { /* Generate 'header' import files. @@ -1172,7 +1169,6 @@ int main(int argc, char *argv[]) } if (global.errors) fatal(); -#endif // load all unconditional imports for better symbol resolving for (i = 0; i < modules.dim; i++) diff --git a/src/module.c b/src/module.c index 2b6516260141..33834c8265c6 100644 --- a/src/module.c +++ b/src/module.c @@ -380,7 +380,7 @@ void Module::read(Loc loc) inline unsigned readwordLE(unsigned short *p) { -#if __I86__ +#if LITTLE_ENDIAN return *p; #else return (((unsigned char *)p)[1] << 8) | ((unsigned char *)p)[0]; @@ -394,7 +394,7 @@ inline unsigned readwordBE(unsigned short *p) inline unsigned readlongLE(unsigned *p) { -#if __I86__ +#if LITTLE_ENDIAN return *p; #else return ((unsigned char *)p)[0] | diff --git a/src/module.h b/src/module.h index 3aaa36e6ff02..ccc3dd3382c3 100644 --- a/src/module.h +++ b/src/module.h @@ -132,9 +132,7 @@ struct Module : Package void semantic3(); // pass 3 semantic analysis void inlineScan(); // scan for functions to inline void setHdrfile(); // set hdrfile member -#ifdef _DH void genhdrfile(); // generate D import file -#endif void genobjfile(int multiobj); void gensymfile(); void gendocfile(); diff --git a/src/openbsd.mak b/src/openbsd.mak index 059632a167b6..a3ab2c4154f1 100644 --- a/src/openbsd.mak +++ b/src/openbsd.mak @@ -17,8 +17,8 @@ WARNINGS=-Wno-deprecated -Wstrict-aliasing #GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 -CFLAGS = $(GFLAGS) -I$(ROOT) -D__I86__=1 -DMARS=1 -DTARGET_OPENBSD=1 -D_DH -MFLAGS = $(GFLAGS) -I$C -I$(TK) -D__I86__=1 -DMARS=1 -DTARGET_OPENBSD=1 -D_DH +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_OPENBSD=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_OPENBSD=1 CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ $C/dt.h $C/cgcv.h $C/el.h $C/iasm.h @@ -174,7 +174,7 @@ builtin.o: builtin.c $(CC) -c $(CFLAGS) $< cast.o: cast.c - $(CC) -c $(CFLAGS) $< + $(CC) -c $(CFLAGS) $< cg.o: fltables.c $C/cg.c $(CC) -c $(MFLAGS) -I. $C/cg.c @@ -403,7 +403,7 @@ mars.o: mars.c rmem.o: $(ROOT)/rmem.c $(CC) -c $(GFLAGS) -I$(ROOT) $(ROOT)/rmem.c - + module.o: $(TOTALH) $C/html.h module.c $(CC) -c $(CFLAGS) -I$C module.c diff --git a/src/opover.c b/src/opover.c index 1458f92b5949..f44a621e012f 100644 --- a/src/opover.c +++ b/src/opover.c @@ -523,7 +523,7 @@ Expression *BinExp::op_overload(Scope *sc) } else { TemplateDeclaration *td = s->isTemplateDeclaration(); - templateResolve(&m, td, sc, loc, targsi, NULL, &args2); + templateResolve(&m, td, sc, loc, targsi, e1, &args2); } } @@ -538,7 +538,7 @@ Expression *BinExp::op_overload(Scope *sc) } else { TemplateDeclaration *td = s_r->isTemplateDeclaration(); - templateResolve(&m, td, sc, loc, targsi, NULL, &args1); + templateResolve(&m, td, sc, loc, targsi, e2, &args1); } } @@ -616,7 +616,7 @@ Expression *BinExp::op_overload(Scope *sc) } else { TemplateDeclaration *td = s_r->isTemplateDeclaration(); - templateResolve(&m, td, sc, loc, targsi, NULL, &args2); + templateResolve(&m, td, sc, loc, targsi, e1, &args2); } } FuncDeclaration *lastf = m.lastf; @@ -630,7 +630,7 @@ Expression *BinExp::op_overload(Scope *sc) } else { TemplateDeclaration *td = s->isTemplateDeclaration(); - templateResolve(&m, td, sc, loc, targsi, NULL, &args1); + templateResolve(&m, td, sc, loc, targsi, e2, &args1); } } @@ -1070,7 +1070,7 @@ Expression *BinAssignExp::op_overload(Scope *sc) } else { TemplateDeclaration *td = s->isTemplateDeclaration(); - templateResolve(&m, td, sc, loc, targsi, NULL, &args2); + templateResolve(&m, td, sc, loc, targsi, e1, &args2); } } diff --git a/src/osx.mak b/src/osx.mak index 4c1415fcb890..0684d181a469 100644 --- a/src/osx.mak +++ b/src/osx.mak @@ -25,8 +25,8 @@ WARNINGS=-Wno-deprecated -Wstrict-aliasing #GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 -CFLAGS = $(GFLAGS) -I$(ROOT) -D__I86__=1 -DMARS=1 -DTARGET_OSX=1 -D_DH -MFLAGS = $(GFLAGS) -I$C -I$(TK) -D__I86__=1 -DMARS=1 -DTARGET_OSX=1 -D_DH +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_OSX=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_OSX=1 CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ $C/dt.h $C/cgcv.h $C/el.h $C/iasm.h diff --git a/src/posix.mak b/src/posix.mak new file mode 100644 index 000000000000..f33aeb90d0eb --- /dev/null +++ b/src/posix.mak @@ -0,0 +1,653 @@ +# NOTE: need to validate solaris behavior +ifeq (,$(TARGET)) + OS:=$(shell uname) + ifeq (Darwin,$(OS)) + TARGET=OSX + else + ifeq (Linux,$(OS)) + TARGET=LINUX + else + ifeq (FreeBSD,$(OS)) + TARGET=FREEBSD + else + ifeq (OpenBSD,$(OS)) + TARGET=OPENBSD + else + ifeq (Solaris,$(OS)) + TARGET=SOLARIS + else + $(error Unrecognized or unsupported OS for uname: $(OS)) + endif + endif + endif + endif + endif +endif + +C=backend +TK=tk +ROOT=root + +MODEL=32 + +ifeq (OSX,$(TARGET)) + ## See: http://developer.apple.com/documentation/developertools/conceptual/cross_development/Using/chapter_3_section_2.html#//apple_ref/doc/uid/20002000-1114311-BABGCAAB + ENVP= MACOSX_DEPLOYMENT_TARGET=10.3 + SDK=/Developer/SDKs/MacOSX10.4u.sdk #doesn't work because can't find + SDK=/Developer/SDKs/MacOSX10.5.sdk + #SDK=/Developer/SDKs/MacOSX10.6.sdk + + TARGET_CFLAGS=-isysroot ${SDK} + LDFLAGS=-lstdc++ -isysroot ${SDK} -Wl,-syslibroot,${SDK} -framework CoreServices +else + LDFLAGS=-lm -lstdc++ -lpthread +endif + +CC=g++ -m$(MODEL) $(TARGET_CFLAGS) + +#OPT=-g -g3 +#OPT=-O2 + +#COV=-fprofile-arcs -ftest-coverage + +WARNINGS=-Wno-deprecated -Wstrict-aliasing + +#GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) +GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 + +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_$(TARGET)=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_$(TARGET)=1 + +CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ + $C/dt.h $C/cgcv.h $C/el.h $C/iasm.h + +DMD_OBJS = \ + access.o array.o attrib.o bcomplex.o bit.o blockopt.o \ + cast.o code.o cg.o cg87.o cgcod.o cgcs.o cgelem.o cgen.o \ + cgreg.o cgsched.o class.o cod1.o cod2.o cod3.o cod4.o cod5.o \ + constfold.o irstate.o dchar.o cond.o debug.o \ + declaration.o dsymbol.o dt.o dump.o e2ir.o ee.o eh.o el.o \ + dwarf.o enum.o evalu8.o expression.o func.o gdag.o gflow.o \ + glocal.o gloop.o glue.o gnuc.o go.o gother.o html.o iasm.o id.o \ + identifier.o impcnvtab.o import.o inifile.o init.o inline.o \ + lexer.o link.o lstring.o mangle.o mars.o rmem.o module.o msc.o mtype.o \ + nteh.o cppmangle.o opover.o optimize.o os.o out.o outbuf.o \ + parse.o ph.o ptrntab.o root.o rtlsym.o s2ir.o scope.o statement.o \ + stringtable.o struct.o csymbol.o template.o tk.o tocsym.o todt.o \ + type.o typinf.o util.o var.o version.o strtold.o utf.o staticassert.o \ + unialpha.o toobj.o toctype.o toelfdebug.o entity.o doc.o macro.o \ + hdrgen.o delegatize.o aa.o ti_achar.o toir.o interpret.o traits.o \ + builtin.o clone.o aliasthis.o \ + man.o arrayop.o port.o response.o async.o json.o speller.o aav.o unittests.o \ + imphint.o argtypes.o ti_pvoid.o + +ifeq (OSX,$(TARGET)) + DMD_OBJS += libmach.o machobj.o +else + DMD_OBJS += libelf.o elfobj.o +endif + +SRC = win32.mak posix.mak \ + mars.c enum.c struct.c dsymbol.c import.c idgen.c impcnvgen.c \ + identifier.c mtype.c expression.c optimize.c template.h \ + template.c lexer.c declaration.c cast.c cond.h cond.c link.c \ + aggregate.h parse.c statement.c constfold.c version.h version.c \ + inifile.c iasm.c module.c scope.c dump.c init.h init.c attrib.h \ + attrib.c opover.c class.c mangle.c bit.c tocsym.c func.c inline.c \ + access.c complex_t.h irstate.h irstate.c glue.c msc.c ph.c tk.c \ + s2ir.c todt.c e2ir.c util.c identifier.h parse.h \ + scope.h enum.h import.h mars.h module.h mtype.h dsymbol.h \ + declaration.h lexer.h expression.h irstate.h statement.h eh.c \ + utf.h utf.c staticassert.h staticassert.c unialpha.c \ + typinf.c toobj.c toctype.c tocvdebug.c toelfdebug.c entity.c \ + doc.h doc.c macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \ + delegatize.c toir.h toir.c interpret.c traits.c cppmangle.c \ + builtin.c clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \ + aliasthis.h aliasthis.c json.h json.c unittests.c imphint.c \ + argtypes.c \ + $C/cdef.h $C/cc.h $C/oper.h $C/ty.h $C/optabgen.c \ + $C/global.h $C/parser.h $C/code.h $C/type.h $C/dt.h $C/cgcv.h \ + $C/el.h $C/iasm.h $C/rtlsym.h $C/html.h \ + $C/bcomplex.c $C/blockopt.c $C/cg.c $C/cg87.c \ + $C/cgcod.c $C/cgcs.c $C/cgcv.c $C/cgelem.c $C/cgen.c $C/cgobj.c \ + $C/cgreg.c $C/var.c $C/strtold.c \ + $C/cgsched.c $C/cod1.c $C/cod2.c $C/cod3.c $C/cod4.c $C/cod5.c \ + $C/code.c $C/symbol.c $C/debug.c $C/dt.c $C/ee.c $C/el.c \ + $C/evalu8.c $C/go.c $C/gflow.c $C/gdag.c \ + $C/gother.c $C/glocal.c $C/gloop.c $C/html.c $C/newman.c \ + $C/nteh.c $C/os.c $C/out.c $C/outbuf.c $C/ptrntab.c $C/rtlsym.c \ + $C/type.c $C/melf.h $C/mach.h $C/bcomplex.h \ + $C/cdeflnx.h $C/outbuf.h $C/token.h $C/tassert.h \ + $C/elfobj.c $C/cv4.h $C/dwarf2.h $C/cpp.h $C/exh.h $C/go.h \ + $C/dwarf.c $C/dwarf.h $C/aa.h $C/aa.c $C/tinfo.h $C/ti_achar.c \ + $C/ti_pvoid.c \ + $C/machobj.c \ + $(TK)/filespec.h $(TK)/mem.h $(TK)/list.h $(TK)/vec.h \ + $(TK)/filespec.c $(TK)/mem.c $(TK)/vec.c $(TK)/list.c \ + $(ROOT)/dchar.h $(ROOT)/dchar.c $(ROOT)/lstring.h \ + $(ROOT)/lstring.c $(ROOT)/root.h $(ROOT)/root.c $(ROOT)/array.c \ + $(ROOT)/rmem.h $(ROOT)/rmem.c $(ROOT)/port.h $(ROOT)/port.c \ + $(ROOT)/gnuc.h $(ROOT)/gnuc.c $(ROOT)/man.c \ + $(ROOT)/stringtable.h $(ROOT)/stringtable.c \ + $(ROOT)/response.c $(ROOT)/async.h $(ROOT)/async.c \ + $(ROOT)/aav.h $(ROOT)/aav.c \ + $(ROOT)/speller.h $(ROOT)/speller.c + + +all: dmd + +dmd: $(DMD_OBJS) + $(ENVP) gcc -o dmd -m$(MODEL) $(COV) $(DMD_OBJS) $(LDFLAGS) + +clean: + rm -f $(DMD_OBJS) dmd optab.o id.o impcnvgen idgen id.c id.h \ + impcnvtab.c optabgen debtab.c optab.c cdxxx.c elxxx.c fltables.c \ + tytab.c core \ + *.cov *.gcda *.gcno + +######## optabgen generates some source + +optabgen: $C/optabgen.c $C/cc.h $C/oper.h + $(ENVP) $(CC) $(MFLAGS) $< -o optabgen + ./optabgen + +optabgen_output = debtab.c optab.c cdxxx.c elxxx.c fltables.c tytab.c +$(optabgen_output) : optabgen + +######## idgen generates some source + +idgen_output = id.h id.c +$(idgen_output) : idgen + +idgen : idgen.c + $(ENVP) $(CC) idgen.c -o idgen + ./idgen + +######### impcnvgen generates some source + +impcnvtab_output = impcnvtab.c +$(impcnvtab_output) : impcnvgen + +impcnvgen : mtype.h impcnvgen.c + $(ENVP) $(CC) $(CFLAGS) impcnvgen.c -o impcnvgen + ./impcnvgen + +######### + +$(DMD_OBJS) : $(idgen_output) $(optabgen_output) $(impcnvgen_output) + +aa.o: $C/aa.c $C/aa.h $C/tinfo.h + $(CC) -c $(MFLAGS) -I. $< + +aav.o: $(ROOT)/aav.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +access.o: access.c + $(CC) -c $(CFLAGS) $< + +aliasthis.o: aliasthis.c + $(CC) -c $(CFLAGS) $< + +argtypes.o: argtypes.c + $(CC) -c $(CFLAGS) $< + +array.o: $(ROOT)/array.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +arrayop.o: arrayop.c + $(CC) -c $(CFLAGS) $< + +async.o: $(ROOT)/async.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +attrib.o: attrib.c + $(CC) -c $(CFLAGS) $< + +bcomplex.o: $C/bcomplex.c + $(CC) -c $(MFLAGS) $< + +bit.o: bit.c expression.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +blockopt.o: $C/blockopt.c + $(CC) -c $(MFLAGS) $< + +builtin.o: builtin.c + $(CC) -c $(CFLAGS) $< + +cast.o: cast.c + $(CC) -c $(CFLAGS) $< + +cg.o: $C/cg.c fltables.c + $(CC) -c $(MFLAGS) -I. $< + +cg87.o: $C/cg87.c + $(CC) -c $(MFLAGS) $< + +cgcod.o: $C/cgcod.c + $(CC) -c $(MFLAGS) -I. $< + +cgcs.o: $C/cgcs.c + $(CC) -c $(MFLAGS) $< + +cgcv.o: $C/cgcv.c + $(CC) -c $(MFLAGS) $< + +cgelem.o: $C/cgelem.c $C/rtlsym.h + $(CC) -c $(MFLAGS) -I. $< + +cgen.o: $C/cgen.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +cgobj.o: $C/cgobj.c + $(CC) -c $(MFLAGS) $< + +cgreg.o: $C/cgreg.c + $(CC) -c $(MFLAGS) $< + +cgsched.o: $C/cgsched.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +class.o: class.c + $(CC) -c $(CFLAGS) $< + +clone.o: clone.c + $(CC) -c $(CFLAGS) $< + +cod1.o: $C/cod1.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +cod2.o: $C/cod2.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +cod3.o: $C/cod3.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +cod4.o: $C/cod4.c + $(CC) -c $(MFLAGS) $< + +cod5.o: $C/cod5.c + $(CC) -c $(MFLAGS) $< + +code.o: $C/code.c + $(CC) -c $(MFLAGS) $< + +constfold.o: constfold.c + $(CC) -c $(CFLAGS) $< + +irstate.o: irstate.c irstate.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +csymbol.o: $C/symbol.c + $(CC) -c $(MFLAGS) $< -o $@ + +dchar.o: $(ROOT)/dchar.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +cond.o: cond.c + $(CC) -c $(CFLAGS) $< + +cppmangle.o: cppmangle.c + $(CC) -c $(CFLAGS) $< + +debug.o: $C/debug.c + $(CC) -c $(MFLAGS) -I. $< + +declaration.o: declaration.c + $(CC) -c $(CFLAGS) $< + +delegatize.o: delegatize.c + $(CC) -c $(CFLAGS) $< + +doc.o: doc.c + $(CC) -c $(CFLAGS) $< + +dsymbol.o: dsymbol.c + $(CC) -c $(CFLAGS) $< + +dt.o: $C/dt.c $C/dt.h + $(CC) -c $(MFLAGS) $< + +dump.o: dump.c + $(CC) -c $(CFLAGS) $< + +dwarf.o: $C/dwarf.c $C/dwarf.h + $(CC) -c $(MFLAGS) -I. $< + +e2ir.o: e2ir.c $C/rtlsym.h expression.h toir.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +ee.o: $C/ee.c + $(CC) -c $(MFLAGS) $< + +eh.o: eh.c $C/cc.h $C/code.h $C/type.h $C/dt.h + $(CC) -c $(MFLAGS) $< + +el.o: $C/el.c $C/rtlsym.h $C/el.h $C/el.c + $(CC) -c $(MFLAGS) $< + +elfobj.o: $C/elfobj.c + $(CC) -c $(MFLAGS) $< + +entity.o: entity.c + $(CC) -c $(CFLAGS) $< + +enum.o: enum.c + $(CC) -c $(CFLAGS) $< + +evalu8.o: $C/evalu8.c + $(CC) -c $(MFLAGS) $< + +expression.o: expression.c + $(CC) -c $(CFLAGS) $< + +func.o: func.c + $(CC) -c $(CFLAGS) $< + +gdag.o: $C/gdag.c + $(CC) -c $(MFLAGS) $< + +gflow.o: $C/gflow.c + $(CC) -c $(MFLAGS) $< + +#globals.o: globals.c +# $(CC) -c $(CFLAGS) $< + +glocal.o: $C/glocal.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +gloop.o: $C/gloop.c + $(CC) -c $(MFLAGS) $< + +glue.o: glue.c $(CH) $C/rtlsym.h mars.h module.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +gnuc.o: $(ROOT)/gnuc.c $(ROOT)/gnuc.h + $(CC) -c $(GFLAGS) $< + +go.o: $C/go.c + $(CC) -c $(MFLAGS) $< + +gother.o: $C/gother.c + $(CC) -c $(MFLAGS) $< + +hdrgen.o: hdrgen.c + $(CC) -c $(CFLAGS) $< + +html.o: $C/html.c $(CH) $C/html.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +iasm.o: iasm.c $(CH) $C/iasm.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +id.o: id.c id.h + $(CC) -c $(CFLAGS) $< + +identifier.o: identifier.c + $(CC) -c $(CFLAGS) $< + +impcnvtab.o: impcnvtab.c mtype.h + $(CC) -c $(CFLAGS) -I$(ROOT) $< + +imphint.o: imphint.c + $(CC) -c $(CFLAGS) $< + +import.o: import.c + $(CC) -c $(CFLAGS) $< + +inifile.o: inifile.c + $(CC) -c $(CFLAGS) $< + +init.o: init.c + $(CC) -c $(CFLAGS) $< + +inline.o: inline.c + $(CC) -c $(CFLAGS) $< + +interpret.o: interpret.c + $(CC) -c $(CFLAGS) $< + +json.o: json.c + $(CC) -c $(CFLAGS) $< + +lexer.o: lexer.c + $(CC) -c $(CFLAGS) $< + +libelf.o: libelf.c $C/melf.h + $(CC) -c $(CFLAGS) -I$C $< + +libmach.o: libmach.c $C/mach.h + $(CC) -c $(CFLAGS) -I$C $< + +link.o: link.c + $(CC) -c $(CFLAGS) $< + +lstring.o: $(ROOT)/lstring.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +machobj.o: $C/machobj.c + $(CC) -c $(MFLAGS) -I. $< + +macro.o: macro.c + $(CC) -c $(CFLAGS) $< + +man.o: $(ROOT)/man.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +mangle.o: mangle.c + $(CC) -c $(CFLAGS) $< + +mars.o: mars.c + $(CC) -c $(CFLAGS) $< + +rmem.o: $(ROOT)/rmem.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +module.o: module.c $C/html.h + $(CC) -c $(CFLAGS) -I$C $< + +msc.o: msc.c $(CH) mars.h + $(CC) -c $(MFLAGS) $< + +mtype.o: mtype.c + $(CC) -c $(CFLAGS) $< + +nteh.o: $C/nteh.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +opover.o: opover.c + $(CC) -c $(CFLAGS) $< + +optimize.o: optimize.c + $(CC) -c $(CFLAGS) $< + +os.o: $C/os.c + $(CC) -c $(MFLAGS) $< + +out.o: $C/out.c + $(CC) -c $(MFLAGS) $< + +outbuf.o: $C/outbuf.c $C/outbuf.h + $(CC) -c $(MFLAGS) $< + +parse.o: parse.c + $(CC) -c $(CFLAGS) $< + +ph.o: ph.c + $(CC) -c $(MFLAGS) $< + +port.o: $(ROOT)/port.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +ptrntab.o: $C/ptrntab.c $C/iasm.h + $(CC) -c $(MFLAGS) $< + +response.o: $(ROOT)/response.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +root.o: $(ROOT)/root.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +rtlsym.o: $C/rtlsym.c $C/rtlsym.h + $(CC) -c $(MFLAGS) $< + +s2ir.o: s2ir.c $C/rtlsym.h statement.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +scope.o: scope.c + $(CC) -c $(CFLAGS) $< + +speller.o: $(ROOT)/speller.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +statement.o: statement.c + $(CC) -c $(CFLAGS) $< + +staticassert.o: staticassert.c staticassert.h + $(CC) -c $(CFLAGS) $< + +stringtable.o: $(ROOT)/stringtable.c + $(CC) -c $(GFLAGS) -I$(ROOT) $< + +strtold.o: $C/strtold.c + gcc -m$(MODEL) -c $< + +struct.o: struct.c + $(CC) -c $(CFLAGS) $< + +template.o: template.c + $(CC) -c $(CFLAGS) $< + +ti_achar.o: $C/ti_achar.c $C/tinfo.h + $(CC) -c $(MFLAGS) -I. $< + +ti_pvoid.o: $C/ti_pvoid.c $C/tinfo.h + $(CC) -c $(MFLAGS) -I. $< + +tk.o: tk.c + $(CC) -c $(MFLAGS) $< + +tocsym.o: tocsym.c $(CH) mars.h module.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +toctype.o: toctype.c $(CH) $C/rtlsym.h mars.h module.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +todt.o: todt.c mtype.h expression.h $C/dt.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +toelfdebug.o: toelfdebug.c $(CH) mars.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +toir.o: toir.c $C/rtlsym.h expression.h toir.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +toobj.o: toobj.c $(CH) mars.h module.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +traits.o: traits.c + $(CC) -c $(CFLAGS) $< + +type.o: $C/type.c + $(CC) -c $(MFLAGS) $< + +typinf.o: typinf.c $(CH) mars.h module.h mtype.h + $(CC) -c $(MFLAGS) -I$(ROOT) $< + +util.o: util.c + $(CC) -c $(MFLAGS) $< + +utf.o: utf.c utf.h + $(CC) -c $(CFLAGS) $< + +unialpha.o: unialpha.c + $(CC) -c $(CFLAGS) $< + +unittests.o: unittests.c + $(CC) -c $(CFLAGS) $< + +var.o: $C/var.c optab.c + $(CC) -c $(MFLAGS) -I. $< + +version.o: version.c + $(CC) -c $(CFLAGS) $< + +###################################################### + +gcov: + gcov access.c + gcov aliasthis.c + gcov arrayop.c + gcov attrib.c + gcov bit.c + gcov builtin.c + gcov cast.c + gcov class.c + gcov clone.c + gcov cond.c + gcov constfold.c + gcov declaration.c + gcov delegatize.c + gcov doc.c + gcov dsymbol.c + gcov dump.c + gcov e2ir.c + gcov eh.c + gcov entity.c + gcov enum.c + gcov expression.c + gcov func.c + gcov glue.c + gcov iasm.c + gcov identifier.c + gcov imphint.c + gcov import.c + gcov inifile.c + gcov init.c + gcov inline.c + gcov interpret.c + gcov irstate.c + gcov json.c + gcov lexer.c +ifeq (OSX,$(TARGET)) + gcov libmach.c +else + gcov libelf.c +endif + gcov link.c + gcov macro.c + gcov mangle.c + gcov mars.c + gcov module.c + gcov msc.c + gcov mtype.c + gcov opover.c + gcov optimize.c + gcov parse.c + gcov ph.c + gcov scope.c + gcov statement.c + gcov staticassert.c + gcov s2ir.c + gcov struct.c + gcov template.c + gcov tk.c + gcov tocsym.c + gcov todt.c + gcov toobj.c + gcov toctype.c + gcov toelfdebug.c + gcov typinf.c + gcov unialpha.c + gcov utf.c + gcov util.c + gcov version.c + +# gcov hdrgen.c +# gcov tocvdebug.c + +###################################################### + +zip: + -rm -f dmdsrc.zip + zip dmdsrc $(SRC) diff --git a/src/root/dchar.c b/src/root/dchar.c index c9462197633f..0b11a8a42b1a 100644 --- a/src/root/dchar.c +++ b/src/root/dchar.c @@ -327,7 +327,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) case 2: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += *(const uint16_t *)str; #else hash += str[0] * 256 + str[1]; @@ -336,7 +336,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) case 3: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += (*(const uint16_t *)str << 8) + ((const uint8_t *)str)[2]; #else @@ -346,7 +346,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) default: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += *(const uint32_t *)str; #else hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3]; @@ -379,7 +379,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) case 2: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += *(const uint16_t *)str; #else hash += str[0] * 256 + str[1]; @@ -388,7 +388,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) case 3: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += (*(const uint16_t *)str << 8) + ((const uint8_t *)str)[2]; #else @@ -398,7 +398,7 @@ hash_t Dchar::calcHash(const dchar *str, size_t len) default: hash *= 37; -#if __I86__ +#if LITTLE_ENDIAN hash += *(const uint32_t *)str; #else hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3]; diff --git a/src/solaris.mak b/src/solaris.mak index 882aa55efd70..732cb83bbe54 100644 --- a/src/solaris.mak +++ b/src/solaris.mak @@ -17,8 +17,8 @@ WARNINGS=-Wno-deprecated -Wstrict-aliasing #GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -g -DDEBUG=1 -DUNITTEST $(COV) GFLAGS = $(WARNINGS) -D__near= -D__pascal= -fno-exceptions -O2 -CFLAGS = $(GFLAGS) -I$(ROOT) -D__I86__=1 -DMARS=1 -DTARGET_SOLARIS=1 -D_DH -MFLAGS = $(GFLAGS) -I$C -I$(TK) -D__I86__=1 -DMARS=1 -DTARGET_SOLARIS=1 -D_DH +CFLAGS = $(GFLAGS) -I$(ROOT) -DMARS=1 -DTARGET_SOLARIS=1 +MFLAGS = $(GFLAGS) -I$C -I$(TK) -DMARS=1 -DTARGET_SOLARIS=1 CH= $C/cc.h $C/global.h $C/parser.h $C/oper.h $C/code.h $C/type.h \ $C/dt.h $C/cgcv.h $C/el.h $C/iasm.h @@ -174,7 +174,7 @@ builtin.o: builtin.c $(CC) -c $(CFLAGS) $< cast.o: cast.c - $(CC) -c $(CFLAGS) $< + $(CC) -c $(CFLAGS) $< cg.o: fltables.c $C/cg.c $(CC) -c $(MFLAGS) -I. $C/cg.c @@ -403,7 +403,7 @@ mars.o: mars.c rmem.o: $(ROOT)/rmem.c $(CC) -c $(GFLAGS) -I$(ROOT) $(ROOT)/rmem.c - + module.o: $(TOTALH) $C/html.h module.c $(CC) -c $(CFLAGS) -I$C module.c diff --git a/src/statement.c b/src/statement.c index de16afbda1ab..ef84a100d0ab 100644 --- a/src/statement.c +++ b/src/statement.c @@ -37,11 +37,9 @@ extern int os_critsecsize64(); Statement::Statement(Loc loc) : loc(loc) { -#ifdef _DH // If this is an in{} contract scope statement (skip for determining // inlineStatus of a function body for header content) incontract = 0; -#endif } Statement *Statement::syntaxCopy() diff --git a/src/statement.h b/src/statement.h index 1532cd75a994..ae07c9a5cff0 100644 --- a/src/statement.h +++ b/src/statement.h @@ -92,9 +92,7 @@ struct Statement : Object void error(const char *format, ...); void warning(const char *format, ...); virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); -#ifdef _DH int incontract; -#endif virtual ScopeStatement *isScopeStatement() { return NULL; } virtual Statement *semantic(Scope *sc); Statement *semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue); diff --git a/src/staticassert.h b/src/staticassert.h index 632c1e901725..2f7e0906e7dd 100644 --- a/src/staticassert.h +++ b/src/staticassert.h @@ -18,9 +18,7 @@ #include "dsymbol.h" struct Expression; -#ifdef _DH struct HdrGenState; -#endif struct StaticAssert : Dsymbol { diff --git a/src/template.c b/src/template.c index 961a5bb0afd8..4ea2eb6dc514 100644 --- a/src/template.c +++ b/src/template.c @@ -1660,11 +1660,14 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { -#if 0 // Should handle template functions +#if 0 // Should handle template functions for doc generation if (onemember && onemember->isFuncDeclaration()) buf->writestring("foo "); #endif - buf->writestring(kind()); + if (hgs->ddoc) + buf->writestring(kind()); + else + buf->writestring("template"); buf->writeByte(' '); buf->writestring(ident->toChars()); buf->writeByte('('); diff --git a/src/win32.mak b/src/win32.mak index ccb5a7080d1b..f7301a2e3c9c 100644 --- a/src/win32.mak +++ b/src/win32.mak @@ -32,8 +32,8 @@ LFLAGS= LINKN=$(SCROOT)\bin\link /de -CFLAGS=-I$(ROOT);$(INCLUDE) $(XFLG) $(OPT) $(DEBUG) -cpp -D_DH -MFLAGS=-I$C;$(TK) -DMARS -cpp $(DEBUG) -e -wx -D_DH +CFLAGS=-I$(ROOT);$(INCLUDE) $(XFLG) $(OPT) $(DEBUG) -cpp +MFLAGS=-I$C;$(TK) -DMARS -cpp $(DEBUG) -e -wx # Makerules: .c.obj: @@ -155,7 +155,7 @@ ROOTSRC= $(ROOT)\dchar.h $(ROOT)\dchar.c $(ROOT)\lstring.h \ $(ROOT)\speller.h $(ROOT)\speller.c \ $(ROOT)\aav.h $(ROOT)\aav.c -MAKEFILES=win32.mak linux.mak osx.mak freebsd.mak solaris.mak openbsd.mak +MAKEFILES=win32.mak posix.mak ######################################### diff --git a/test/compilable/extra-files/xheader.di b/test/compilable/extra-files/xheader.di index 6573720b0beb..604cb3e97c7c 100644 --- a/test/compilable/extra-files/xheader.di +++ b/test/compilable/extra-files/xheader.di @@ -30,3 +30,23 @@ return 0; } } +template foo3(T) +{ +T foo3() +{ +} +} +template Foo4(T) +{ +struct Foo4 +{ + T x; +} +} +template C4(T) +{ +class C4 +{ + T x; +} +} diff --git a/test/compilable/interpret3.d b/test/compilable/interpret3.d index 815212a05411..3ffeea8ac730 100644 --- a/test/compilable/interpret3.d +++ b/test/compilable/interpret3.d @@ -692,6 +692,15 @@ static assert(bug5852("abc")==3); static assert( ['a', 'b'] ~ "c" == "abc" ); +/******************************************* + Bug 6159 +*******************************************/ + +struct A6159 {} + +static assert({ return A6159.init is A6159.init;}()); +static assert({ return [1] is [1];}()); + /******************************************* Bug 5685 *******************************************/ @@ -1657,3 +1666,63 @@ static assert( return *p; }() == 'a' ); + +struct AList +{ + AList * next; + int value; + static AList * newList() + { + AList[] z = new AList[1]; + return &z[0]; + } + static AList * make(int i, int j) + { + auto r = newList(); + r.next = (new AList[1]).ptr; + r.value = 1; + AList * z= r.next; + (*z).value = 2; + r.next.value = j; + assert(r.value == 1); + assert(r.next.value == 2); + r.next.next = &(new AList[1])[0]; + assert(r.next.next != null); + assert(r.next.next); + r.next.next.value = 3; + assert(r.next.next.value == 3); + r.next.next = newList(); + r.next.next.value = 9; + return r; + } + static int checkList() + { + auto r = make(1,2); + assert(r.value == 1); + assert(r.next.value == 2); + assert(r.next.next.value == 9); + return 2; + } +} + +static assert(AList.checkList()==2); + +/************************************************** + 4065 [CTFE] AA "in" operator doesn't work +**************************************************/ + +bool bug4065(string s) { + enum int[string] aa = ["aa":14, "bb":2]; + int *p = s in aa; + if (s == "aa") + assert(*p == 14); + else if (s=="bb") + assert(*p == 2); + else assert(!p); + bool c = !p; + return cast(bool)(s in aa); +} + +static assert(!bug4065("xx")); +static assert(bug4065("aa")); +static assert(bug4065("bb")); diff --git a/test/compilable/xheader.d b/test/compilable/xheader.d index dc121f9ccb8d..1df09e694a29 100644 --- a/test/compilable/xheader.d +++ b/test/compilable/xheader.d @@ -29,4 +29,14 @@ struct Foo3 class C3 { @property int get() { return 0; } } +T foo3(T)() {} +struct Foo4(T) +{ + T x; +} + +class C4(T) +{ + T x; +} diff --git a/test/runnable/xtest46.d b/test/runnable/xtest46.d index 57c6caedbfb2..df8fa1e25d54 100644 --- a/test/runnable/xtest46.d +++ b/test/runnable/xtest46.d @@ -2842,6 +2842,63 @@ void test146() std.c.stdio.printf("hello world 146\n"); } +/***************************************************/ +// 5856 + +struct X147 +{ + void f() { writeln("X.f mutable"); } + void f() const { writeln("X.f const"); } + + void g()() { writeln("X.g mutable"); } + void g()() const { writeln("X.g const"); } + + void opOpAssign(string op)(int n) { writeln("X+= mutable"); } + void opOpAssign(string op)(int n) const { writeln("X+= const"); } +} + +void test147() +{ + X147 xm; + xm.f(); // prints "X.f mutable" + xm.g(); // prints "X.g mutable" + xm += 10; // should print "X+= mutable" (1) + + const(X147) xc; + xc.f(); // prints "X.f const" + xc.g(); // prints "X.g const" + xc += 10; // should print "X+= const" (2) +} + + +/***************************************************/ +// 5897 + +struct A148{ int n; } +struct B148{ + int n, m; + this(A148 a){ n = a.n, m = a.n*2; } +} + +struct C148{ + int n, m; + static C148 opCall(A148 a) + { + C148 b; + b.n = a.n, b.m = a.n*2; + return b; + } +} + +void test148() +{ + auto a = A148(10); + auto b = cast(B148)a; + assert(b.n == 10 && b.m == 20); + auto c = cast(C148)a; + assert(c.n == 10 && c.m == 20); +} + /***************************************************/ int main() @@ -2992,6 +3049,8 @@ int main() test144(); test145(); test146(); + test147(); + test148(); printf("Success\n"); return 0;