fixed to comply with latest changes to boo

namespace UnityScript.Steps

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.TypeSystem.Internal
import Boo.Lang.Compiler.Steps

import Boo.Lang.Environments

import UnityScript.Core
import UnityScript.Macros
import UnityScript.TypeSystem

class ProcessUnityScriptMethods(ProcessMethodBodiesWithDuckTyping):

	deferred IEnumerable_GetEnumerator = Types.IEnumerable.GetMethod("GetEnumerator");

	deferred IEnumerator_MoveNext = Types.IEnumerator.GetMethod("MoveNext");

	deferred IEnumerator_get_Current = Types.IEnumerator.GetProperty("Current").GetGetMethod();

	deferred _StartCoroutine = NameResolutionService.ResolveMethod(UnityScriptTypeSystem.ScriptBaseType, "StartCoroutine_Auto")

	deferred _UnityRuntimeServices_GetEnumerator = ResolveUnityRuntimeMethod("GetEnumerator")

	deferred _UnityRuntimeServices_Update = ResolveUnityRuntimeMethod("Update")

	deferred _UnityRuntimeServices_GetTypeOf = ResolveUnityRuntimeMethod("GetTypeOf")

	_implicit = false

	override def Initialize(context as CompilerContext):
		super(context)

		// don't transform
		//     foo == null
		// into:
		//     foo is null
		// but into:
		//     foo.Equals(null)
		self.OptimizeNullComparisons = false

	def ResolveUnityRuntimeMethod(name as string):
		return NameResolutionService.ResolveMethod(UnityRuntimeServicesType, name)

	def ResolveUnityRuntimeField(name as string):
		return NameResolutionService.ResolveField(UnityRuntimeServicesType, name)

	deferred UnityRuntimeServicesType = TypeSystemServices.Map(UnityScript.Lang.UnityRuntimeServices)

	UnityScriptTypeSystem as UnityScript.TypeSystem.UnityScriptTypeSystem:
		get: return self.TypeSystemServices

	UnityScriptParameters as UnityScript.UnityScriptCompilerParameters:
		get: return _context.Parameters

	override def GetGeneratorReturnType(generator as InternalMethod):
		return TypeSystemServices.IEnumeratorType

	override def IsDuckTyped(e as Expression):
		if Strict: return false
		return super(e)

	override def IsDuckTyped(member as IMember):
		if Strict: return false
		return super(member)

	override protected def MemberNotFound(node as MemberReferenceExpression, ns as INamespace):
		if (not Strict) and (UnityScriptParameters.Expando or super.IsDuckTyped(node.Target)):
			BindQuack(node);
			return
		super(node, ns)

	override protected def LocalToReuseFor(d as Declaration):
		if DeclarationAnnotations.ShouldForceNewVariableFor(d):
			AssertUniqueLocal(d)
			return null
		return super(d)

	override def OnModule(module as Module):
		downcastPermissions = my(UnityDowncastPermissions)

		preserving _activeModule, Parameters.Strict, _implicit, downcastPermissions.Enabled:
			_activeModule = module
			Parameters.Strict = Pragmas.IsEnabledOn(module, Pragmas.Strict)
			_implicit = Pragmas.IsEnabledOn(module, Pragmas.Implicit)
			downcastPermissions.Enabled = Pragmas.IsEnabledOn(module, Pragmas.Downcast)
			super(module)

	override def VisitMemberPreservingContext(node as TypeMember):
		downcastPermissions = my(UnityDowncastPermissions)

		module = node.EnclosingModule
		if module is _activeModule:
			super(node)
			return

		preserving _activeModule, Parameters.Strict, _implicit, downcastPermissions.Enabled:
			_activeModule = module
			Parameters.Strict = Pragmas.IsEnabledOn(module, Pragmas.Strict)
			_implicit = Pragmas.IsEnabledOn(module, Pragmas.Implicit)
			downcastPermissions.Enabled = Pragmas.IsEnabledOn(module, Pragmas.Downcast)
			super(node)

	_activeModule as Module

	Strict:
		get: return Parameters.Strict

	override def OnMethod(node as Method):
		super(node)
		CheckForEmptyCoroutine(node)
		return if Parameters.OutputType == CompilerOutputType.Library
		CheckEntryPoint(node)

	def CheckForEmptyCoroutine(node as Method):
		if not IsEmptyCoroutine(node):
			return
		node.Body.Add([| return $(EmptyEnumeratorReference) |])

	def IsEmptyCoroutine(node as Method):
		entity as InternalMethod = GetEntity(node)
		return entity.ReturnType is GetGeneratorReturnType(entity) and HasNeitherReturnNorYield(node)

	deferred EmptyEnumeratorReference = CodeBuilder.CreateMemberReference(ResolveUnityRuntimeField("EmptyEnumerator"))

	def CheckEntryPoint(node as Method):
		if not node.IsStatic: return
		if not node.IsPublic: return
		if node.Name != "Main": return
		if GetType(node.ReturnType) is not TypeSystemServices.VoidType: return

		ContextAnnotations.SetEntryPoint(_context, node)

	override def ProcessAutoLocalDeclaration(node as BinaryExpression, reference as ReferenceExpression):
		if (Strict and not _implicit) and not IsCompilerGenerated(reference):
			EmitUnknownIdentifierError(reference, reference.Name)
		else:
			super(node, reference)

	def IsCompilerGenerated(reference as ReferenceExpression):
		return reference.Name.Contains('$')

	override protected def ProcessBuiltinInvocation(node as MethodInvocationExpression, function as BuiltinFunction):
		if function is UnityScriptTypeSystem.UnityScriptEval:
			EvalAnnotation.Mark(_currentMethod.Method)
			BindExpressionType(node, TypeSystemServices.ObjectType)
			return
		if function is UnityScriptTypeSystem.UnityScriptTypeof:
			ProcessTypeofBuiltin(node);
			return
		super(node, function)

	private def ProcessTypeofBuiltin(node as MethodInvocationExpression):
		if node.Arguments.Count != 1:
			Error(node, CompilerError("UCE0001", node.Target.LexicalInfo, "'typeof' takes a single argument.", null))
			return

		type = node.Arguments[0].Entity as IType
		if type is not null:
			node.ParentNode.Replace(node, CodeBuilder.CreateTypeofExpression(type))
			return

		node.Target = CodeBuilder.CreateReference(_UnityRuntimeServices_GetTypeOf)
		BindExpressionType(node, TypeSystemServices.TypeType)

	override protected def ProcessMethodInvocation(node as MethodInvocationExpression, method as IMethod):
	"""
	Automatically detects coroutine invocations in assignments and as standalone
	expressions and generates StartCoroutine invocations.
	"""
		super(node, method)

		if not IsPossibleStartCoroutineInvocation(node):
			return

		if method.IsStatic: return

		tss = self.UnityScriptTypeSystem
		if not tss.IsScriptType(method.DeclaringType): return
		if not tss.IsGenerator(method): return

		parentNode = node.ParentNode
		parentNode.Replace(
			node,
			CodeBuilder.CreateMethodInvocation(
				TargetForStartCoroutineInvocation(node, method),
				_StartCoroutine,
				node))

	def TargetForStartCoroutineInvocation(node as MethodInvocationExpression, method as IMethod):
		target = cast(MemberReferenceExpression, node.Target).Target
		if target isa SuperLiteralExpression: // super becomes self for coroutine invocation
			return CodeBuilder.CreateSelfReference(target.LexicalInfo, method.DeclaringType)
		return target.CloneNode()

	override def ProcessStaticallyTypedAssignment(node as BinaryExpression):
		TryToResolveAmbiguousAssignment(node)
		ApplyImplicitArrayConversion(node)
		if ValidateAssignment(node):
			BindExpressionType(node, GetExpressionType(node.Right))
		else:
			Error(node)

	def ApplyImplicitArrayConversion(node as BinaryExpression):
		left = GetExpressionType(node.Left)
		if not left.IsArray: return

		right = GetExpressionType(node.Right)
		if right is not TypeSystemServices.Map(UnityScript.Lang.Array): return

		node.Right = CodeBuilder.CreateCast(left,
						CodeBuilder.CreateMethodInvocation(
							node.Right,
							ResolveMethod(right, "ToBuiltin"),
							CodeBuilder.CreateTypeofExpression(left.ElementType)))

	override def OnForStatement(node as ForStatement):
		assert 1 == len(node.Declarations)
		Visit(node.Iterator)
		if NeedsUpdateableIteration(node):
			ProcessUpdateableIteration(node)
		else:
			ProcessNormalIteration(node)

	def ProcessNormalIteration(node as ForStatement):
		node.Iterator = ProcessIterator(node.Iterator, node.Declarations)
		VisitForStatementBlock(node)

	def ProcessUpdateableIteration(node as ForStatement):
		newIterator = CodeBuilder.CreateMethodInvocation(_UnityRuntimeServices_GetEnumerator, node.Iterator)
		newIterator.LexicalInfo = LexicalInfo(node.Iterator.LexicalInfo)
		node.Iterator = newIterator
		ProcessDeclarationForIterator(node.Declarations[0], TypeSystemServices.ObjectType)
		VisitForStatementBlock(node)
		TransformIteration(node)

	def TransformIteration(node as ForStatement):
		iterator = CodeBuilder.DeclareLocal(
						_currentMethod.Method,
						_context.GetUniqueName("iterator"),
						TypeSystemServices.IEnumeratorType)
		iterator.IsUsed = true
		body = Block(node.LexicalInfo)
		body.Add(
			CodeBuilder.CreateAssignment(
				node.LexicalInfo,
				CodeBuilder.CreateReference(iterator),
				node.Iterator))

		// while __iterator.MoveNext():
		ws = WhileStatement(node.LexicalInfo)
		ws.Condition = CodeBuilder.CreateMethodInvocation(
						CodeBuilder.CreateReference(iterator),
						IEnumerator_MoveNext)

		current = CodeBuilder.CreateMethodInvocation(
							CodeBuilder.CreateReference(iterator),
							IEnumerator_get_Current)

		//	item = __iterator.Current
		loopVariable as InternalLocal = TypeSystemServices.GetEntity(node.Declarations[0])
		ws.Block.Add(
				CodeBuilder.CreateAssignment(
					node.LexicalInfo,
					CodeBuilder.CreateReference(loopVariable),
					current))
		ws.Block.Add(node.Block)

		LoopVariableUpdater(self, _context, iterator, loopVariable).Visit(node)

		body.Add(ws)
		node.ParentNode.Replace(node, body)

	def NeedsUpdateableIteration(node as ForStatement):
		iteratorType = GetExpressionType(node.Iterator)
		if iteratorType.IsArray: return false
		return true

	class LoopVariableUpdater(DepthFirstVisitor):

		_parent as ProcessUnityScriptMethods
		_context as CompilerContext
		_iteratorVariable as IEntity
		_loopVariable as IEntity
		_found as bool

		def constructor(parent as ProcessUnityScriptMethods, context as CompilerContext, iteratorVariable as IEntity, loopVariable as IEntity):
			_parent = parent
			_context = context
			_iteratorVariable = iteratorVariable
			_loopVariable = loopVariable

		override def OnExpressionStatement(node as ExpressionStatement):
			_found = false
			Visit(node.Expression)
			if not _found: return

			parentNode = node.ParentNode

			codeBuilder = _context.CodeBuilder
			block = Block(node.LexicalInfo)
			block.Add(node)
			block.Add(
				codeBuilder.CreateMethodInvocation(
					_parent._UnityRuntimeServices_Update,
					codeBuilder.CreateReference(_iteratorVariable),
					codeBuilder.CreateReference(_loopVariable)))

			parentNode.Replace(node, block)

		override def OnReferenceExpression(node as ReferenceExpression):
			if _found: return

			referent = node.Entity
			_found = referent is _loopVariable

