diff dmd/Parameter.d @ 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents dmd/Argument.d@1765f3ef917d
children 206db751bd4c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/Parameter.d	Thu Sep 09 22:51:44 2010 +0100
@@ -0,0 +1,303 @@
+module dmd.Parameter;
+
+import dmd.common;
+import dmd.Type;
+import dmd.Identifier;
+import dmd.TypeArray;
+import dmd.TypeFunction;
+import dmd.TypeDelegate;
+import dmd.TypeTuple;
+import dmd.TY;
+import dmd.Expression;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.ArrayTypes;
+import dmd.StorageClassDeclaration;
+import dmd.Global;
+import dmd.MOD;
+import dmd.CppMangleState;
+import dmd.STC;
+
+class Parameter
+{
+    //enum InOut inout;
+    STC storageClass;
+    Type type;
+    Identifier ident;
+    Expression defaultArg;
+
+    this(STC storageClass, Type type, Identifier ident, Expression defaultArg)
+	{
+		this.type = type;
+		this.ident = ident;
+		this.storageClass = storageClass;
+		this.defaultArg = defaultArg;
+	}
+	
+	Parameter clone()
+	{
+		return new Parameter(storageClass, type, ident, defaultArg);
+	}
+	
+    Parameter syntaxCopy()
+	{
+		return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null);
+	}
+	
+	/****************************************************
+	 * Determine if parameter is a lazy array of delegates.
+	 * If so, return the return type of those delegates.
+	 * If not, return null.
+	 */
+    Type isLazyArray()
+	{
+	//    if (inout == Lazy)
+		{
+			Type tb = type.toBasetype();
+			if (tb.ty == Tsarray || tb.ty == Tarray)
+			{
+				Type tel = (cast(TypeArray)tb).next.toBasetype();
+				if (tel.ty == Tdelegate)
+				{
+					TypeDelegate td = cast(TypeDelegate)tel;
+					TypeFunction tf = cast(TypeFunction)td.next;
+
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
+					{
+						return tf.next;	// return type of delegate
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+    void toDecoBuffer(OutBuffer buf)
+	{
+		if (storageClass & STC.STCscope)
+			buf.writeByte('M');
+		switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy))
+		{   
+			case STC.STCundefined:
+			case STC.STCin:
+				break;
+			case STC.STCout:
+				buf.writeByte('J');
+				break;
+			case STC.STCref:
+				buf.writeByte('K');
+				break;
+			case STC.STClazy:
+				buf.writeByte('L');
+				break;
+		}
+static if (false) {
+		int mod = 0x100;
+		if (type.toBasetype().ty == TY.Tclass)
+			mod = 0;
+		type.toDecoBuffer(buf, mod);
+} else {
+		//type.toHeadMutable().toDecoBuffer(buf, 0);
+		type.toDecoBuffer(buf, 0);
+}
+	}
+	
+    static Parameters arraySyntaxCopy(Parameters args)
+	{
+		typeof(return) a = null;
+
+		if (args)
+		{
+			a = new Parameters();
+			a.setDim(args.dim);
+
+			for (size_t i = 0; i < a.dim; i++)
+			{   
+				auto arg = args[i];
+
+				arg = arg.syntaxCopy();
+				a[i] = arg;
+			}
+		}
+	
+		return a;
+	}
+	
+    static string argsTypesToChars(Parameters args, int varargs)
+	{
+		scope OutBuffer buf = new OutBuffer();
+
+	static if (true) {
+		HdrGenState hgs;
+		argsToCBuffer(buf, &hgs, args, varargs);
+	} else {
+		buf.writeByte('(');
+		if (args)
+		{	
+			OutBuffer argbuf = new OutBuffer();
+			HdrGenState hgs;
+
+			for (int i = 0; i < args.dim; i++)
+			{   
+				if (i)
+					buf.writeByte(',');
+				auto arg = cast(Parameter)args.data[i];
+				argbuf.reset();
+				arg.type.toCBuffer2(&argbuf, &hgs, 0);
+				buf.write(&argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+		return buf.toChars();
+	}
+	
+    static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Parameters arguments, int varargs)
+	{
+		assert(false);
+	}
+	
+    static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Parameters arguments, int varargs)
+	{
+		buf.writeByte('(');
+		if (arguments)
+		{	
+			int i;
+			scope OutBuffer argbuf = new OutBuffer();
+
+			for (i = 0; i < arguments.dim; i++)
+			{
+				if (i)
+					buf.writestring(", ");
+				auto arg = arguments[i];
+
+				if (arg.storageClass & STCout)
+					buf.writestring("out ");
+				else if (arg.storageClass & STCref)
+					buf.writestring((global.params.Dversion == 1) ? "inout " : "ref ");
+				else if (arg.storageClass & STCin)
+					buf.writestring("in ");
+				else if (arg.storageClass & STClazy)
+					buf.writestring("lazy ");
+				else if (arg.storageClass & STCalias)
+					buf.writestring("alias ");
+				else if (arg.storageClass & STCauto)
+					buf.writestring("auto ");
+
+				uint stc = arg.storageClass;
+				if (arg.type && arg.type.mod & MODshared)
+					stc &= ~STCshared;
+
+				StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope));
+
+				argbuf.reset();
+				if (arg.storageClass & STCalias)
+				{	
+					if (arg.ident)
+						argbuf.writestring(arg.ident.toChars());
+				}
+				else
+					arg.type.toCBuffer(argbuf, arg.ident, hgs);
+				if (arg.defaultArg)
+				{
+					argbuf.writestring(" = ");
+					arg.defaultArg.toCBuffer(argbuf, hgs);
+				}
+				buf.write(argbuf);
+			}
+			if (varargs)
+			{
+				if (i && varargs == 1)
+					buf.writeByte(',');
+				buf.writestring("...");
+			}
+		}
+		buf.writeByte(')');
+	}
+	
+    static void argsToDecoBuffer(OutBuffer buf, Parameters arguments)
+	{
+		//printf("Parameter::argsToDecoBuffer()\n");
+
+		// Write argument types
+		if (arguments)
+		{
+			size_t dim = Parameter.dim(arguments);
+			for (size_t i = 0; i < dim; i++)
+			{
+				auto arg = Parameter.getNth(arguments, i);
+				arg.toDecoBuffer(buf);
+			}
+		}
+	}
+	
+    static int isTPL(Parameters arguments)
+	{
+		assert(false);
+	}
+
+	/***************************************
+	 * Determine number of arguments, folding in tuples.
+	 */	
+    static size_t dim(Parameters args)
+	{
+		size_t n = 0;
+		if (args)
+		{
+			foreach (arg; args)
+			{   
+				Type t = arg.type.toBasetype();
+
+				if (t.ty == TY.Ttuple)
+				{   
+					auto tu = cast(TypeTuple)t;
+					n += dim(tu.arguments);
+				}
+				else
+					n++;
+			}
+		}
+		return n;
+	}
+	
+	/***************************************
+	 * Get nth Parameter, folding in tuples.
+	 * Returns:
+	 *	Parameter	nth Parameter
+	 *	null		not found, *pn gets incremented by the number
+	 *			of Parameters
+	 */
+    static Parameter getNth(Parameters args, size_t nth, size_t* pn = null)
+	{
+		if (!args)
+			return null;
+
+		size_t n = 0;
+		foreach (arg; args)
+		{   
+			Type t = arg.type.toBasetype();
+
+			if (t.ty == TY.Ttuple)
+			{   TypeTuple tu = cast(TypeTuple)t;
+				arg = getNth(tu.arguments, nth - n, &n);
+				if (arg)
+					return arg;
+			}
+			else if (n == nth)
+				return arg;
+			else
+				n++;
+		}
+
+		if (pn)
+			*pn += n;
+
+		return null;
+	}
+}