2 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 using System
.Collections
;
31 using System
.Collections
.Generic
;
34 using System
.Reflection
;
35 using Boo
.Lang
.Runtime
;
40 /// boo language builtin functions.
48 public static System
.Version BooVersion
52 return new System
.Version("0.8.1.2896");
56 public static void print(object o
)
61 public static string gets()
63 return Console
.ReadLine();
66 public static string prompt(string message
)
68 Console
.Write(message
);
69 return Console
.ReadLine();
72 public static string join(IEnumerable enumerable
, string separator
)
74 StringBuilder sb
= new StringBuilder();
75 IEnumerator enumerator
= enumerable
.GetEnumerator();
76 using (enumerator
as IDisposable
)
78 if (enumerator
.MoveNext())
80 sb
.Append(enumerator
.Current
);
81 while (enumerator
.MoveNext())
84 sb
.Append(enumerator
.Current
);
91 public static string join(IEnumerable enumerable
, char separator
)
93 StringBuilder sb
= new StringBuilder();
94 IEnumerator enumerator
= enumerable
.GetEnumerator();
95 using (enumerator
as IDisposable
)
97 if (enumerator
.MoveNext())
99 sb
.Append(enumerator
.Current
);
100 while (enumerator
.MoveNext())
102 sb
.Append(separator
);
103 sb
.Append(enumerator
.Current
);
107 return sb
.ToString();
110 public static string join(IEnumerable enumerable
)
112 return join(enumerable
, ' ');
115 public static IEnumerable
map(object enumerable
, ICallable function
)
117 if (null == enumerable
) throw new ArgumentNullException("enumerable");
118 if (null == function
) throw new ArgumentNullException("function");
120 object[] args
= new object[1];
121 foreach (object item
in iterator(enumerable
))
124 yield return function
.Call(args
);
128 public static object[] array(IEnumerable enumerable
)
130 return new List(enumerable
).ToArray();
133 public static Array
array(Type elementType
, ICollection collection
)
135 if (null == collection
)
137 throw new ArgumentNullException("collection");
139 if (null == elementType
)
141 throw new ArgumentNullException("elementType");
144 Array array
= Array
.CreateInstance(elementType
, collection
.Count
);
145 if (RuntimeServices
.IsPromotableNumeric(Type
.GetTypeCode(elementType
)))
148 foreach (object item
in collection
)
150 object value = RuntimeServices
.CheckNumericPromotion(item
).ToType(elementType
, null);
151 array
.SetValue(value, i
);
157 collection
.CopyTo(array
, 0);
162 public static Array
array(Type elementType
, IEnumerable enumerable
)
164 if (null == enumerable
)
166 throw new ArgumentNullException("enumerable");
168 if (null == elementType
)
170 throw new ArgumentNullException("elementType");
173 // future optimization, check EnumeratorItemType of enumerable
174 // and get the fast path whenever possible
176 if (RuntimeServices
.IsPromotableNumeric(Type
.GetTypeCode(elementType
)))
179 foreach (object item
in enumerable
)
181 object value = RuntimeServices
.CheckNumericPromotion(item
).ToType(elementType
, null);
187 l
= new List(enumerable
);
189 return l
.ToArray(elementType
);
192 public static Array
array(Type elementType
, int length
)
194 return matrix(elementType
, length
);
197 public static Array
matrix(Type elementType
, params int[] lengths
)
199 if (null == elementType
)
201 throw new ArgumentNullException("elementType");
203 return Array
.CreateInstance(elementType
, lengths
);
206 public static IEnumerable
iterator(object enumerable
)
208 return RuntimeServices
.GetEnumerable(enumerable
);
212 public static System
.Diagnostics
.Process
shellp(string filename
, string arguments
)
214 System
.Diagnostics
.Process p
= new System
.Diagnostics
.Process();
215 p
.StartInfo
.Arguments
= arguments
;
216 p
.StartInfo
.CreateNoWindow
= true;
217 p
.StartInfo
.UseShellExecute
= false;
218 p
.StartInfo
.RedirectStandardOutput
= true;
219 p
.StartInfo
.RedirectStandardInput
= true;
220 p
.StartInfo
.RedirectStandardError
= true;
221 p
.StartInfo
.FileName
= filename
;
226 public static string shell(string filename
, string arguments
)
228 System
.Diagnostics
.Process p
= shellp(filename
, arguments
);
229 string output
= p
.StandardOutput
.ReadToEnd();
235 internal class AssemblyExecutor
: MarshalByRefObject
239 string _capturedOutput
= "";
241 public AssemblyExecutor(string filename
, string[] arguments
)
243 _filename
= filename
;
244 _arguments
= arguments
;
247 public string CapturedOutput
251 return _capturedOutput
;
255 public void Execute()
257 StringWriter output
= new System
.IO
.StringWriter();
258 TextWriter saved
= Console
.Out
;
261 Console
.SetOut(output
);
262 //AppDomain.CurrentDomain.ExecuteAssembly(_filename, null, _arguments);
263 Assembly
.LoadFrom(_filename
).EntryPoint
.Invoke(null, new object[1] { _arguments }
);
267 Console
.SetOut(saved
);
268 _capturedOutput
= output
.ToString();
274 /// Execute the specified MANAGED application in a new AppDomain.
276 /// The base directory for the new application domain will be set to
277 /// directory containing filename (Path.GetDirectoryName(Path.GetFullPath(filename))).
279 public static string shellm(string filename
, params string[] arguments
)
281 AppDomainSetup setup
= new AppDomainSetup();
282 setup
.ApplicationBase
= Path
.GetDirectoryName(Path
.GetFullPath(filename
));
284 AppDomain domain
= AppDomain
.CreateDomain("shellm", null, setup
);
287 AssemblyExecutor executor
= new AssemblyExecutor(filename
, arguments
);
288 domain
.DoCallBack(new CrossAppDomainDelegate(executor
.Execute
));
289 return executor
.CapturedOutput
;
293 AppDomain
.Unload(domain
);
297 public static IEnumerable
<object[]> enumerate(object enumerable
)
300 foreach (object item
in iterator(enumerable
))
302 yield return new object[] { i++, item }
;
306 public static IEnumerable
<int> range(int max
)
308 if (max
< 0) /* added for coherence with behavior of compiler-optimized
309 * for-in-range() loops, should compiler loops automatically
310 * inverse iteration in this case? */
312 throw new ArgumentOutOfRangeException("max < 0");
314 return range(0, max
);
317 public static IEnumerable
<int> range(int begin
, int end
)
321 for (int i
= begin
; i
< end
; ++i
) yield return i
;
323 else if (begin
> end
)
325 for (int i
= begin
; i
> end
; --i
) yield return i
;
329 public static IEnumerable
<int> range(int begin
, int end
, int step
)
333 throw new ArgumentOutOfRangeException("step == 0");
339 throw new ArgumentOutOfRangeException("begin < end && step < 0");
341 for (int i
= begin
; i
> end
; i
+= step
) yield return i
;
347 throw new ArgumentOutOfRangeException("begin > end && step > 0");
349 for (int i
= begin
; i
< end
; i
+= step
) yield return i
;
353 public static IEnumerable
reversed(object enumerable
)
355 return new List(iterator(enumerable
)).Reversed
;
358 public static ZipEnumerator
zip(params object[] enumerables
)
360 IEnumerator
[] enumerators
= new IEnumerator
[enumerables
.Length
];
361 for (int i
=0; i
<enumerables
.Length
; ++i
)
363 enumerators
[i
] = GetEnumerator(enumerables
[i
]);
365 return new ZipEnumerator(enumerators
);
368 public static IEnumerable
<object> cat(params object[] args
)
370 foreach (object e
in args
)
372 foreach (object item
in iterator(e
))
379 [EnumeratorItemType(typeof(object[]))]
380 public class ZipEnumerator
: IEnumerator
, IEnumerable
, IDisposable
382 IEnumerator
[] _enumerators
;
384 internal ZipEnumerator(params IEnumerator
[] enumerators
)
386 _enumerators
= enumerators
;
389 public void Dispose()
391 for (int i
=0; i
<_enumerators
.Length
; ++i
)
393 IDisposable d
= _enumerators
[i
] as IDisposable
;
401 for (int i
=0; i
<_enumerators
.Length
; ++i
)
403 _enumerators
[i
].Reset();
407 public bool MoveNext()
409 for (int i
=0; i
<_enumerators
.Length
; ++i
)
411 if (!_enumerators
[i
].MoveNext())
419 public object Current
423 object[] current
= new object[_enumerators
.Length
];
424 for (int i
=0; i
<current
.Length
; ++i
)
426 current
[i
] = _enumerators
[i
].Current
;
432 public IEnumerator
GetEnumerator()
438 private static IEnumerator
GetEnumerator(object enumerable
)
440 return RuntimeServices
.GetEnumerable(enumerable
).GetEnumerator();