namespace UnityScript.Steps

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.TypeSystem.Internal
import Boo.Lang.Compiler.Steps

import Boo.Lang.Environments

import UnityScript.Core
import UnityScript.Macros
import UnityScript.TypeSystem

class ProcessUnityScriptMethods(ProcessMethodBodiesWithDuckTyping):

	deferred IEnumerable_GetEnumerator = Types.IEnumerable.GetMethod("GetEnumerator");

	deferred IEnumerator_MoveNext = Types.IEnumerator.GetMethod("MoveNext");

	deferred IEnumerator_get_Current = Types.IEnumerator.GetProperty("Current").GetGetMethod();

	deferred _StartCoroutine = NameResolutionService.ResolveMethod(UnityScriptTypeSystem.ScriptBaseType, "StartCoroutine_Auto")

	deferred _UnityRuntimeServices_GetEnumerator = ResolveUnityRuntimeMethod("GetEnumerator")

	deferred _UnityRuntimeServices_Update = ResolveUnityRuntimeMethod("Update")

	deferred _UnityRuntimeServices_GetTypeOf = ResolveUnityRuntimeMethod("GetTypeOf")

	_implicit = false

	override def Initialize(context as CompilerContext):
		super(context)

		// don't transform
		//     foo == null
		// into:
		//     foo is null
		// but into:
		//     foo.Equals(null)
		self.OptimizeNullComparisons = false

	def ResolveUnityRuntimeMethod(name as string):
		return NameResolutionService.ResolveMethod(UnityRuntimeServicesType, name)

	def ResolveUnityRuntimeField(name as string):
		return NameResolutionService.ResolveField(UnityRuntimeServicesType, name)

	deferred UnityRuntimeServicesType = TypeSystemServices.Map(UnityScript.Lang.UnityRuntimeServices)

	UnityScriptTypeSystem as UnityScript.TypeSystem.UnityScriptTypeSystem:
		get: return self.TypeSystemServices

	UnityScriptParameters as UnityScript.UnityScriptCompilerParameters:
		get: return _context.Parameters

	override def GetGeneratorReturnType(generator as InternalMethod):
		return TypeSystemServices.IEnumeratorType

	override def IsDuckTyped(e as Expression):
		if Strict: return false
		return super(e)

	override def IsDuckTyped(member as IMember):
		if Strict: return false
		return super(member)

	override protected def MemberNotFound(node as MemberReferenceExpression, ns as INamespace):
		if (not Strict) and (UnityScriptParameters.Expando or super.IsDuckTyped(node.Target)):
			BindQuack(node);
			return
		super(node, ns)

	override protected def LocalToReuseFor(d as Declaration):
		if DeclarationAnnotations.ShouldForceNewVariableFor(d):
			AssertUniqueLocal(d)
			return null
		return super(d)

	override def OnModule(module as Module):
		downcastPermissions = my(UnityDowncastPermissions)

		preserving _activeModule, Parameters.Strict, _implicit, downcastPermissions.Enabled:
			_activeModule = module
			Parameters.Strict = Pragmas.IsEnabledOn(module, Pragmas.Strict)
			_implicit = Pragmas.IsEnabledOn(module, Pragmas.Implicit)
			downcastPermissions.Enabled = Pragmas.IsEnabledOn(module, Pragmas.Downcast)
			super(module)

	override def VisitMemberPreservingContext(node as TypeMember):
		downcastPermissions = my(UnityDowncastPermissions)

		module = node.EnclosingModule
		if module is _activeModule:
			super(node)
			return

		preserving _activeModule, Parameters.Strict, _implicit, downcastPermissions.Enabled:
			_activeModule = module
			Parameters.Strict = Pragmas.IsEnabledOn(module, Pragmas.Strict)
			_implicit = Pragmas.IsEnabledOn(module, Pragmas.Implicit)
			downcastPermissions.Enabled = Pragmas.IsEnabledOn(module, Pragmas.Downcast)
			super(node)

	_activeModule as Module

	Strict:
		get: return Parameters.Strict

	override def OnMethod(node as Method):
		super(node)
		CheckForEmptyCoroutine(node)
		return if Parameters.OutputType == CompilerOutputType.Library
		CheckEntryPoint(node)

	def CheckForEmptyCoroutine(node as Method):
		if not IsEmptyCoroutine(node):
			return
		node.Body.Add([| return $(EmptyEnumeratorReference) |])

	def IsEmptyCoroutine(node as Method):
		entity as InternalMethod = GetEntity(node)
		return entity.ReturnType is GetGeneratorReturnType(entity) and HasNeitherReturnNorYield(node)

	deferred EmptyEnumeratorReference = CodeBuilder.CreateMemberReference(ResolveUnityRuntimeField("EmptyEnumerator"))

	def CheckEntryPoint(node as Method):
		if not node.IsStatic: return
		if not node.IsPublic: return
		if node.Name != "Main": return
		if GetType(node.ReturnType) is not TypeSystemServices.VoidType: return

		ContextAnnotations.SetEntryPoint(_context, node)

	override def ProcessAutoLocalDeclaration(node as BinaryExpression, reference as ReferenceExpression):
		if (Strict and not _implicit) and not IsCompilerGenerated(reference):
			EmitUnknownIdentifierError(reference, reference.Name)
		else:
			super(node, reference)

	def IsCompilerGenerated(reference as ReferenceExpression):
		return reference.Name.Contains('$')

	override protected def ProcessBuiltinInvocation(function as BuiltinFunction, node as MethodInvocationExpression):
		if function is UnityScriptTypeSystem.UnityScriptEval:
			EvalAnnotation.Mark(_currentMethod.Method)
			BindExpressionType(node, TypeSystemServices.ObjectType)
			return
		if function is UnityScriptTypeSystem.UnityScriptTypeof:
			ProcessTypeofBuiltin(node);
			return
		super(function, node)

	private def ProcessTypeofBuiltin(node as MethodInvocationExpression):
		if node.Arguments.Count != 1:
			Error(node, CompilerError("UCE0001", node.Target.LexicalInfo, "'typeof' takes a single argument.", null))
			return

		type = node.Arguments[0].Entity as IType
		if type is not null:
			node.ParentNode.Replace(node, CodeBuilder.CreateTypeofExpression(type))
			return

		node.Target = CodeBuilder.CreateReference(_UnityRuntimeServices_GetTypeOf)
		BindExpressionType(node, TypeSystemServices.TypeType)

	override protected def ProcessMethodInvocation(node as MethodInvocationExpression, targetEntity as IEntity):
	"""
	Automatically detects coroutine invocations in assignments and as standalone
	expressions and generates StartCoroutine invocations.
	"""
		super(node, targetEntity)

		if not IsPossibleStartCoroutineInvocation(node):
			return

		method as IMethod = targetEntity
		if method is null or method.IsStatic: return

		tss = self.UnityScriptTypeSystem
		if not tss.IsScriptType(method.DeclaringType): return
		if not tss.IsGenerator(method): return

		parentNode = node.ParentNode
		parentNode.Replace(
			node,
			CodeBuilder.CreateMethodInvocation(
				TargetForStartCoroutineInvocation(node, method),
				_StartCoroutine,
				node))

	def TargetForStartCoroutineInvocation(node as MethodInvocationExpression, method as IMethod):
		target = cast(MemberReferenceExpression, node.Target).Target
		if target isa SuperLiteralExpression: // super becomes self for coroutine invocation
			return CodeBuilder.CreateSelfReference(target.LexicalInfo, method.DeclaringType)
		return target.CloneNode()

	override def ProcessStaticallyTypedAssignment(node as BinaryExpression):
		TryToResolveAmbiguousAssignment(node)
		ApplyImplicitArrayConversion(node)
		if ValidateAssignment(node):
			BindExpressionType(node, GetExpressionType(node.Right))
		else:
			Error(node)

	def ApplyImplicitArrayConversion(node as BinaryExpression):
		left = GetExpressionType(node.Left)
		if not left.IsArray: return

		right = GetExpressionType(node.Right)
		if right is not TypeSystemServices.Map(UnityScript.Lang.Array): return

		node.Right = CodeBuilder.CreateCast(left,
						CodeBuilder.CreateMethodInvocation(
							node.Right,
							ResolveMethod(right, "ToBuiltin"),
							CodeBuilder.CreateTypeofExpression(left.ElementType)))

	override def OnForStatement(node as ForStatement):
		assert 1 == len(node.Declarations)
		Visit(node.Iterator)
		if NeedsUpdateableIteration(node):
			ProcessUpdateableIteration(node)
		else:
			ProcessNormalIteration(node)

	def ProcessNormalIteration(node as ForStatement):
		node.Iterator = ProcessIterator(node.Iterator, node.Declarations)
		VisitForStatementBlock(node)

	def ProcessUpdateableIteration(node as ForStatement):
		newIterator = CodeBuilder.CreateMethodInvocation(_UnityRuntimeServices_GetEnumerator, node.Iterator)
		newIterator.LexicalInfo = LexicalInfo(node.Iterator.LexicalInfo)
		node.Iterator = newIterator
		ProcessDeclarationForIterator(node.Declarations[0], TypeSystemServices.ObjectType)
		VisitForStatementBlock(node)
		TransformIteration(node)

	def TransformIteration(node as ForStatement):
		iterator = CodeBuilder.DeclareLocal(
						_currentMethod.Method,
						_context.GetUniqueName("iterator"),
						TypeSystemServices.IEnumeratorType)
		iterator.IsUsed = true
		body = Block(node.LexicalInfo)
		body.Add(
			CodeBuilder.CreateAssignment(
				node.LexicalInfo,
				CodeBuilder.CreateReference(iterator),
				node.Iterator))

		// while __iterator.MoveNext():
		ws = WhileStatement(node.LexicalInfo)
		ws.Condition = CodeBuilder.CreateMethodInvocation(
						CodeBuilder.CreateReference(iterator),
						IEnumerator_MoveNext)

		current = CodeBuilder.CreateMethodInvocation(
							CodeBuilder.CreateReference(iterator),
							IEnumerator_get_Current)

		//	item = __iterator.Current
		loopVariable as InternalLocal = TypeSystemServices.GetEntity(node.Declarations[0])
		ws.Block.Add(
				CodeBuilder.CreateAssignment(
					node.LexicalInfo,
					CodeBuilder.CreateReference(loopVariable),
					current))
		ws.Block.Add(node.Block)

		LoopVariableUpdater(self, _context, iterator, loopVariable).Visit(node)

		body.Add(ws)
		node.ParentNode.Replace(node, body)

	def NeedsUpdateableIteration(node as ForStatement):
		iteratorType = GetExpressionType(node.Iterator)
		if iteratorType.IsArray: return false
		return true

	class LoopVariableUpdater(DepthFirstVisitor):

		_parent as ProcessUnityScriptMethods
		_context as CompilerContext
		_iteratorVariable as IEntity
		_loopVariable as IEntity
		_found as bool

		def constructor(parent as ProcessUnityScriptMethods, context as CompilerContext, iteratorVariable as IEntity, loopVariable as IEntity):
			_parent = parent
			_context = context
			_iteratorVariable = iteratorVariable
			_loopVariable = loopVariable

		override def OnExpressionStatement(node as ExpressionStatement):
			_found = false
			Visit(node.Expression)
			if not _found: return

			parentNode = node.ParentNode

			codeBuilder = _context.CodeBuilder
			block = Block(node.LexicalInfo)
			block.Add(node)
			block.Add(
				codeBuilder.CreateMethodInvocation(
					_parent._UnityRuntimeServices_Update,
					codeBuilder.CreateReference(_iteratorVariable),
					codeBuilder.CreateReference(_loopVariable)))

			parentNode.Replace(node, block)

		override def OnReferenceExpression(node as ReferenceExpression):
			if _found: return

			referent = node.Entity
			_found = referent is _loopVariable


