PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/System.Xronos/Builtins/SpecialForms.cs

https://bitbucket.org/stefanrusek/xronos
C# | 747 lines | 592 code | 131 blank | 24 comment | 57 complexity | e66235336007d25a0deacd86eefebfed MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) 2008 Stefan Rusek and Benjamin Pollack
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. *
  23. * ***************************************************************************/
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Linq;
  27. using System.Text;
  28. using System.Xronos.Language;
  29. using Microsoft.Linq.Expressions;
  30. using System.Reflection;
  31. using System.Collections;
  32. using Microsoft.Scripting.Actions;
  33. using Microsoft.Scripting.Runtime;
  34. using System.Xronos.Scripting.Binders;
  35. using Microsoft.Scripting.Utils;
  36. using System.Xronos.Scripting;
  37. using Microsoft.Scripting.Ast;
  38. namespace System.Xronos.Builtins
  39. {
  40. public static partial class SpecialForms
  41. {
  42. static readonly Symbol Add = Symbol.Create("+*");
  43. static readonly Symbol Sub = Symbol.Create("-*");
  44. static readonly Symbol Mul = Symbol.Create("**");
  45. static readonly Symbol Div = Symbol.Create("div*");
  46. static readonly Symbol Quot = Symbol.Create("quot");
  47. static readonly Symbol Rem = Symbol.Create("rem");
  48. static readonly Symbol Lt = Symbol.Create("<");
  49. static readonly Symbol Gt = Symbol.Create(">");
  50. static readonly Symbol Lte = Symbol.Create("<=");
  51. static readonly Symbol Gte = Symbol.Create(">=");
  52. static readonly Symbol EqualsOp = Symbol.Create("==");
  53. static readonly Symbol Not = Symbol.Create("not");
  54. static readonly Symbol NotEquals = Symbol.Create("not=");
  55. static readonly Symbol Try = Symbol.Create("try");
  56. static readonly Symbol Throw = Symbol.Create("throw");
  57. static readonly Symbol Rethrow = Symbol.Create("rethrow");
  58. internal static readonly Symbol Do = Symbol.Create("do");
  59. static readonly Symbol Let = Symbol.Create("let");
  60. static readonly Symbol If = Symbol.Create("if");
  61. static readonly Symbol Binding = Symbol.Create("binding");
  62. static readonly Symbol Set = Symbol.Create("set!");
  63. static readonly Symbol Def = Symbol.Create("def");
  64. static readonly Symbol Fn = Symbol.Create("fn");
  65. static readonly Symbol Loop = Symbol.Create("loop");
  66. static readonly Symbol Recur = Symbol.Create("recur");
  67. static readonly Symbol Quote = Symbol.Create("quote");
  68. public static readonly Symbol Dot = Symbol.Create(".");
  69. public static readonly Symbol New = Symbol.Create("new");
  70. static readonly Symbol Enter = Symbol.Create("monitor-enter");
  71. static readonly Symbol Exit = Symbol.Create("monitor-exit");
  72. static readonly Symbol InNs = Symbol.Create("in-ns");
  73. static readonly Symbol Cast = Symbol.Create("cast*");
  74. static readonly Symbol Is = Symbol.Create("is*");
  75. static readonly Symbol As = Symbol.Create("as*");
  76. #if DEBUG
  77. static readonly Symbol Debug = Symbol.Create("debug");
  78. #endif
  79. static Dictionary<Symbol, SpecialFormBase> forms;
  80. static SpecialForms()
  81. {
  82. forms = new Dictionary<Symbol, SpecialFormBase>();
  83. forms[Add] = new AddForm();
  84. forms[Sub] = new SubtractForm();
  85. forms[Mul] = new MultiplyForm();
  86. forms[Div] = new DivideForm();
  87. forms[Quot] = new QuotForm();
  88. forms[Rem] = new RemForm();
  89. forms[Lt] = new LtForm();
  90. forms[Gt] = new GtForm();
  91. forms[Lte] = new LteForm();
  92. forms[Gte] = new GteForm();
  93. forms[EqualsOp] = new EqualsForm();
  94. forms[Not] = new NotForm();
  95. forms[NotEquals] = new NotEqualsForm();
  96. forms[Try] = new TryForm();
  97. forms[Throw] = new ThrowForm();
  98. forms[Rethrow] = new RethrowForm();
  99. forms[Do] = new DoForm();
  100. forms[Let] = new LetForm();
  101. forms[If] = new IfForm();
  102. forms[Binding] = new BindingForm();
  103. forms[Set] = new SetForm();
  104. forms[Def] = new DefForm();
  105. forms[Fn] = new FnForm();
  106. forms[Loop] = new LoopForm();
  107. forms[Recur] = new RecurForm();
  108. forms[Quote] = new QuoteForm();
  109. forms[Dot] = new DotForm();
  110. forms[New] = new NewForm();
  111. forms[Enter] = new StaticMethodForm(typeof(System.Threading.Monitor).GetMethod("Enter"));
  112. forms[Exit] = new StaticMethodForm(typeof(System.Threading.Monitor).GetMethod("Exit"));
  113. forms[InNs] = new InNsForm();
  114. forms[Cast] = new CastForm();
  115. forms[Is] = new CastIsForm();
  116. forms[As] = new CastAsForm();
  117. #if DEBUG
  118. forms[Debug] = new DebugForm();
  119. #endif
  120. }
  121. internal static object Lookup(Symbol sym)
  122. {
  123. SpecialFormBase result;
  124. if (forms.TryGetValue(sym, out result))
  125. return result;
  126. return null;
  127. }
  128. internal static bool IsSpecialForm(Symbol sym)
  129. {
  130. return Lookup(sym) != null;
  131. }
  132. internal abstract class SpecialFormBase : XronosObject
  133. {
  134. protected SpecialFormBase() : base(null) { }
  135. protected abstract Expression Compile(Compiler compiler, ISequence rest, Scope scope);
  136. public virtual object Invoke(object arg1, object arg2, object arg3)
  137. {
  138. return Compile((Compiler)arg1, RT.seq(arg2), (Scope)arg3);
  139. }
  140. public override XronosObject withMeta(IPersistentMap meta)
  141. {
  142. throw new NotImplementedException();
  143. }
  144. }
  145. class StaticMethodForm : SpecialFormBase
  146. {
  147. MethodInfo method;
  148. internal StaticMethodForm(MethodInfo method) { this.method = method; }
  149. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  150. {
  151. return Utils.SimpleCallHelper(method, compiler.CompileArguments(rest, scope));
  152. }
  153. }
  154. class ThrowForm : SpecialFormBase
  155. {
  156. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  157. {
  158. return Expression.Throw(compiler.CompileToExpression(rest.first(), scope));
  159. }
  160. }
  161. class RethrowForm : SpecialFormBase
  162. {
  163. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  164. {
  165. return Expression.Rethrow();
  166. }
  167. }
  168. class DebugForm : SpecialFormBase
  169. {
  170. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  171. {
  172. var exp = compiler.CompileToExpression(rest.first(), scope);
  173. object dump = exp.DebugView;
  174. Console.Out.WriteLine(dump);
  175. return exp;
  176. }
  177. }
  178. #region math special forms
  179. abstract class BinaryOpForm : SpecialFormBase
  180. {
  181. protected virtual bool AllowEmpty { get { return true; } }
  182. protected abstract object DefaultValue { get; }
  183. protected abstract ExpressionType ExType { get; }
  184. protected Expression InternalOp(Expression left, Expression right)
  185. {
  186. return Expression.Dynamic(BinderFactory.BinaryOp(ExType), typeof(object), left, right);
  187. }
  188. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  189. {
  190. Expression result = null;
  191. if (rest == null && AllowEmpty)
  192. result = Expression.Constant(DefaultValue);
  193. else
  194. {
  195. result = compiler.CompileToExpression(rest.first(), scope);
  196. rest = rest.rest();
  197. }
  198. CompileRest(compiler, rest, scope, ref result);
  199. return result;
  200. }
  201. protected virtual void CompileRest(Compiler compiler, ISequence rest, Scope scope, ref Expression result)
  202. {
  203. while (rest != null)
  204. {
  205. result = InternalOp(result, compiler.CompileToExpression(rest.first(), scope));
  206. rest = rest.rest();
  207. }
  208. }
  209. }
  210. class AddForm : BinaryOpForm
  211. {
  212. protected override object DefaultValue
  213. {
  214. get { return (int)0; }
  215. }
  216. protected override ExpressionType ExType
  217. {
  218. get { return ExpressionType.Add; }
  219. }
  220. }
  221. class SubtractForm : BinaryOpForm
  222. {
  223. protected override bool AllowEmpty { get { return false; } }
  224. protected override object DefaultValue
  225. {
  226. get { return (int)0; }
  227. }
  228. protected override ExpressionType ExType
  229. {
  230. get { return ExpressionType.Subtract; }
  231. }
  232. }
  233. class MultiplyForm : BinaryOpForm
  234. {
  235. protected override object DefaultValue
  236. {
  237. get { return (int)1; }
  238. }
  239. protected override ExpressionType ExType
  240. {
  241. get { return ExpressionType.Multiply; }
  242. }
  243. }
  244. class DivideForm : BinaryOpForm
  245. {
  246. protected override bool AllowEmpty { get { return false; } }
  247. protected override object DefaultValue
  248. {
  249. get { return (int)1; }
  250. }
  251. protected override ExpressionType ExType
  252. {
  253. get { return ExpressionType.Divide; }
  254. }
  255. }
  256. class QuotForm : BinaryOpForm
  257. {
  258. protected override bool AllowEmpty { get { return false; } }
  259. protected override object DefaultValue
  260. {
  261. get { return (int)1; }
  262. }
  263. protected override ExpressionType ExType
  264. {
  265. get { return ExpressionType.Divide; }
  266. }
  267. }
  268. class RemForm : BinaryOpForm
  269. {
  270. protected override bool AllowEmpty { get { return false; } }
  271. protected override object DefaultValue
  272. {
  273. get { return (int)1; }
  274. }
  275. protected override ExpressionType ExType
  276. {
  277. get { return ExpressionType.Modulo; }
  278. }
  279. }
  280. abstract class ComparisonForm : BinaryOpForm
  281. {
  282. protected override bool AllowEmpty { get { return false; } }
  283. protected override object DefaultValue
  284. {
  285. get { return null; }
  286. }
  287. protected override void CompileRest(Compiler compiler, ISequence rest, Scope scope, ref Expression result)
  288. {
  289. var vars = new List<ParameterExpression>();
  290. List<Expression> exprs = new List<Expression>();
  291. vars.Add(Expression.Variable(result.Type, "__t0"));
  292. exprs.Add(Expression.Assign(vars[0], result));
  293. while (rest != null)
  294. {
  295. var e = compiler.CompileToExpression(rest.first(), scope);
  296. var v = Expression.Variable(e.Type, "__t" + vars.Count);
  297. vars.Add(v);
  298. exprs.Add(Expression.Assign(v, e));
  299. rest = rest.rest();
  300. }
  301. Expression comparison;
  302. comparison = InternalOp(vars[0], vars[1]);
  303. for (int i = 1; i < vars.Count - 1; i++)
  304. comparison = Expression.AndAlso(comparison, InternalOp(vars[i], vars[i + 1]));
  305. exprs.Add(comparison);
  306. result = Expression.Block(vars, exprs);
  307. }
  308. }
  309. class LtForm : ComparisonForm
  310. {
  311. protected override ExpressionType ExType
  312. {
  313. get { return ExpressionType.LessThan; }
  314. }
  315. }
  316. class GtForm : ComparisonForm
  317. {
  318. protected override ExpressionType ExType
  319. {
  320. get { return ExpressionType.GreaterThan; }
  321. }
  322. }
  323. class LteForm : ComparisonForm
  324. {
  325. protected override ExpressionType ExType
  326. {
  327. get { return ExpressionType.LessThanOrEqual; }
  328. }
  329. }
  330. class GteForm : ComparisonForm
  331. {
  332. protected override ExpressionType ExType
  333. {
  334. get { return ExpressionType.GreaterThanOrEqual; }
  335. }
  336. }
  337. #endregion
  338. class EqualsForm : SpecialFormBase
  339. {
  340. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  341. {
  342. return Utils.SimpleCallHelper(typeof(object).GetMethod("Equals", new Type[] { typeof(object), typeof(object)}),
  343. compiler.CompileToExpression(rest.first(), scope),
  344. compiler.CompileToExpression(rest.rest().first(), scope));
  345. }
  346. }
  347. class NotForm : SpecialFormBase
  348. {
  349. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  350. {
  351. return Expression.Not(IfForm.ToBool(compiler.CompileToExpression(rest.first(), scope)));
  352. }
  353. }
  354. class NotEqualsForm : SpecialFormBase
  355. {
  356. EqualsForm equals = new EqualsForm();
  357. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  358. {
  359. return Expression.Not((Expression)equals.Invoke(compiler, rest, scope));
  360. }
  361. }
  362. class DoForm : SpecialFormBase
  363. {
  364. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  365. {
  366. return CompileDo(compiler, null, rest, null, scope);
  367. }
  368. internal static Expression CompileDo(Compiler compiler, IEnumerable<Expression> pre, ISequence rest, IEnumerable<Expression> post, Scope scope)
  369. {
  370. return CompileDo(compiler, pre, CompileToEnum(compiler, rest, scope), post, scope);
  371. }
  372. internal static Expression CompileDo(Compiler compiler, IEnumerable<Expression> pre, IEnumerable<Expression> block, IEnumerable<Expression> post, Scope scope)
  373. {
  374. var list = new List<Expression>();
  375. if (pre != null) list.AddRange(pre);
  376. if (block != null) list.AddRange(block);
  377. if (post != null) list.AddRange(post);
  378. if (list.Count == 0)
  379. return Expression.Constant(null);
  380. return Expression.Block(list);
  381. }
  382. static IEnumerable<Expression> CompileToEnum(Compiler compiler, ISequence rest, Scope scope)
  383. {
  384. while (rest != null)
  385. {
  386. yield return compiler.CompileToExpression(rest.first(), scope);
  387. rest = rest.rest();
  388. }
  389. }
  390. }
  391. class QuoteForm : SpecialFormBase
  392. {
  393. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  394. {
  395. return Expression.Constant(rest.first());
  396. }
  397. }
  398. class DefForm : SpecialFormBase
  399. {
  400. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  401. {
  402. if (!scope.IsTopLevel)
  403. throw new CompilerException("(def) is only allowed at top-level scope.");
  404. var name = (Symbol)rest.first();
  405. rest = rest.rest();
  406. var var = compiler.CompileToVar(name, true);
  407. if (rest == null)
  408. return var;
  409. var temp = Expression.Variable(var.Type, "temp");
  410. var val = Expression.Variable(var.Type.GetGenericArguments()[0], "val");
  411. return Expression.Block(new[] { temp, val },
  412. Expression.Assign(temp, var),
  413. Expression.Assign(val, Expression.Convert(compiler.CompileToExpression(rest.first(), scope), val.Type)),
  414. Utils.SimpleCallHelper(temp, var.Type.GetMethod("bindRoot"), val),
  415. Utils.SimpleCallHelper(temp, var.Type.GetMethod("setMeta"), Expression.Constant(name.meta())),
  416. temp);
  417. }
  418. }
  419. class TryForm : SpecialFormBase
  420. {
  421. internal static readonly Symbol Catch = Symbol.Create("catch");
  422. internal static readonly Symbol Finally = Symbol.Create("finally");
  423. internal static readonly LabelTarget CatchNullLabel = Expression.Label();
  424. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  425. {
  426. List<Expression> body = new List<Expression>();
  427. List<CatchBlock> catches = new List<CatchBlock>();
  428. Expression @finally = null;
  429. while (rest != null)
  430. {
  431. var first = rest.first();
  432. var call = first as IPersistentList;
  433. rest = rest.rest();
  434. if (call != null)
  435. {
  436. var method = call.peek() as Symbol;
  437. if (Catch.Equals(method))
  438. {
  439. if (@finally != null)
  440. throw new InvalidProgramException("Catches must appear before finally");
  441. BuildCatch(compiler, scope, catches, RT.seq(call));
  442. continue;
  443. }
  444. if (Finally.Equals(method))
  445. {
  446. if (@finally != null)
  447. throw new InvalidProgramException("More than one finally");
  448. @finally = DoForm.CompileDo(compiler, null, RT.seq( call.pop()), null, scope);
  449. continue;
  450. }
  451. }
  452. if (@finally != null || catches.Count > 0)
  453. throw new InvalidProgramException();
  454. body.Add(compiler.CompileToExpression(first, scope));
  455. }
  456. if (body.Count == 0)
  457. return Expression.Constant(null);
  458. Type result = body[body.Count - 1].Type;
  459. if (result == typeof(void))
  460. {
  461. result = typeof(object);
  462. body.Add(Expression.Constant(null));
  463. }
  464. var rvar = Expression.Variable(result, "@tryResult");
  465. var vars = new List<ParameterExpression>();
  466. vars.Add(rvar);
  467. for (int i = 0; i < catches.Count; i++)
  468. {
  469. var cb = catches[i];
  470. if (cb.Body.Type != typeof(void))
  471. {
  472. catches[i] = Expression.Catch(cb.Variable,
  473. Expression.Assign(rvar, Expression.Convert(cb.Body, rvar.Type)));
  474. }
  475. vars.Add(cb.Variable);
  476. }
  477. return Expression.Block(vars,
  478. Expression.TryCatchFinally(
  479. Expression.Assign(rvar, Expression.Block(body)),
  480. @finally,
  481. catches.ToArray()),
  482. rvar);
  483. }
  484. private static void BuildCatch(Compiler compiler, Scope scope, List<CatchBlock> catches, ISequence call)
  485. {
  486. var type = (Symbol)call.rest().first();
  487. var name = (Symbol)call.rest().rest().first();
  488. var cScope = new Scope(scope);
  489. // make sure we can't recur from in a catch out of the catch
  490. cScope.LoopLabel = CatchNullLabel;
  491. cScope.LoopVariables = new List<Expression>();
  492. var ex = Expression.Variable(Compiler.FindType(type), name.Name);
  493. cScope[name] = ex;
  494. catches.Add(Expression.Catch(
  495. ex,
  496. DoForm.CompileDo(compiler, null, call.rest().rest().rest(), null, cScope)));
  497. }
  498. }
  499. class BindingForm : SpecialFormBase
  500. {
  501. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  502. {
  503. List<Expression> vars = new List<Expression>();
  504. List<Expression> values = new List<Expression>();
  505. BuildVarsAndValues(compiler, (PersistentVector)rest.first(), vars, values, scope);
  506. var body = DoForm.CompileDo(compiler, values, rest.rest(), null, scope);
  507. var result = Expression.Variable(body.Type, "bindingResult");
  508. return Expression.Block( new [] { result },
  509. Utils.SimpleCallHelper(typeof(VarBase).GetMethod("PushThreadBindings"), Expression.NewArrayInit(typeof(VarBase), vars), Expression.NewArrayInit(typeof(object), values)),
  510. Expression.TryFinally(
  511. Expression.Assign(result, body),
  512. Utils.SimpleCallHelper(typeof(VarBase).GetMethod("PopThreadBindings"))),
  513. result);
  514. }
  515. public static void BuildVarsAndValues(Compiler compiler, IList vector, List<Expression> vars, List<Expression> values, Scope scope)
  516. {
  517. for (int i = 0; i < vector.Count; i+=2)
  518. {
  519. var sym = (Symbol)vector[i];
  520. var val = vector[i + 1];
  521. var var = compiler.CompileToVar(sym, false);
  522. var value = compiler.CompileToExpression(val, scope);
  523. vars.Add(var);
  524. values.Add(value);
  525. }
  526. }
  527. }
  528. class LetForm : SpecialFormBase
  529. {
  530. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  531. {
  532. scope = new Scope(scope);
  533. List<Expression> vars = new List<Expression>();
  534. List<Expression> assigns = new List<Expression>();
  535. BuildVariablesAndAssignments(compiler, (PersistentVector)rest.first(), vars, assigns, scope);
  536. return Expression.Block(
  537. from v in vars select (ParameterExpression)v,
  538. DoForm.CompileDo(compiler, assigns, rest.rest(), null, scope));
  539. }
  540. public static void BuildVariablesAndAssignments(Compiler compiler, IList vector, List<Expression> vars, List<Expression> assigns, Scope scope)
  541. {
  542. for (int i = 0; i < vector.Count; i += 2)
  543. {
  544. var sym = (Symbol)vector[i];
  545. var val = vector[i + 1];
  546. var value = compiler.CompileToExpression(val, scope);
  547. var varexp = Expression.Variable(value.Type, sym.ToString());
  548. scope[sym] = varexp;
  549. vars.Add(varexp);
  550. assigns.Add(Expression.Assign(varexp, value));
  551. }
  552. }
  553. }
  554. class IfForm : SpecialFormBase
  555. {
  556. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  557. {
  558. var cond = compiler.CompileToExpression(rest.first(), scope); rest=rest.rest();
  559. var t = compiler.CompileToExpression(rest.first(), scope); rest=rest.rest();
  560. Expression f;
  561. if (rest == null)
  562. f = Expression.Constant(null);
  563. else
  564. f = compiler.CompileToExpression(rest.first(),scope);
  565. Type result = t.Type;
  566. if (result != f.Type)
  567. result = typeof(object);
  568. if (result == typeof(void))
  569. result = typeof(object);
  570. return Expression.Condition(ToBool(cond), Wrap(result, t), Wrap(result, f));
  571. }
  572. private Expression Wrap(Type result, Expression e)
  573. {
  574. if (e.Type == typeof(void))
  575. return Expression.Block(e, Expression.Constant(null));
  576. return Expression.Convert(e, result);
  577. }
  578. internal static Expression ToBool(Expression cond)
  579. {
  580. if (cond.Type == typeof(bool))
  581. return cond;
  582. var temp = Expression.Variable(typeof(object), "temp");
  583. return Expression.Block(new[] { temp },
  584. Expression.Assign(temp, Expression.Convert(cond, typeof(object))),
  585. Expression.Not(Expression.Or(
  586. Expression.Equal(Expression.Constant(null), temp),
  587. Expression.Call(Expression.Constant(false), "Equals", new Type[0], temp))
  588. ));
  589. }
  590. }
  591. class NewForm : SpecialFormBase
  592. {
  593. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  594. {
  595. var symbol = (Symbol)rest.first();
  596. var t = Compiler.FindType(symbol);
  597. if (t == null)
  598. throw new System.TypeLoadException(symbol.ToString());
  599. var args = compiler.CompileArguments(rest.rest(), scope);
  600. args = ArrayUtils.Insert(Expression.Constant(t.FullName), args);
  601. return Expression.Dynamic(BinderFactory.New(symbol.meta(), t), t, args);
  602. }
  603. }
  604. class InNsForm : SpecialFormBase
  605. {
  606. protected override Expression Compile(Compiler compiler, ISequence rest, Scope scope)
  607. {
  608. return Utils.SimpleCallHelper(
  609. Expression.Constant(Namespace.CurrentNs),
  610. Namespace.CurrentNs.GetType().GetMethod("set"),
  611. Utils.SimpleCallHelper(typeof(Namespace).GetMethod("findOrCreate"),
  612. Expression.Convert(compiler.CompileToExpression(rest.first(), scope), typeof(Symbol))));
  613. }
  614. }
  615. }
  616. }