/*
 * Bernoulli Compiler
 * Copyright (c) Cornell University
 * Department of Computer Science
 * 
 * Kamen Yotov (kamen@yotov.org)
 * 
 * $Source: C:/CVS/kyotov/kyotov/Research/BC/sequoia/Sequoia.cs,v $
 * $Revision: 1.5 $
 * $Date: 2002/12/05 03:07:54 $
 */

#define X

using System;
using System.IO;
using System.Collections;

using BC.Core.Exceptions;
using BC.Core.Passes;
using BC.Core.ASTs;

using BC.C;

using System.Resources;

class Sequoia
{
	static AbstractType RealType ()
	{
		return Create.RealType(BC.C.Definitions.RT_double.Precision);
	}

	static AbstractType IntegerType ()
	{
		return Create.IntegerType(BC.C.Definitions.IT_signed_int.Precision);
	}

	static AbstractElement Test (int n)
	{
		ArrayList s1 = new ArrayList();
		ArrayList s2 = new ArrayList();
		AbstractExpression r = null;

		for (int i = 0; i < n; i++)
		{
			s1.Add(Create.Statement(
				Create.Declaration(
					"t" + i, 
					RealType(), 
					Create.Initializer(Create.Expression(0)))));

			s2.Add(Create.Statement(
				Create.Expression(
					Operator.AddAssign,
					Create.Expression("t" + i),
					Create.Expression("d"))));

			if (r == null)
				r = Create.Expression("t" + i);
			else
				r = Create.Expression(Operator.Add, r, Create.Expression("t" + i));
		}

		s1.Add(Create.Statement(
			Create.Statement(Create.Declaration("i", IntegerType())),
			Create.ForStatement(
				Create.Expression(
					Operator.Assign,
					Create.Expression("i"),
					Create.Expression(0)),
				Create.Expression(
					Operator.Less,
					Create.Expression("i"),
					Create.Expression("R")),
				Create.Expression(
					Operator.PreIncrement,
					Create.Expression("i")),
				Create.Statement(Create.Statements(s2)))));

		s1.Add(Create.ReturnStatement(r));

		return Create.Method(
			"test" + n, 
			RealType(), 
			Create.Declarations(
				Create.Declaration("d", RealType()),
				Create.Declaration("R", IntegerType())),
			Create.Statement(
				Create.Statements(s1)));					
	}

	static readonly int max = 128;

	[STAThread]
	static void Main (string[] a)
	{
		try
		{
			BC.Core.Global.GetString = new CUI(BC.Core.Global.GetString).GetString;

			CRenderer w = new CRenderer("sequoia_test.cpp");

			Elements e = new Elements();

			e.Element = new AbstractElement[max + 1];
			AbstractInitializer[] b = new AbstractInitializer[max];

			e.Element[128] = Create.Declaration("tests", 
				Create.ArrayType(
					Create.IndirectType(
						Create.FunctionType(
							RealType(), 
							Create.Declaration(RealType()), 
							Create.Declaration(IntegerType()))), 
					Create.Expressions(null)),
				Create.Initializer(b));

			for (int i = 1; i <= 128; i++)
			{
				Console.Write("{0}\r", i);

				e.Element[i - 1] = Test(i);
				b[i - 1] = Create.Initializer(Create.Expression("test" + i));
			}

			Console.WriteLine("Done!");

			w.Execute(ref e);
		}
		catch (BCException e)
		{
			Console.WriteLine();
			Console.WriteLine(e);
		}
	}
}