remove unused method

remove unused method

namespace UnityScript.TypeSystem

import Boo.Lang.Compiler.TypeSystem

class UnityScriptTypeSystem(TypeSystemServices):

	public static final UnityScriptEval = BuiltinFunction("eval", BuiltinFunctionType.Custom)

	public static final UnityScriptTypeof = BuiltinFunction("typeof", BuiltinFunctionType.Custom)

	[getter(ScriptBaseType)]
	_ScriptBaseType as IType
	_AbstractGenerator as IType

	def constructor():
		self._ScriptBaseType = Map(UnityScriptParameters.ScriptBaseType)
		self._AbstractGenerator = Map(Boo.Lang.AbstractGenerator)

	UnityScriptParameters as UnityScript.UnityScriptCompilerParameters:
		get: return self.Context.Parameters

	def IsScriptType(type as IType):
		return type.IsSubclassOf(_ScriptBaseType)

	def IsGenerator(method as IMethod):
		rt = method.ReturnType
		if rt is IEnumeratorType: return true
		// for backwards compatibility
		return rt.IsSubclassOf(self._AbstractGenerator)

	override def CanBeReachedByPromotion(expected as IType, actual as IType):
		result = super(expected, actual)
		if result: return true
		if expected.IsEnum: return IsIntegerNumber(actual)
		if actual.IsEnum: return IsIntegerNumber(expected)
		return false

	override protected def PreparePrimitives():
		AddPrimitiveType("void", VoidType)
		AddPrimitiveType("boolean", BoolType)
		AddPrimitiveType("char", CharType)
		AddPrimitiveType("Date", DateTimeType)
		AddPrimitiveType("String", StringType)
		AddPrimitiveType("Object", ObjectType)
		AddPrimitiveType("Regex", RegexType)
		AddPrimitiveType("sbyte", SByteType)
		AddPrimitiveType("byte", ByteType)
		AddPrimitiveType("short", ShortType)
		AddPrimitiveType("ushort", UShortType)
		AddPrimitiveType("int", IntType)
		AddPrimitiveType("uint", UIntType)
		AddPrimitiveType("long", LongType)
		AddPrimitiveType("ulong", ULongType)
		AddPrimitiveType("Number", DoubleType)
		AddPrimitiveType("float", SingleType)
		AddPrimitiveType("double", DoubleType)
		AddPrimitiveType("Function", ICallableType)
		AddPrimitiveType("Array", Map(UnityScript.Lang.Array))

	override def PrepareBuiltinFunctions():
		super()
		AddBuiltin(UnityScriptEval)
		AddBuiltin(UnityScriptTypeof)

namespace UnityScript.TypeSystem

import Boo.Lang.Compiler.TypeSystem

class UnityScriptTypeSystem(TypeSystemServices):

	public static final UnityScriptEval = BuiltinFunction("eval", BuiltinFunctionType.Custom)

	public static final UnityScriptTypeof = BuiltinFunction("typeof", BuiltinFunctionType.Custom)

	[getter(ScriptBaseType)]
	_ScriptBaseType as IType
	_AbstractGenerator as IType

	def constructor():
		self._ScriptBaseType = Map(UnityScriptParameters.ScriptBaseType)
		self._AbstractGenerator = Map(Boo.Lang.AbstractGenerator)

	UnityScriptParameters as UnityScript.UnityScriptCompilerParameters:
		get: return self.Context.Parameters

	def IsScriptType(type as IType):
		return type.IsSubclassOf(_ScriptBaseType)

	def IsGenerator(method as IMethod):
		rt = method.ReturnType
		if rt is IEnumeratorType: return true

		// for backwards compatibility
		return rt.IsSubclassOf(self._AbstractGenerator)

	override def IsModule(type as System.Type):
		return false

	override def CanBeReachedByPromotion(expected as IType, actual as IType):
		result = super(expected, actual)
		if result: return true
		if expected.IsEnum: return IsIntegerNumber(actual)
		if actual.IsEnum: return IsIntegerNumber(expected)
		return false

	override protected def PreparePrimitives():
		AddPrimitiveType("void", VoidType)
		AddPrimitiveType("boolean", BoolType)
		AddPrimitiveType("char", CharType)
		AddPrimitiveType("Date", DateTimeType)
		AddPrimitiveType("String", StringType)
		AddPrimitiveType("Object", ObjectType)
		AddPrimitiveType("Regex", RegexType)
		AddPrimitiveType("sbyte", SByteType)
		AddPrimitiveType("byte", ByteType)
		AddPrimitiveType("short", ShortType)
		AddPrimitiveType("ushort", UShortType)
		AddPrimitiveType("int", IntType)
		AddPrimitiveType("uint", UIntType)
		AddPrimitiveType("long", LongType)
		AddPrimitiveType("ulong", ULongType)
		AddPrimitiveType("Number", DoubleType)
		AddPrimitiveType("float", SingleType)
		AddPrimitiveType("double", DoubleType)
		AddPrimitiveType("Function", ICallableType)
		AddPrimitiveType("Array", Map(UnityScript.Lang.Array))

	override def PrepareBuiltinFunctions():
		super()
		AddBuiltin(UnityScriptEval)
		AddBuiltin(UnityScriptTypeof)


Refine display of completion results.

Refine display of completion results.

namespace UnityScript.MonoDevelop.Completion

import System
import System.Collections.Generic

import UnityScript
import UnityScript.MonoDevelop
import UnityScript.MonoDevelop.ProjectModel

import MonoDevelop.Core
import MonoDevelop.Projects
import MonoDevelop.Projects.Dom.Parser
import MonoDevelop.Ide.Gui
import MonoDevelop.Ide.Gui.Content
import MonoDevelop.Ide.CodeCompletion

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Steps
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.IO
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.PatternMatching

class UnityScriptEditorCompletion(CompletionTextEditorExtension):

	_dom as ProjectDom
	_resolver as UnityScriptTypeResolver
	_project as DotNetProject

	override def Initialize():
		super()
		_dom = ProjectDomService.GetProjectDom(Document.Project) or ProjectDomService.GetFileDom(Document.FileName)
		InstallUnityScriptSyntaxModeIfNeeded()
		_resolver = UnityScriptTypeResolver()
		_project = Document.Project as DotNetProject
		InitializeProjectReferences()

	def InitializeProjectReferences():
		if _project is null:
			return

		for reference in _project.References:
			if ReferenceType.Project != reference.ReferenceType:
				_resolver.AddReference(reference.Reference)

	def InstallUnityScriptSyntaxModeIfNeeded():
		view = Document.GetContent[of MonoDevelop.SourceEditor.SourceEditorView]()
		return if view is null

		mimeType = UnityScriptParser.MimeType
		return if view.Document.SyntaxMode.MimeType == mimeType

		mode = Mono.TextEditor.Highlighting.SyntaxModeService.GetSyntaxMode(mimeType)
		if mode is not null:
			view.Document.SyntaxMode = mode
		else:
			LoggingService.LogWarning(GetType() + " could not get SyntaxMode for mimetype '" + mimeType + "'.")

	override def ExtendsEditor(doc as MonoDevelop.Ide.Gui.Document, editor as IEditableTextBuffer):
		return IsUnityScriptFile(doc.Name)

	override def HandleCodeCompletion(context as CodeCompletionContext, completionChar as char):
