Mercurial > projects > ldc
changeset 130:a7dfa0ed966c trunk
[svn r134] Merged the DMD 1.024 frontend.
Added std.base64.
author | lindquist |
---|---|
date | Fri, 28 Dec 2007 23:52:40 +0100 |
parents | 8096ba7082db |
children | 5825d48b27d1 |
files | dmd/declaration.c dmd/declaration.h dmd/doc.c dmd/expression.c dmd/func.c dmd/mars.c dmd/module.c dmd/module.h dmd/mtype.c dmd/opover.c dmd/template.c dmd/template.h lphobos/phobos.d lphobos/std/base64.d |
diffstat | 14 files changed, 387 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/declaration.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/declaration.c Fri Dec 28 23:52:40 2007 +0100 @@ -29,6 +29,7 @@ : Dsymbol(id) { type = NULL; + originalType = NULL; storage_class = STCundefined; protection = PROTundefined; linkage = LINKdefault; @@ -622,9 +623,13 @@ * declarations. */ storage_class &= ~STCauto; + originalType = type; } else + { if (!originalType) + originalType = type; type = type->semantic(loc, sc); + } type->checkDeprecated(loc, sc); linkage = sc->linkage;
--- a/dmd/declaration.h Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/declaration.h Fri Dec 28 23:52:40 2007 +0100 @@ -91,6 +91,7 @@ struct Declaration : Dsymbol { Type *type; + Type *originalType; // before semantic analysis unsigned storage_class; enum PROT protection; enum LINK linkage; @@ -114,6 +115,7 @@ int isFinal() { return storage_class & STCfinal; } int isAbstract() { return storage_class & STCabstract; } int isConst() { return storage_class & STCconst; } + int isInvariant() { return 0; } int isAuto() { return storage_class & STCauto; } int isScope() { return storage_class & (STCscope | STCauto); } int isSynchronized() { return storage_class & STCsynchronized; }
--- a/dmd/doc.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/doc.c Fri Dec 28 23:52:40 2007 +0100 @@ -269,7 +269,6 @@ } buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); - if (isDocFile) { size_t commentlen = strlen((char *)comment); @@ -283,7 +282,6 @@ } else { - dc->writeSections(sc, this, sc->docbuf); emitMemberComments(sc); } @@ -654,6 +652,10 @@ buf->writestring("static "); if (d->isConst()) buf->writestring("const "); +#if V2 + if (d->isInvariant()) + buf->writestring("invariant "); +#endif if (d->isFinal()) buf->writestring("final "); if (d->isSynchronized()) @@ -663,7 +665,7 @@ void Declaration::toDocBuffer(OutBuffer *buf) { - //printf("Declaration::toDocbuffer() %s\n", toChars()); + //printf("Declaration::toDocbuffer() %s, originalType = %p\n", toChars(), originalType); if (ident) { prefix(buf, this); @@ -671,7 +673,12 @@ if (type) { HdrGenState hgs; hgs.ddoc = 1; - type->toCBuffer(buf, ident, &hgs); + if (originalType) + { //originalType->print(); + originalType->toCBuffer(buf, ident, &hgs); + } + else + type->toCBuffer(buf, ident, &hgs); } else buf->writestring(ident->toChars()); @@ -723,10 +730,11 @@ td->onemember == this) { HdrGenState hgs; unsigned o = buf->offset; + TypeFunction *tf = (TypeFunction *)type; hgs.ddoc = 1; prefix(buf, td); - type->next->toCBuffer(buf, NULL, &hgs); + tf->next->toCBuffer(buf, NULL, &hgs); buf->writeByte(' '); buf->writestring(ident->toChars()); buf->writeByte('('); @@ -738,7 +746,6 @@ tp->toCBuffer(buf, &hgs); } buf->writeByte(')'); - TypeFunction *tf = (TypeFunction *)type; Argument::argsToCBuffer(buf, &hgs, tf->parameters, tf->varargs); buf->writestring(";\n");
--- a/dmd/expression.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/expression.c Fri Dec 28 23:52:40 2007 +0100 @@ -1270,7 +1270,7 @@ char *RealExp::toChars() { - static char buffer[sizeof(value) * 3 + 8 + 1 + 1]; + char buffer[sizeof(value) * 3 + 8 + 1 + 1]; #ifdef IN_GCC value.format(buffer, sizeof(buffer)); @@ -1280,7 +1280,7 @@ sprintf(buffer, type->isimaginary() ? "%Lgi" : "%Lg", value); #endif assert(strlen(buffer) < sizeof(buffer)); - return buffer; + return mem.strdup(buffer); } integer_t RealExp::toInteger() @@ -1484,7 +1484,7 @@ char *ComplexExp::toChars() { - static char buffer[sizeof(value) * 3 + 8 + 1]; + char buffer[sizeof(value) * 3 + 8 + 1]; #ifdef IN_GCC char buf1[sizeof(value) * 3 + 8 + 1]; @@ -1496,7 +1496,7 @@ sprintf(buffer, "(%Lg+%Lgi)", creall(value), cimagl(value)); assert(strlen(buffer) < sizeof(buffer)); #endif - return buffer; + return mem.strdup(buffer); } integer_t ComplexExp::toInteger() @@ -3140,7 +3140,13 @@ if (cd->isInterfaceDeclaration()) error("cannot create instance of interface %s", cd->toChars()); else if (cd->isAbstract()) - error("cannot create instance of abstract class %s", cd->toChars()); + { error("cannot create instance of abstract class %s", cd->toChars()); + for (int i = 0; i < cd->vtbl.dim; i++) + { FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); + if (fd && fd->isAbstract()) + error("function %s is abstract", fd->toChars()); + } + } checkDeprecated(sc, cd); if (cd->isNested()) { /* We need a 'this' pointer for the nested class. @@ -5528,9 +5534,9 @@ TemplateDeclaration *td = dte->td; assert(td); if (!arguments) - // Should fix deduce() so it works on NULL argument + // Should fix deduceFunctionTemplate() so it works on NULL argument arguments = new Expressions(); - f = td->deduce(sc, loc, NULL, arguments); + f = td->deduceFunctionTemplate(sc, loc, NULL, arguments); if (!f) { type = Type::terror; return this; @@ -5705,7 +5711,7 @@ else if (e1->op == TOKtemplate) { TemplateExp *te = (TemplateExp *)e1; - f = te->td->deduce(sc, loc, NULL, arguments); + f = te->td->deduceFunctionTemplate(sc, loc, NULL, arguments); if (!f) { type = Type::terror; return this;
--- a/dmd/func.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/func.c Fri Dec 28 23:52:40 2007 +0100 @@ -145,6 +145,9 @@ if (isAbstract() && !isVirtual()) error("non-virtual functions cannot be abstract"); + + if (isAbstract() && isFinal()) + error("cannot be both final and abstract"); #if 0 if (isAbstract() && fbody) error("abstract functions cannot have bodies");
--- a/dmd/mars.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/mars.c Fri Dec 28 23:52:40 2007 +0100 @@ -71,7 +71,7 @@ copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen"; written = "written by Walter Bright and Tomas Lindquist Olsen"; llvmdc_version = "0.1"; - version = "v1.023"; + version = "v1.024"; global.structalign = 8; memset(¶ms, 0, sizeof(Param));
--- a/dmd/module.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/module.c Fri Dec 28 23:52:40 2007 +0100 @@ -87,6 +87,7 @@ vmoduleinfo = NULL; massert = NULL; marray = NULL; + sictor = NULL; sctor = NULL; sdtor = NULL; stest = NULL;
--- a/dmd/module.h Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/module.h Fri Dec 28 23:52:40 2007 +0100 @@ -147,6 +147,7 @@ Symbol *cov; // private uint[] __coverage; unsigned *covb; // bit array of valid code line numbers + Symbol *sictor; // module order independent constructor Symbol *sctor; // module constructor Symbol *sdtor; // module destructor Symbol *stest; // module unit test
--- a/dmd/mtype.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/mtype.c Fri Dec 28 23:52:40 2007 +0100 @@ -2742,38 +2742,50 @@ } //printf("TypeFunction::semantic() this = %p\n", this); - linkage = sc->linkage; - if (!next) + TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); + memcpy(tf, this, sizeof(TypeFunction)); + if (parameters) + { tf->parameters = (Arguments *)parameters->copy(); + for (size_t i = 0; i < parameters->dim; i++) + { Argument *arg = (Argument *)parameters->data[i]; + Argument *cpy = (Argument *)mem.malloc(sizeof(Argument)); + memcpy(cpy, arg, sizeof(Argument)); + tf->parameters->data[i] = (void *)cpy; + } + } + + tf->linkage = sc->linkage; + if (!tf->next) { assert(global.errors); - next = tvoid; - } - next = next->semantic(loc,sc); - if (next->toBasetype()->ty == Tsarray) - { error(loc, "functions cannot return static array %s", next->toChars()); - next = Type::terror; - } - if (next->toBasetype()->ty == Tfunction) + tf->next = tvoid; + } + tf->next = tf->next->semantic(loc,sc); + if (tf->next->toBasetype()->ty == Tsarray) + { error(loc, "functions cannot return static array %s", tf->next->toChars()); + tf->next = Type::terror; + } + if (tf->next->toBasetype()->ty == Tfunction) { error(loc, "functions cannot return a function"); - next = Type::terror; - } - if (next->toBasetype()->ty == Ttuple) + tf->next = Type::terror; + } + if (tf->next->toBasetype()->ty == Ttuple) { error(loc, "functions cannot return a tuple"); - next = Type::terror; - } - if (next->isauto() && !(sc->flags & SCOPEctor)) - error(loc, "functions cannot return auto %s", next->toChars()); - - if (parameters) - { size_t dim = Argument::dim(parameters); + tf->next = Type::terror; + } + if (tf->next->isauto() && !(sc->flags & SCOPEctor)) + error(loc, "functions cannot return auto %s", tf->next->toChars()); + + if (tf->parameters) + { size_t dim = Argument::dim(tf->parameters); for (size_t i = 0; i < dim; i++) - { Argument *arg = Argument::getNth(parameters, i); + { Argument *arg = Argument::getNth(tf->parameters, i); Type *t; - inuse++; + tf->inuse++; arg->type = arg->type->semantic(loc,sc); - if (inuse == 1) inuse--; + if (tf->inuse == 1) tf->inuse--; t = arg->type->toBasetype(); if (arg->storageClass & (STCout | STCref | STClazy)) @@ -2795,27 +2807,27 @@ * change. */ if (t->ty == Ttuple) - { dim = Argument::dim(parameters); + { dim = Argument::dim(tf->parameters); i--; } } } - deco = merge()->deco; - - if (inuse) + tf->deco = tf->merge()->deco; + + if (tf->inuse) { error(loc, "recursive type"); - inuse = 0; + tf->inuse = 0; return terror; } - if (varargs == 1 && linkage != LINKd && Argument::dim(parameters) == 0) + if (tf->varargs == 1 && tf->linkage != LINKd && Argument::dim(tf->parameters) == 0) error(loc, "variadic functions with non-D linkage must have at least one parameter"); /* Don't return merge(), because arg identifiers and default args * can be different * even though the types match */ - return this; + return tf; } /********************************
--- a/dmd/opover.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/opover.c Fri Dec 28 23:52:40 2007 +0100 @@ -729,7 +729,7 @@ FuncDeclaration *fd; assert(td); - fd = td->deduce(sc, loc, targsi, arguments); + fd = td->deduceFunctionTemplate(sc, loc, targsi, arguments); if (!fd) return; m->anyf = fd;
--- a/dmd/template.c Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/template.c Fri Dec 28 23:52:40 2007 +0100 @@ -647,7 +647,7 @@ * dedargs Expression/Type deduced template arguments */ -MATCH TemplateDeclaration::deduceMatch(Objects *targsi, Expressions *fargs, +MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs) { size_t i; @@ -662,7 +662,7 @@ Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T #if 0 - printf("\nTemplateDeclaration::deduceMatch() %s\n", toChars()); + printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); for (i = 0; i < fargs->dim; i++) { Expression *e = (Expression *)fargs->data[i]; printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); @@ -985,7 +985,7 @@ * fargs arguments to function */ -FuncDeclaration *TemplateDeclaration::deduce(Scope *sc, Loc loc, +FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs) { MATCH m_best = MATCHnomatch; @@ -996,7 +996,7 @@ FuncDeclaration *fd; #if 0 - printf("TemplateDeclaration::deduce() %s\n", toChars()); + printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars()); printf(" targsi:\n"); if (targsi) { for (int i = 0; i < targsi->dim; i++) @@ -1028,8 +1028,8 @@ MATCH m; Objects dedargs; - m = td->deduceMatch(targsi, fargs, &dedargs); - //printf("deduceMatch = %d\n", m); + m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs); + //printf("deduceFunctionTemplateMatch = %d\n", m); if (!m) // if no match continue;
--- a/dmd/template.h Fri Dec 28 22:55:24 2007 +0100 +++ b/dmd/template.h Fri Dec 28 23:52:40 2007 +0100 @@ -71,8 +71,8 @@ MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); int leastAsSpecialized(TemplateDeclaration *td2); - MATCH deduceMatch(Objects *targsi, Expressions *fargs, Objects *dedargs); - FuncDeclaration *deduce(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs); + MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs); + FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs); void declareParameter(Scope *sc, TemplateParameter *tp, Object *o); TemplateDeclaration *isTemplateDeclaration() { return this; }
--- a/lphobos/phobos.d Fri Dec 28 22:55:24 2007 +0100 +++ b/lphobos/phobos.d Fri Dec 28 23:52:40 2007 +0100 @@ -2,16 +2,18 @@ import std.array, +std.base64, std.ctype, std.format, std.intrinsic, std.math, std.moduleinit, std.outofmemory, +std.stdarg, std.stdint, std.stdio, -std.stdarg, std.string, +std.traits, std.uni, std.utf,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/std/base64.d Fri Dec 28 23:52:40 2007 +0100 @@ -0,0 +1,293 @@ +/** + * Encodes/decodes MIME base64 data. + * + * Macros: + * WIKI=Phobos/StdBase64 + * References: + * <a href="http://en.wikipedia.org/wiki/Base64">Wikipedia Base64</a>$(BR) + * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>$(BR) + */ + + +/* base64.d + * Modified from C. Miller's version, his copyright is below. + */ + +/* + Copyright (C) 2004 Christopher E. Miller + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +module std.base64; + +/** + */ + +class Base64Exception: Exception +{ + this(char[] msg) + { + super(msg); + } +} + + +/** + */ + +class Base64CharException: Base64Exception +{ + this(char[] msg) + { + super(msg); + } +} + + +const char[] array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +/** + * Returns the number of bytes needed to encode a string of length slen. + */ + +uint encodeLength(uint slen) +{ + uint result; + result = slen / 3; + if(slen % 3) + result++; + return result * 4; +} + +/** + * Encodes str[] and places the result in buf[]. + * Params: + * str = string to encode + * buf = destination buffer, must be large enough for the result. + * Returns: + * slice into buf[] representing encoded result + */ + +char[] encode(char[] str, char[] buf) +in +{ + assert(buf.length >= encodeLength(str.length)); +} +body +{ + if(!str.length) + return buf[0 .. 0]; + + uint stri; + uint strmax = str.length / 3; + uint strleft = str.length % 3; + uint x; + char* sp, bp; + + bp = &buf[0]; + sp = &str[0]; + for(stri = 0; stri != strmax; stri++) + { + x = (sp[0] << 16) | (sp[1] << 8) | (sp[2]); + sp+= 3; + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6]; + *bp++ = array[(x & 0b00000000_00000000_00111111)]; + } + + switch(strleft) + { + case 2: + x = (sp[0] << 16) | (sp[1] << 8); + sp += 2; + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = array[(x & 0b00000000_00001111_11000000) >> 6]; + *bp++ = '='; + break; + + case 1: + x = *sp++ << 16; + *bp++ = array[(x & 0b11111100_00000000_00000000) >> 18]; + *bp++ = array[(x & 0b00000011_11110000_00000000) >> 12]; + *bp++ = '='; + *bp++ = '='; + break; + + case 0: + break; + + default: + assert(0); + } + + return buf[0 .. (bp - &buf[0])]; +} + + +/** + * Encodes str[] and returns the result. + */ + +char[] encode(char[] str) +{ + return encode(str, new char[encodeLength(str.length)]); +} + + +unittest +{ + assert(encode("f") == "Zg=="); + assert(encode("fo") == "Zm8="); + assert(encode("foo") == "Zm9v"); + assert(encode("foos") == "Zm9vcw=="); + assert(encode("all your base64 are belong to foo") == "YWxsIHlvdXIgYmFzZTY0IGFyZSBiZWxvbmcgdG8gZm9v"); +} + + +/** + * Returns the number of bytes needed to decode an encoded string of this + * length. + */ +uint decodeLength(uint elen) +{ + return elen / 4 * 3; +} + + +/** + * Decodes str[] and places the result in buf[]. + * Params: + * str = string to encode + * buf = destination buffer, must be large enough for the result. + * Returns: + * slice into buf[] representing encoded result + * Errors: + * Throws Base64Exception on invalid base64 encoding in estr[]. + * Throws Base64CharException on invalid base64 character in estr[]. + */ +char[] decode(char[] estr, char[] buf) +in +{ + assert(buf.length + 2 >= decodeLength(estr.length)); //account for '=' padding +} +body +{ + void badc(char ch) + { + throw new Base64CharException("Invalid base64 character '" ~ (&ch)[0 .. 1] ~ "'"); + } + + + uint arrayIndex(char ch) + out(result) + { + assert(ch == array[result]); + } + body + { + if(ch >= 'A' && ch <= 'Z') + return ch - 'A'; + if(ch >= 'a' && ch <= 'z') + return 'Z' - 'A' + 1 + ch - 'a'; + if(ch >= '0' && ch <= '9') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + ch - '0'; + if(ch == '+') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1; + if(ch == '/') + return 'Z' - 'A' + 1 + 'z' - 'a' + 1 + '9' - '0' + 1 + 1; + badc(ch); + assert(0); + } + + + if(!estr.length) + return buf[0 .. 0]; + + if(estr.length % 4) + throw new Base64Exception("Invalid encoded base64 string"); + + uint estri; + uint estrmax = estr.length / 4; + uint x; + char* sp, bp; + char ch; + + sp = &estr[0]; + bp = &buf[0]; + for(estri = 0; estri != estrmax; estri++) + { + x = arrayIndex(sp[0]) << 18 | arrayIndex(sp[1]) << 12; + sp += 2; + + ch = *sp++; + if(ch == '=') + { + if(*sp++ != '=') + badc('='); + *bp++ = cast(char) (x >> 16); + break; + } + x |= arrayIndex(ch) << 6; + + ch = *sp++; + if(ch == '=') + { + *bp++ = cast(char) (x >> 16); + *bp++ = cast(char) ((x >> 8) & 0xFF); + break; + } + x |= arrayIndex(ch); + + *bp++ = cast(char) (x >> 16); + *bp++ = cast(char) ((x >> 8) & 0xFF); + *bp++ = cast(char) (x & 0xFF); + } + + return buf[0 .. (bp - &buf[0])]; +} + +/** + * Decodes estr[] and returns the result. + * Errors: + * Throws Base64Exception on invalid base64 encoding in estr[]. + * Throws Base64CharException on invalid base64 character in estr[]. + */ + +char[] decode(char[] estr) +{ + return decode(estr, new char[decodeLength(estr.length)]); +} + + +unittest +{ + assert(decode(encode("f")) == "f"); + assert(decode(encode("fo")) == "fo"); + assert(decode(encode("foo")) == "foo"); + assert(decode(encode("foos")) == "foos"); + assert(decode(encode("all your base64 are belong to foo")) == "all your base64 are belong to foo"); + + assert(decode(encode("testing some more")) == "testing some more"); + assert(decode(encode("asdf jkl;")) == "asdf jkl;"); + assert(decode(encode("base64 stuff")) == "base64 stuff"); + assert(decode(encode("\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!")) == "\1\2\3\4\5\6\7foo\7\6\5\4\3\2\1!"); +} +