#		print "HandleCodeCompletion(${context.ToString()}, ${completionChar.ToString()})"

		match completionChar.ToString():
			case ' ':
				lineText = GetLineText(context.TriggerLine).TrimStart()
				if not lineText.StartsWith("import "):
					return null

				return ImportCompletionDataFor('')

			case '.':
				lineText = GetLineText(context.TriggerLine)
				lineLength = lineText.Length
				lineText = lineText.TrimStart()
				trimmedLength = lineLength - lineText.Length
				if lineText.StartsWith("import "):
					nameSpace = lineText[len("import "):context.TriggerLineOffset-(2+trimmedLength)].Trim()
					return ImportCompletionDataFor(nameSpace)

				result = null as CompletionDataList
				text = string.Format ("{0}{1} {2}", Document.TextEditor.GetText (0, context.TriggerOffset),
				                                    CompletionFinder.CompletionToken,
				                                    Document.TextEditor.GetText (context.TriggerOffset, Document.TextEditor.TextLength))
				# print text
				_resolver.Input.Clear()
				_resolver.Input.Add(StringInput("completion text", text))

				result = CompletionDataList()

				_resolver.ResolveAnd() do (type as IType):
					resultHash = Dictionary[of string,string]()
					for member in type.GetMembers():
						# print member
						resultHash[SanitizeMemberName(type,member)] = GetIconForMember(member)
					for pair in resultHash:
						unless string.IsNullOrEmpty(pair.Key) or (4 < pair.Key.Length and /^[gs]et_/.Matches(pair.Key) and resultHash.ContainsKey(pair.Key[4:])):
							result.Add(pair.Key, pair.Value)

				return result

			otherwise:
				return null

	def ImportCompletionDataFor(nameSpace as string):
#		print "ImportCompletionDataFor(${nameSpace})"

		result = CompletionDataList()
		for member in _dom.GetNamespaceContents(nameSpace, true, true):
			result.Add(member.Name, member.StockIcon)
		return result

	def GetLineText(line as int):
		return Document.TextEditor.GetLineText(line)

	# <summary>
	# Gets the proper stock icon for an IEntity
	# </summary>
	# <param name="member">The member whose icon is wanted</param>
	# <returns>A stock icon string</returns>
	def GetIconForMember(member as IEntity):
		match member.EntityType:
			case EntityType.BuiltinFunction:
				return Stock.Method
			case EntityType.Constructor:
				return Stock.Method
			case EntityType.Method:
				return Stock.Method
			case EntityType.Local:
				return Stock.Field
			case EntityType.Field:
				return Stock.Field
			case EntityType.Property:
				return Stock.Property
			case EntityType.Event:
				return Stock.Event
			otherwise:
				return Stock.Literal

	# <summary>
	# Sanitizes the member names we get from the compiler pipeline
	# </summary>
	# <param name="type">The type to which the member belongs</param>
	# <param name="member">The member whose name should be sanitized</param>
	# <returns>The sanitized name (empty for invalid)</returns>
	def SanitizeMemberName(type as IType,member as IEntity) as string:
		name = member.Name
		if (0 <= (lastDot = name.LastIndexOf('.'))):
			name = name[lastDot:]
		if ("constructor" == name):
			name = type.Name
		if (name.StartsWith("internal_", StringComparison.OrdinalIgnoreCase)):
			name = string.Empty
		return name

namespace UnityScript.MonoDevelop.Completion

import System.Collections.Generic

import UnityScript
import UnityScript.MonoDevelop
import UnityScript.MonoDevelop.ProjectModel

import MonoDevelop.Core
import MonoDevelop.Projects
import MonoDevelop.Projects.Dom.Parser
import MonoDevelop.Ide.Gui
import MonoDevelop.Ide.Gui.Content
import MonoDevelop.Ide.CodeCompletion

import Boo.Lang.Compiler
import Boo.Lang.Compiler.Steps
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.IO
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.PatternMatching

class UnityScriptEditorCompletion(CompletionTextEditorExtension):

	_dom as ProjectDom
	_resolver as UnityScriptTypeResolver
	_project as DotNetProject

	override def Initialize():
		super()
		_dom = ProjectDomService.GetProjectDom(Document.Project) or ProjectDomService.GetFileDom(Document.FileName)
		InstallUnityScriptSyntaxModeIfNeeded()
		_resolver = UnityScriptTypeResolver()
		_project = Document.Project as DotNetProject
		InitializeProjectReferences()

	def InitializeProjectReferences():
		if _project is null:
			return

		for reference in _project.References:
			if ReferenceType.Project != reference.ReferenceType:
				_resolver.AddReference(reference.Reference)

	def InstallUnityScriptSyntaxModeIfNeeded():
		view = Document.GetContent[of MonoDevelop.SourceEditor.SourceEditorView]()
		return if view is null

		mimeType = UnityScriptParser.MimeType
		return if view.Document.SyntaxMode.MimeType == mimeType

		mode = Mono.TextEditor.Highlighting.SyntaxModeService.GetSyntaxMode(mimeType)
		if mode is not null:
			view.Document.SyntaxMode = mode
		else:
			LoggingService.LogWarning(GetType() + " could not get SyntaxMode for mimetype '" + mimeType + "'.")

	override def ExtendsEditor(doc as MonoDevelop.Ide.Gui.Document, editor as IEditableTextBuffer):
		return IsUnityScriptFile(doc.Name)

	override def HandleCodeCompletion(context as CodeCompletionContext, completionChar as char):
#		print "HandleCodeCompletion(${context.ToString()}, ${completionChar.ToString()})"

		match completionChar.ToString():
			case ' ':
				lineText = GetLineText(context.TriggerLine).TrimStart()
				if not lineText.StartsWith("import "):
					return null

				return ImportCompletionDataFor('')

			case '.':
				lineText = GetLineText(context.TriggerLine)
				lineLength = lineText.Length
				lineText = lineText.TrimStart()
				trimmedLength = lineLength - lineText.Length
				if lineText.StartsWith("import "):
					nameSpace = lineText[len("import "):context.TriggerLineOffset-(2+trimmedLength)].Trim()
					return ImportCompletionDataFor(nameSpace)

				result = null as CompletionDataList
				text = string.Format ("{0}{1} {2}", Document.TextEditor.GetText (0, context.TriggerOffset),
				                                    CompletionFinder.CompletionToken,
				                                    Document.TextEditor.GetText (context.TriggerOffset, Document.TextEditor.TextLength))
				# print text
				_resolver.Input.Clear()
				_resolver.Input.Add(StringInput("completion text", text))

				result = CompletionDataList()

				_resolver.ResolveAnd() do (type as IType):
					resultHash = Dictionary[of string,string]()
					for member in type.GetMembers():
						# print member
						resultHash[member.Name] = GetIconForMember(member)
					for pair in resultHash:
						result.Add(pair.Key, pair.Value)

				return result

			otherwise:
				return null

	def ImportCompletionDataFor(nameSpace as string):
#		print "ImportCompletionDataFor(${nameSpace})"

		result = CompletionDataList()
		for member in _dom.GetNamespaceContents(nameSpace, true, true):
			result.Add(member.Name, member.StockIcon)
		return result

	def GetLineText(line as int):
		return Document.TextEditor.GetLineText(line)

	def GetIconForMember(member as IEntity):
		match member.EntityType:
			case EntityType.BuiltinFunction:
				return Stock.Method
			case EntityType.Constructor:
				return Stock.Method
			case EntityType.Method:
				return Stock.Method
			case EntityType.Local:
				return Stock.Field
			case EntityType.Field:
				return Stock.Field
			case EntityType.Property:
				return Stock.Property
			case EntityType.Event:
				return Stock.Event
			otherwise:
				return Stock.Literal


Convert build.boo to UTF-8

Convert build.boo to UTF-8

include "build_support.boo"

solution = "MarkEmbling.PostcodesIO.sln"
configuration = "release"
test_assembly = "MarkEmbling.PostcodesIO.Tests/bin/${configuration}/MarkEmbling.PostcodesIO.Tests.dll"
bin_path = "build/bin"

target default, (compile, test, prep):
  pass

desc "Compiles the solution"
target compile:
  msbuild(file: solution, configuration: configuration, version: "4.0")

desc "Executes the tests"
target test, (compile):
  with nunit(assembly: test_assembly, toolPath: "packages/NUnit.Runners.2.6.4/tools/nunit-console.exe")

desc "Copies the binaries to the 'build/bin' directory"
target prep, (compile, test):
  rmdir(bin_path)

  with FileList("MarkEmbling.PostcodesIO/bin/${configuration}"):
    .Include("*.{dll,exe,config,nupkg}")
    .ForEach def(file):
      file.CopyToDirectory(bin_path)

desc "Publishes the NuGet packages"
target publish, (prep):
  api_key = read_nuget_api_key()

  with FileList(bin_path):
    .Include("*.nupkg")
    .ForEach def(file):
      filename = Path.GetFileName(file.FullName)
      if prompt("Publish ${filename}...?"):
        with nuget_push():
          .toolPath =  ".nuget/NuGet.exe"
          .packagePath = file.FullName
          .apiKey = api_key


taking out test variable

taking out test variable

import UnityEngine
import Area

class City (MonoBehaviour):
	private turn as int = 0
	private maxturns = 4
	public orcamento as (single)
	public MusicName as string
	private caixa as single
	private areas as (Area)
	private city as City
	public gotoending = false

	def Start ():
		areas = GameObject.FindObjectsOfType(Area)
		t = turn/2
		caixa = orcamento[t]/2
		generateRandomPlayers()

	def Update ():
		//pass
		if gotoending:
			newTurn()

	def getAreas():
		return areas

	def getOrcamento() as single:
		gasto = 0
		for a in areas:
			gasto += a.getInvestimentoCultura()
			gasto += a.getInvestimentoEducacao()
			gasto += a.getInvestimentoEsporte()
			gasto += a.getInvestimentoInfraestrutura()
			gasto += a.getInvestimentoMeioAmbiente()
			gasto += a.getInvestimentoMobilidade()
			gasto += a.getInvestimentoAgropecuaria()
			gasto += a.getInvestimentoSaude()
			gasto += a.getInvestimentoTrabalho()
			gasto += a.getInvestimentoSeguranca()
		return caixa - gasto

	public def getCaixa() as single:
		return caixa

	def newTurn():
		turn++
		if turn >= maxturns:
			gotoending = false
			(GameObject.FindObjectOfType(EndChosen) as EndChosen).setEnding()
			return
		t = turn/2
		caixa = orcamento[t]/2
		generateRandomPlayers()
		(GameObject.FindObjectOfType(ButtonHistorico) as ButtonHistorico).activate()
		for a in areas:
			a.setSelected(false)

	def getTurn():
		return turn

	def getCaixaAtTurn(turnnum as int):
		if (turnnum < 0):
			turnnum = turn + 1 + turnnum
		t = turnnum/2
		return orcamento[t]/2

	public def getCaixaAllTurns():
		total = 0.0F
		for i in range(turn):
			total += getCaixaAtTurn(i)
		return total

	public def getMusicName():
		return MusicName

	def GenerateRandomValues(start as single,end as single,length as int) as (single):
		targets as (single) = array(single,length)

		for i in range(length):
			targets[i] = Random.Range(start, end)
		return targets

	def generateRandomPlayers():
		playervals = []
		for i in range(7):
			randomnums = GenerateRandomValues(0,caixa,len(areas)*10)
			sum as single = 0.0F
			for j in range(len(areas)*10):
				sum += randomnums[j]
			factor = (caixa/sum)*0.50 // bots invest 50% less
			for j in randomnums:
				j = j*factor
			playervals.Add(randomnums)

		for a in range(len(areas)):
			playerlist = array(Player,8)
			playerlist[0] = Player()
			playerlist[0].InvestimentoCultura = 0
			playerlist[0].InvestimentoEducacao = 0
			playerlist[0].InvestimentoEsporte = 0
			playerlist[0].InvestimentoInfraestrutura = 0
			playerlist[0].InvestimentoMeioAmbiente = 0
			playerlist[0].InvestimentoMobilidade = 0
			playerlist[0].InvestimentoAgropecuaria = 0
			playerlist[0].InvestimentoSaude = 0
			playerlist[0].InvestimentoTrabalho = 0
			playerlist[0].InvestimentoSeguranca = 0
			for p in range(1,8):
				playerlist[p] = Player()
				playerlist[p].InvestimentoCultura = (playervals[p-1] as (single))[0+a*10]
				playerlist[p].InvestimentoEducacao = (playervals[p-1] as (single))[1+a*10]
				playerlist[p].InvestimentoEsporte = (playervals[p-1] as (single))[2+a*10]
				playerlist[p].InvestimentoInfraestrutura = (playervals[p-1] as (single))[3+a*10]
				playerlist[p].InvestimentoMeioAmbiente = (playervals[p-1] as (single))[4+a*10]
				playerlist[p].InvestimentoMobilidade = (playervals[p-1] as (single))[5+a*10]
				playerlist[p].InvestimentoAgropecuaria = (playervals[p-1] as (single))[6+a*10]
				playerlist[p].InvestimentoSaude = (playervals[p-1] as (single))[7+a*10]
				playerlist[p].InvestimentoTrabalho = (playervals[p-1] as (single))[8+a*10]
				playerlist[p].InvestimentoSeguranca = (playervals[p-1] as (single))[9+a*10]
			areas[a].AddPlayers(playerlist)

	public def getInvestimentoCulturaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoCulturaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoEducacaoPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoEducacaoPlayer(playernum,turnnum)
		return total

	public def getInvestimentoEsportePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoEsportePlayer(playernum,turnnum)
		return total

	public def getInvestimentoInfraestruturaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoInfraestruturaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoMeioAmbientePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoMeioAmbientePlayer(playernum,turnnum)
		return total

	public def getInvestimentoMobilidadePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoMobilidadePlayer(playernum,turnnum)
		return total

	public def getInvestimentoAgropecuariaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoAgropecuariaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoSaudePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoSaudePlayer(playernum,turnnum)
		return total

	public def getInvestimentoTrabalhoPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoTrabalhoPlayer(playernum,turnnum)
		return total

	public def getInvestimentoSegurancaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoSegurancaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoDisponivelPlayer(playernum,turnnum as int) as single:
		gasto = 0.0F
		for a in areas:
			gasto += a.getInvestimentoCulturaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoEducacaoPlayer(playernum,turnnum)
			gasto += a.getInvestimentoEsportePlayer(playernum,turnnum)
			gasto += a.getInvestimentoInfraestruturaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoMeioAmbientePlayer(playernum,turnnum)
			gasto += a.getInvestimentoMobilidadePlayer(playernum,turnnum)
			gasto += a.getInvestimentoAgropecuariaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoSaudePlayer(playernum,turnnum)
			gasto += a.getInvestimentoTrabalhoPlayer(playernum,turnnum)
			gasto += a.getInvestimentoSegurancaPlayer(playernum,turnnum)
		return getCaixaAtTurn(turnnum)-gasto

	public def getInvestimentoCulturaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoCulturaPlayer(i,turnnum)
		return total

	public def getInvestimentoEducacaoTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoEducacaoPlayer(i,turnnum)
		return total

	public def getInvestimentoEsporteTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoEsportePlayer(i,turnnum)
		return total

	public def getInvestimentoInfraestruturaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoInfraestruturaPlayer(i,turnnum)
		return total

	public def getInvestimentoMeioAmbienteTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoMeioAmbientePlayer(i,turnnum)
		return total

	public def getInvestimentoMobilidadeTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoMobilidadePlayer(i,turnnum)
		return total

	public def getInvestimentoAgropecuariaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoAgropecuariaPlayer(i,turnnum)
		return total

	public def getInvestimentoSaudeTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoSaudePlayer(i,turnnum)
		return total

	public def getInvestimentoTrabalhoTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoTrabalhoPlayer(i,turnnum)
		return total

	public def getInvestimentoSegurancaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoSegurancaPlayer(i,turnnum)
		return total

	public def getInvestimentoDisponivelTotal(turnnum as int) as single:
		gasto = 0.0F
		gasto += getInvestimentoCulturaTotal(turnnum)
		gasto += getInvestimentoEducacaoTotal(turnnum)
		gasto += getInvestimentoEsporteTotal(turnnum)
		gasto += getInvestimentoInfraestruturaTotal(turnnum)
		gasto += getInvestimentoMeioAmbienteTotal(turnnum)
		gasto += getInvestimentoMobilidadeTotal(turnnum)
		gasto += getInvestimentoAgropecuariaTotal(turnnum)
		gasto += getInvestimentoSaudeTotal(turnnum)
		gasto += getInvestimentoTrabalhoTotal(turnnum)
		gasto += getInvestimentoSegurancaTotal(turnnum)
		return getCaixaAtTurn(turnnum)*8-gasto

	public def getInvestimentoCulturaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoCulturaTotal(i)
		return total

	public def getInvestimentoEducacaoAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoEducacaoTotal(i)
		return total

	public def getInvestimentoEsporteAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoEsporteTotal(i)
		return total

	public def getInvestimentoInfraestruturaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoInfraestruturaTotal(i)
		return total

	public def getInvestimentoMeioAmbienteAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoMeioAmbienteTotal(i)
		return total

	public def getInvestimentoMobilidadeAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoMobilidadeTotal(i)
		return total

	public def getInvestimentoAgropecuariaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoAgropecuariaTotal(i)
		return total

	public def getInvestimentoSaudeAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoSaudeTotal(i)
		return total

	public def getInvestimentoTrabalhoAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoTrabalhoTotal(i)
		return total

	public def getInvestimentoSegurancaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoSegurancaTotal(i)
		return total

import UnityEngine
import Area

class City (MonoBehaviour):
	private turn as int = 0
	private maxturns = 4
	public orcamento as (single)
	public MusicName as string
	private caixa as single
	private areas as (Area)
	private city as City
	public gotoending = true

	def Start ():
		areas = GameObject.FindObjectsOfType(Area)
		t = turn/2
		caixa = orcamento[t]/2
		generateRandomPlayers()

	def Update ():
		//pass
		if gotoending:
			newTurn()

	def getAreas():
		return areas

	def getOrcamento() as single:
		gasto = 0
		for a in areas:
			gasto += a.getInvestimentoCultura()
			gasto += a.getInvestimentoEducacao()
			gasto += a.getInvestimentoEsporte()
			gasto += a.getInvestimentoInfraestrutura()
			gasto += a.getInvestimentoMeioAmbiente()
			gasto += a.getInvestimentoMobilidade()
			gasto += a.getInvestimentoAgropecuaria()
			gasto += a.getInvestimentoSaude()
			gasto += a.getInvestimentoTrabalho()
			gasto += a.getInvestimentoSeguranca()
		return caixa - gasto

	public def getCaixa() as single:
		return caixa

	def newTurn():
		turn++
		if turn >= maxturns:
			gotoending = false
			(GameObject.FindObjectOfType(EndChosen) as EndChosen).setEnding()
			return
		t = turn/2
		caixa = orcamento[t]/2
		generateRandomPlayers()
		(GameObject.FindObjectOfType(ButtonHistorico) as ButtonHistorico).activate()
		for a in areas:
			a.setSelected(false)

	def getTurn():
		return turn

	def getCaixaAtTurn(turnnum as int):
		if (turnnum < 0):
			turnnum = turn + 1 + turnnum
		t = turnnum/2
		return orcamento[t]/2

	public def getCaixaAllTurns():
		total = 0.0F
		for i in range(turn):
			total += getCaixaAtTurn(i)
		return total

	public def getMusicName():
		return MusicName

	def GenerateRandomValues(start as single,end as single,length as int) as (single):
		targets as (single) = array(single,length)

		for i in range(length):
			targets[i] = Random.Range(start, end)
		return targets

	def generateRandomPlayers():
		playervals = []
		for i in range(7):
			randomnums = GenerateRandomValues(0,caixa,len(areas)*10)
			sum as single = 0.0F
			for j in range(len(areas)*10):
				sum += randomnums[j]
			factor = (caixa/sum)*0.50 // bots invest 50% less
			for j in randomnums:
				j = j*factor
			playervals.Add(randomnums)

		for a in range(len(areas)):
			playerlist = array(Player,8)
			playerlist[0] = Player()
			playerlist[0].InvestimentoCultura = 0
			playerlist[0].InvestimentoEducacao = 0
			playerlist[0].InvestimentoEsporte = 0
			playerlist[0].InvestimentoInfraestrutura = 0
			playerlist[0].InvestimentoMeioAmbiente = 0
			playerlist[0].InvestimentoMobilidade = 0
			playerlist[0].InvestimentoAgropecuaria = 0
			playerlist[0].InvestimentoSaude = 0
			playerlist[0].InvestimentoTrabalho = 0
			playerlist[0].InvestimentoSeguranca = 0
			for p in range(1,8):
				playerlist[p] = Player()
				playerlist[p].InvestimentoCultura = (playervals[p-1] as (single))[0+a*10]
				playerlist[p].InvestimentoEducacao = (playervals[p-1] as (single))[1+a*10]
				playerlist[p].InvestimentoEsporte = (playervals[p-1] as (single))[2+a*10]
				playerlist[p].InvestimentoInfraestrutura = (playervals[p-1] as (single))[3+a*10]
				playerlist[p].InvestimentoMeioAmbiente = (playervals[p-1] as (single))[4+a*10]
				playerlist[p].InvestimentoMobilidade = (playervals[p-1] as (single))[5+a*10]
				playerlist[p].InvestimentoAgropecuaria = (playervals[p-1] as (single))[6+a*10]
				playerlist[p].InvestimentoSaude = (playervals[p-1] as (single))[7+a*10]
				playerlist[p].InvestimentoTrabalho = (playervals[p-1] as (single))[8+a*10]
				playerlist[p].InvestimentoSeguranca = (playervals[p-1] as (single))[9+a*10]
			areas[a].AddPlayers(playerlist)

	public def getInvestimentoCulturaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoCulturaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoEducacaoPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoEducacaoPlayer(playernum,turnnum)
		return total

	public def getInvestimentoEsportePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoEsportePlayer(playernum,turnnum)
		return total

	public def getInvestimentoInfraestruturaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoInfraestruturaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoMeioAmbientePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoMeioAmbientePlayer(playernum,turnnum)
		return total

	public def getInvestimentoMobilidadePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoMobilidadePlayer(playernum,turnnum)
		return total

	public def getInvestimentoAgropecuariaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoAgropecuariaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoSaudePlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoSaudePlayer(playernum,turnnum)
		return total

	public def getInvestimentoTrabalhoPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoTrabalhoPlayer(playernum,turnnum)
		return total

	public def getInvestimentoSegurancaPlayer(playernum,turnnum as int) as single:
		total = 0.0F
		for a in areas:
			total += a.getInvestimentoSegurancaPlayer(playernum,turnnum)
		return total

	public def getInvestimentoDisponivelPlayer(playernum,turnnum as int) as single:
		gasto = 0.0F
		for a in areas:
			gasto += a.getInvestimentoCulturaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoEducacaoPlayer(playernum,turnnum)
			gasto += a.getInvestimentoEsportePlayer(playernum,turnnum)
			gasto += a.getInvestimentoInfraestruturaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoMeioAmbientePlayer(playernum,turnnum)
			gasto += a.getInvestimentoMobilidadePlayer(playernum,turnnum)
			gasto += a.getInvestimentoAgropecuariaPlayer(playernum,turnnum)
			gasto += a.getInvestimentoSaudePlayer(playernum,turnnum)
			gasto += a.getInvestimentoTrabalhoPlayer(playernum,turnnum)
			gasto += a.getInvestimentoSegurancaPlayer(playernum,turnnum)
		return getCaixaAtTurn(turnnum)-gasto

	public def getInvestimentoCulturaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoCulturaPlayer(i,turnnum)
		return total

	public def getInvestimentoEducacaoTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoEducacaoPlayer(i,turnnum)
		return total

	public def getInvestimentoEsporteTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoEsportePlayer(i,turnnum)
		return total

	public def getInvestimentoInfraestruturaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoInfraestruturaPlayer(i,turnnum)
		return total

	public def getInvestimentoMeioAmbienteTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoMeioAmbientePlayer(i,turnnum)
		return total

	public def getInvestimentoMobilidadeTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoMobilidadePlayer(i,turnnum)
		return total

	public def getInvestimentoAgropecuariaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoAgropecuariaPlayer(i,turnnum)
		return total

	public def getInvestimentoSaudeTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoSaudePlayer(i,turnnum)
		return total

	public def getInvestimentoTrabalhoTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoTrabalhoPlayer(i,turnnum)
		return total

	public def getInvestimentoSegurancaTotal(turnnum as int) as single:
		total = 0.0F
		for i in range(8):
			total += getInvestimentoSegurancaPlayer(i,turnnum)
		return total

	public def getInvestimentoDisponivelTotal(turnnum as int) as single:
		gasto = 0.0F
		gasto += getInvestimentoCulturaTotal(turnnum)
		gasto += getInvestimentoEducacaoTotal(turnnum)
		gasto += getInvestimentoEsporteTotal(turnnum)
		gasto += getInvestimentoInfraestruturaTotal(turnnum)
		gasto += getInvestimentoMeioAmbienteTotal(turnnum)
		gasto += getInvestimentoMobilidadeTotal(turnnum)
		gasto += getInvestimentoAgropecuariaTotal(turnnum)
		gasto += getInvestimentoSaudeTotal(turnnum)
		gasto += getInvestimentoTrabalhoTotal(turnnum)
		gasto += getInvestimentoSegurancaTotal(turnnum)
		return getCaixaAtTurn(turnnum)*8-gasto

	public def getInvestimentoCulturaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoCulturaTotal(i)
		return total

	public def getInvestimentoEducacaoAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoEducacaoTotal(i)
		return total

	public def getInvestimentoEsporteAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoEsporteTotal(i)
		return total

	public def getInvestimentoInfraestruturaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoInfraestruturaTotal(i)
		return total

	public def getInvestimentoMeioAmbienteAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoMeioAmbienteTotal(i)
		return total

	public def getInvestimentoMobilidadeAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoMobilidadeTotal(i)
		return total

	public def getInvestimentoAgropecuariaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoAgropecuariaTotal(i)
		return total

	public def getInvestimentoSaudeAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoSaudeTotal(i)
		return total

	public def getInvestimentoTrabalhoAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoTrabalhoTotal(i)
		return total

	public def getInvestimentoSegurancaAllTurns() as single:
		total = 0.0F
		for i in range(turn):
			total += getInvestimentoSegurancaTotal(i)
		return total


DeclaringType might be null (for DynamicMethods for instance)

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2689 2c1201b4-01cd-e047-a400-b836ae1fbc61

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.Lang.Interpreter

import System
import System.Collections
import System.IO
import Boo.Lang
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.IO

class InteractiveInterpreter(AbstractInterpreter):

	_values = {}

	_declarations = {}

	_representers = []

	[property(ShowWarnings)]
	_showWarnings = false

	[property(BlockStarters, value is not null)]
	_blockStarters = ":", "\\"

	[getter(LastValue)]
	_lastValue

	[property(Print, value is not null)]
	_print as callable(object) = print

	def constructor():
		super()
		InitializeStandardReferences()

	def constructor(parser as ICompilerStep):
		super(parser)
		InitializeStandardReferences()

	def Reset():
		_values.Clear()
		_declarations.Clear()
		_lastValue = null
		InitializeStandardReferences()

	def ConsoleLoopEval():
		while (line=prompt(">>> ")) is not null:
			try:
				line = ReadBlock(line) if line[-1:] in _blockStarters
				InternalLoopEval(line)
			except x as System.Reflection.TargetInvocationException:
				print(x.InnerException)
			except x:
				print(x)
		print

	def LoopEval(code as string):
		using console = ConsoleCapture():
			result = InternalLoopEval(code)
			for line in System.IO.StringReader(console.ToString()):
				_print(line)
		return result

	private def InternalLoopEval(code as string):
		result = self.Eval(code)
		if ShowWarnings:
			self.DisplayProblems(result.Warnings)
		if not self.DisplayProblems(result.Errors):
			ProcessLastValue()
		return result

	private def ProcessLastValue():
		_ = self.LastValue
		if _ is not null:
			_print(repr(_))
			SetValue("_", _)

	override def Declare([required] name as string,
				[required] type as System.Type):
		_declarations.Add(name, type)

	override def SetLastValue(value):
		_lastValue = value

	override def SetValue(name as string, value):
		_values[name] = value
		return value

	override def GetValue(name as string):
		return _values[name]

	override def Lookup([required] name as string):
		type as System.Type = _declarations[name]
		return type if type is not null

		value = GetValue(name)
		return value.GetType() if value is not null

	def DisplayProblems(problems as ICollection):
		return if problems is null or problems.Count == 0
		for problem as duck in problems:
			markLocation(problem.LexicalInfo)
			type = ("WARNING", "ERROR")[problem isa CompilerError]
			_print("${type}: ${problem.Message}")
		if problems.Count > 0:
			return true
		return false
	/*def DisplayWarnings(warnings as CompilerWarningCollection):
		for warning in warnings:
			markLocation(warning.LexicalInfo)
			_print("WARNING: ${warning.Message}")

	def DisplayErrors(errors as CompilerErrorCollection):
		for error in errors:
			markLocation(error.LexicalInfo)
			_print("ERROR: ${error.Message}")
	*/
	private def markLocation(location as LexicalInfo):
		pos = location.Column
		_print("---" + "-" * pos + "^") if pos > 0
	private def InitializeStandardReferences():
		SetValue("interpreter", self)
		SetValue("dir", dir)
		SetValue("help", help)
		SetValue("print", { value | _print(value) })
		SetValue("load", load)
		SetValue("globals", globals)
		SetValue("getRootNamespace", Namespace.GetRootNamespace)

	def globals():
		return array(string, _values.Keys)

	def dir([required] obj):
		type = (obj as Type) or obj.GetType()
		return array(
				member for member in type.GetMembers()
				unless (method=(member as System.Reflection.MethodInfo))
				and method.IsSpecialName)

	def load([required] path as string):
		if path.EndsWith(".boo"):
			result = EvalCompilerInput(FileInput(path))
			if ShowWarnings:
				DisplayProblems(result.Warnings)
			if not DisplayProblems(result.Errors):
				ProcessLastValue()
		else:
			try:
				References.Add(System.Reflection.Assembly.LoadFrom(path))
			except e:
				print e.Message

	def help(obj):
		type = (obj as Type) or obj.GetType()
		DescribeType("    ", type)

	def DescribeType(indent as string, type as Type):

		if type.IsInterface:
			typeDef = "interface"
			baseTypes = array(GetBooTypeName(t) for t in type.GetInterfaces())
		else:
			typeDef = "class"
			baseTypes = (GetBooTypeName(type.BaseType),) + array(GetBooTypeName(t) for t in type.GetInterfaces())

		_print("${typeDef} ${type.Name}(${join(baseTypes, ', ')}):")
		_print("")

		for ctor in type.GetConstructors():
			_print("${indent}def constructor(${DescribeParameters(ctor.GetParameters())})")
			_print("")

		sortByName = def (lhs as Reflection.MemberInfo, rhs as Reflection.MemberInfo):
			return lhs.Name.CompareTo(rhs.Name)

		for f as Reflection.FieldInfo in List(type.GetFields()).Sort(sortByName):
			_print("${indent}public ${DescribeField(f)}")
			_print("")

		for p as Reflection.PropertyInfo in List(type.GetProperties()).Sort(sortByName):
			_print("${indent}${DescribeProperty(p)}:")
			_print("${indent}${indent}get") if p.GetGetMethod() is not null
			_print("${indent}${indent}set") if p.GetSetMethod() is not null
			_print("")

		for m as Reflection.MethodInfo in List(type.GetMethods()).Sort(sortByName):
			continue if m.IsSpecialName
			_print("${indent}${DescribeMethod(m)}")
			_print("")

		for e as Reflection.EventInfo in List(type.GetEvents()).Sort(sortByName):
			_print("${indent}${DescribeEvent(e)}")
			_print("")

	static def DescribeEntity(entity as IEntity):
		method = entity as ExternalMethod
		if method is not null:
			return InteractiveInterpreter.DescribeMethod(method.MethodInfo)
		field = entity as ExternalField
		if field is not null:
			return InteractiveInterpreter.DescribeField(field.FieldInfo)
		property = entity as ExternalProperty
		if property is not null:
			return InteractiveInterpreter.DescribeProperty(property.PropertyInfo)
		e = entity as ExternalEvent
		if e is not null:
			return InteractiveInterpreter.DescribeEvent(e.EventInfo)
		return entity.ToString()

	static def DescribeEvent(e as Reflection.EventInfo):
		return "${DescribeModifiers(e)}event ${e.Name} as ${e.EventHandlerType}"

	static def DescribeProperty(p as Reflection.PropertyInfo):
		modifiers = DescribeModifiers(p)
		params = DescribePropertyParameters(p.GetIndexParameters())
		return "${modifiers}${p.Name}${params} as ${GetBooTypeName(p.PropertyType)}"

	static def DescribeField(f as Reflection.FieldInfo):
		return "${DescribeModifiers(f)}${f.Name} as ${GetBooTypeName(f.FieldType)}"

	static def DescribeMethod(m as Reflection.MethodInfo):
		returnType = GetBooTypeName(m.ReturnType)
		modifiers = DescribeModifiers(m)
		return "${modifiers}def ${m.Name}(${DescribeParameters(m.GetParameters())}) as ${returnType}"

	static def DescribeModifiers(f as Reflection.FieldInfo):
		return "static " if f.IsStatic
		return ""

	static def DescribeModifiers(m as Reflection.MethodBase):
		return "static " if m.IsStatic
		return ""

	static def DescribeModifiers(e as Reflection.EventInfo):
		return DescribeModifiers(e.GetAddMethod(true) or e.GetRemoveMethod(true))

	static def DescribeModifiers(p as Reflection.PropertyInfo):
		accessor = p.GetGetMethod(true) or p.GetSetMethod(true)
		return DescribeModifiers(accessor)

	static def DescribePropertyParameters(parameters as (Reflection.ParameterInfo)):
		return "" if 0 == len(parameters)
		return "(${DescribeParameters(parameters)})"

	static def DescribeParameters(parameters as (Reflection.ParameterInfo)):
		return join(DescribeParameter(p) for p in parameters, ", ")

	static def DescribeParameter(p as Reflection.ParameterInfo):
		return "${p.Name} as ${GetBooTypeName(p.ParameterType)}"

	static def GetBooTypeName(type as System.Type) as string:
		return "(${GetBooTypeName(type.GetElementType())})" if type.IsArray
		return "object" if object is type
		return "string" if string is type
		return "void" if void is type
		return "bool" if bool is type
		return "byte" if byte is type
		return "char" if char is type
		return "sbyte" if sbyte is type
		return "short" if short is type
		return "ushort" if ushort is type
		return "int" if int is type
		return "uint" if uint is type
		return "long" if long is type
		return "ulong" if ulong is type
		return "single" if single is type
		return "double" if double is type
		return "date" if date is type
		return "timespan" if timespan is type
		return "regex" if regex is type
		return type.FullName

	def repr(value):
		writer = System.IO.StringWriter()
		repr(value, writer)
		return writer.ToString()

	def repr(value, writer as System.IO.TextWriter):
		return unless value is not null
		InitializeRepresenters() if 0 == len(_representers)
		GetBestRepresenter(value.GetType())(value, writer)

	private def InitializeRepresenters():
		AddRepresenter(string) do (value as string, writer as TextWriter):
			Visitors.BooPrinterVisitor.WriteStringLiteral(value, writer)

		AddRepresenter(bool) do (value as bool, writer as TextWriter):
			writer.Write(("false", "true")[value])

		AddRepresenter(Array) do (a as Array, writer as TextWriter):
			writer.Write("(")
			RepresentItems(a, writer)
			writer.Write(")")

		AddRepresenter(Delegate) do (d as Delegate, writer as TextWriter):
			method = d.Method
			if method.DeclaringType is not null:
				writer.Write(method.DeclaringType.FullName)
				writer.Write(".")
			writer.Write(method.Name)

		AddRepresenter(IDictionary) do (value as IDictionary, writer as TextWriter):
			writer.Write("{")
			i = 0
			for key in value.Keys:
				writer.Write(", ") if i
				repr(key, writer)
				writer.Write(": ")
				repr(value[key], writer)
				++i
			writer.Write("}")

		AddRepresenter(IList) do (value as IList, writer as TextWriter):
			writer.Write("[")
			RepresentItems(value, writer)
			writer.Write("]")

		AddRepresenter(object) do (value, writer as TextWriter):
			writer.Write(value)

	private def RepresentItems(items, writer as TextWriter):
		i = 0
		for item in items:
			writer.Write(", ") if i > 0
			repr(item, writer)
			++i

	callable Representer(value, writer as TextWriter)

	private def AddRepresenter(type as Type, value as Representer):
		_representers.Add((type, value))

	def GetBestRepresenter(type as Type) as Representer:
		for key as Type, value in _representers:
			return value if key.IsAssignableFrom(type)
		assert false, "An appropriate representer could not be found!"

def ReadBlock(line as string):
	newLine = System.Environment.NewLine
	buffer = System.Text.StringBuilder()
	buffer.Append(line)
	buffer.Append(newLine)
	while line=prompt("... "):
		break if 0 == len(line)
		buffer.Append(line)
		buffer.Append(newLine)
	return buffer.ToString()

#region license
// Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Rodrigo B. de Oliveira nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

namespace Boo.Lang.Interpreter

import System
import System.Collections
import System.IO
import Boo.Lang
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.IO

class InteractiveInterpreter(AbstractInterpreter):

	_values = {}

	_declarations = {}

	_representers = []

	[property(ShowWarnings)]
	_showWarnings = false

	[property(BlockStarters, value is not null)]
	_blockStarters = ":", "\\"

	[getter(LastValue)]
	_lastValue

	[property(Print, value is not null)]
	_print as callable(object) = print

	def constructor():
		super()
		InitializeStandardReferences()

	def constructor(parser as ICompilerStep):
		super(parser)
		InitializeStandardReferences()

	def Reset():
		_values.Clear()
		_declarations.Clear()
		_lastValue = null
		InitializeStandardReferences()

	def ConsoleLoopEval():
		while (line=prompt(">>> ")) is not null:
			try:
				line = ReadBlock(line) if line[-1:] in _blockStarters
				InternalLoopEval(line)
			except x as System.Reflection.TargetInvocationException:
				print(x.InnerException)
			except x:
				print(x)
		print

	def LoopEval(code as string):
		using console = ConsoleCapture():
			result = InternalLoopEval(code)
			for line in System.IO.StringReader(console.ToString()):
				_print(line)
		return result

	private def InternalLoopEval(code as string):
		result = self.Eval(code)
		if ShowWarnings:
			self.DisplayProblems(result.Warnings)
		if not self.DisplayProblems(result.Errors):
			ProcessLastValue()
		return result

	private def ProcessLastValue():
		_ = self.LastValue
		if _ is not null:
			_print(repr(_))
			SetValue("_", _)

	override def Declare([required] name as string,
				[required] type as System.Type):
		_declarations.Add(name, type)

	override def SetLastValue(value):
		_lastValue = value

	override def SetValue(name as string, value):
		_values[name] = value
		return value

	override def GetValue(name as string):
		return _values[name]

	override def Lookup([required] name as string):
		type as System.Type = _declarations[name]
		return type if type is not null

		value = GetValue(name)
		return value.GetType() if value is not null

	def DisplayProblems(problems as ICollection):
		return if problems is null or problems.Count == 0
		for problem as duck in problems:
			markLocation(problem.LexicalInfo)
			type = ("WARNING", "ERROR")[problem isa CompilerError]
			_print("${type}: ${problem.Message}")
		if problems.Count > 0:
			return true
		return false
	/*def DisplayWarnings(warnings as CompilerWarningCollection):
		for warning in warnings:
			markLocation(warning.LexicalInfo)
			_print("WARNING: ${warning.Message}")

	def DisplayErrors(errors as CompilerErrorCollection):
		for error in errors:
			markLocation(error.LexicalInfo)
			_print("ERROR: ${error.Message}")
	*/
	private def markLocation(location as LexicalInfo):
		pos = location.Column
		_print("---" + "-" * pos + "^") if pos > 0
	private def InitializeStandardReferences():
		SetValue("interpreter", self)
		SetValue("dir", dir)
		SetValue("help", help)
		SetValue("print", { value | _print(value) })
		SetValue("load", load)
		SetValue("globals", globals)
		SetValue("getRootNamespace", Namespace.GetRootNamespace)

	def globals():
		return array(string, _values.Keys)

	def dir([required] obj):
		type = (obj as Type) or obj.GetType()
		return array(
				member for member in type.GetMembers()
				unless (method=(member as System.Reflection.MethodInfo))
				and method.IsSpecialName)

	def load([required] path as string):
		if path.EndsWith(".boo"):
			result = EvalCompilerInput(FileInput(path))
			if ShowWarnings:
				DisplayProblems(result.Warnings)
			if not DisplayProblems(result.Errors):
				ProcessLastValue()
		else:
			try:
				References.Add(System.Reflection.Assembly.LoadFrom(path))
			except e:
				print e.Message

	def help(obj):
		type = (obj as Type) or obj.GetType()
		DescribeType("    ", type)

	def DescribeType(indent as string, type as Type):

		if type.IsInterface:
			typeDef = "interface"
			baseTypes = array(GetBooTypeName(t) for t in type.GetInterfaces())
		else:
			typeDef = "class"
			baseTypes = (GetBooTypeName(type.BaseType),) + array(GetBooTypeName(t) for t in type.GetInterfaces())

		_print("${typeDef} ${type.Name}(${join(baseTypes, ', ')}):")
		_print("")

		for ctor in type.GetConstructors():
			_print("${indent}def constructor(${DescribeParameters(ctor.GetParameters())})")
			_print("")

		sortByName = def (lhs as Reflection.MemberInfo, rhs as Reflection.MemberInfo):
			return lhs.Name.CompareTo(rhs.Name)

		for f as Reflection.FieldInfo in List(type.GetFields()).Sort(sortByName):
			_print("${indent}public ${DescribeField(f)}")
			_print("")

		for p as Reflection.PropertyInfo in List(type.GetProperties()).Sort(sortByName):
			_print("${indent}${DescribeProperty(p)}:")
			_print("${indent}${indent}get") if p.GetGetMethod() is not null
			_print("${indent}${indent}set") if p.GetSetMethod() is not null
			_print("")

		for m as Reflection.MethodInfo in List(type.GetMethods()).Sort(sortByName):
			continue if m.IsSpecialName
			_print("${indent}${DescribeMethod(m)}")
			_print("")

		for e as Reflection.EventInfo in List(type.GetEvents()).Sort(sortByName):
			_print("${indent}${DescribeEvent(e)}")
			_print("")

	static def DescribeEntity(entity as IEntity):
		method = entity as ExternalMethod
		if method is not null:
			return InteractiveInterpreter.DescribeMethod(method.MethodInfo)
		field = entity as ExternalField
		if field is not null:
			return InteractiveInterpreter.DescribeField(field.FieldInfo)
		property = entity as ExternalProperty
		if property is not null:
			return InteractiveInterpreter.DescribeProperty(property.PropertyInfo)
		e = entity as ExternalEvent
		if e is not null:
			return InteractiveInterpreter.DescribeEvent(e.EventInfo)
		return entity.ToString()

	static def DescribeEvent(e as Reflection.EventInfo):
		return "${DescribeModifiers(e)}event ${e.Name} as ${e.EventHandlerType}"

	static def DescribeProperty(p as Reflection.PropertyInfo):
		modifiers = DescribeModifiers(p)
		params = DescribePropertyParameters(p.GetIndexParameters())
		return "${modifiers}${p.Name}${params} as ${GetBooTypeName(p.PropertyType)}"

	static def DescribeField(f as Reflection.FieldInfo):
		return "${DescribeModifiers(f)}${f.Name} as ${GetBooTypeName(f.FieldType)}"

	static def DescribeMethod(m as Reflection.MethodInfo):
		returnType = GetBooTypeName(m.ReturnType)
		modifiers = DescribeModifiers(m)
		return "${modifiers}def ${m.Name}(${DescribeParameters(m.GetParameters())}) as ${returnType}"

	static def DescribeModifiers(f as Reflection.FieldInfo):
		return "static " if f.IsStatic
		return ""

	static def DescribeModifiers(m as Reflection.MethodBase):
		return "static " if m.IsStatic
		return ""

	static def DescribeModifiers(e as Reflection.EventInfo):
		return DescribeModifiers(e.GetAddMethod(true) or e.GetRemoveMethod(true))

	static def DescribeModifiers(p as Reflection.PropertyInfo):
		accessor = p.GetGetMethod(true) or p.GetSetMethod(true)
		return DescribeModifiers(accessor)

	static def DescribePropertyParameters(parameters as (Reflection.ParameterInfo)):
		return "" if 0 == len(parameters)
		return "(${DescribeParameters(parameters)})"

	static def DescribeParameters(parameters as (Reflection.ParameterInfo)):
		return join(DescribeParameter(p) for p in parameters, ", ")

	static def DescribeParameter(p as Reflection.ParameterInfo):
		return "${p.Name} as ${GetBooTypeName(p.ParameterType)}"

	static def GetBooTypeName(type as System.Type) as string:
		return "(${GetBooTypeName(type.GetElementType())})" if type.IsArray
		return "object" if object is type
		return "string" if string is type
		return "void" if void is type
		return "bool" if bool is type
		return "byte" if byte is type
		return "char" if char is type
		return "sbyte" if sbyte is type
		return "short" if short is type
		return "ushort" if ushort is type
		return "int" if int is type
		return "uint" if uint is type
		return "long" if long is type
		return "ulong" if ulong is type
		return "single" if single is type
		return "double" if double is type
		return "date" if date is type
		return "timespan" if timespan is type
		return "regex" if regex is type
		return type.FullName

	def repr(value):
		writer = System.IO.StringWriter()
		repr(value, writer)
		return writer.ToString()

	def repr(value, writer as System.IO.TextWriter):
		return unless value is not null
		InitializeRepresenters() if 0 == len(_representers)
		GetBestRepresenter(value.GetType())(value, writer)

	private def InitializeRepresenters():
		AddRepresenter(string) do (value as string, writer as TextWriter):
			Visitors.BooPrinterVisitor.WriteStringLiteral(value, writer)

		AddRepresenter(bool) do (value as bool, writer as TextWriter):
			writer.Write(("false", "true")[value])

		AddRepresenter(Array) do (a as Array, writer as TextWriter):
			writer.Write("(")
			RepresentItems(a, writer)
			writer.Write(")")

		AddRepresenter(Delegate) do (d as Delegate, writer as TextWriter):
			method = d.Method
			writer.Write(method.DeclaringType.FullName)
			writer.Write(".")
			writer.Write(method.Name)

		AddRepresenter(IDictionary) do (value as IDictionary, writer as TextWriter):
			writer.Write("{")
			i = 0
			for key in value.Keys:
				writer.Write(", ") if i
				repr(key, writer)
				writer.Write(": ")
				repr(value[key], writer)
				++i
			writer.Write("}")

		AddRepresenter(IList) do (value as IList, writer as TextWriter):
			writer.Write("[")
			RepresentItems(value, writer)
			writer.Write("]")

		AddRepresenter(object) do (value, writer as TextWriter):
			writer.Write(value)

	private def RepresentItems(items, writer as TextWriter):
		i = 0
		for item in items:
			writer.Write(", ") if i > 0
			repr(item, writer)
			++i

	callable Representer(value, writer as TextWriter)

	private def AddRepresenter(type as Type, value as Representer):
		_representers.Add((type, value))

	def GetBestRepresenter(type as Type) as Representer:
		for key as Type, value in _representers:
			return value if key.IsAssignableFrom(type)
		assert false, "An appropriate representer could not be found!"

def ReadBlock(line as string):
	newLine = System.Environment.NewLine
	buffer = System.Text.StringBuilder()
	buffer.Append(line)
	buffer.Append(newLine)
	while line=prompt("... "):
		break if 0 == len(line)
		buffer.Append(line)
		buffer.Append(newLine)
	return buffer.ToString()


corrected test

corrected test

git-svn-id: fcce7d6ce0ac15bf24f68871b5145d46fc068279@2141 2c1201b4-01cd-e047-a400-b836ae1fbc61

"""
a = ast:
	return 3

d = ast:
	print 'Hello, world'

e = ast { print('Hello, world') }
"""
a = ast { return 3 }
d = ast { print "Hello, world" }
e = ast { print("Hello, world") }

"""
a = ast:
	return 3

d = ast:
	print 'Hello, world'

e = ast:
	print('Hello, world')
"""
a = ast { return 3 }
d = ast { print "hello world" }
e = ast { print("hello world") }