예제 #1
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 2)
         throw new ArgumentException("Unproperly formated cast expression");
     engine.CompileExpr(il, locals, st, args[0]);
     Type type = args[1] as Type;
     if (type == null)
         throw new ArgumentException("Expecting type value");
     Type curr_type = st.Pop();
     if (curr_type.IsValueType)
     {
         if (type == typeof(System.Object))
             il.EmitBoxing(curr_type);
         else if (curr_type != type)
             throw new InvalidCastException();
     }
     else
     {
         il.Emit(OpCodes.Isinst, type);
         il.Emit(OpCodes.Dup);
         Label ok = il.DefineLabel();
         il.Emit(OpCodes.Brtrue_S, ok);
         il.EmitCall(_raiseInvalidCast);
         il.MarkLabel(ok);
         if (type.IsValueType)
             il.EmitUnbox(type);
     }
     st.Push(type);
 }
예제 #2
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 1)
         throw new ArgumentException("Unproperly formated expression");
     for (int k = 0; k < st.Count; k++)
         il.Emit(OpCodes.Pop);
     engine.CompileExpr(il, locals, st, args[0]);
     st.Pop();
     il.Emit(OpCodes.Ret);
     st.Push(typeof(System.Object));
 }
예제 #3
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length != 2)
         throw new ArgumentException("Unproperly formated expression");
     engine.CompileExpr(il, locals, st, args[0]);
     if (st.Pop() != typeof(System.Object))
         throw new ArgumentException("Expecting boolean value");
     Label l_false = il.DefineLabel();            
     il.Emit(OpCodes.Brfalse, l_false);
     engine.CompileExpr(il, locals, st, args[1]);
     if (st.Pop() != typeof(System.Object))
         throw new ArgumentException("Expecting boolean value");
     Label end = il.DefineLabel();
     il.Emit(OpCodes.Brfalse_S, l_false);
     il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
     il.Emit(OpCodes.Br_S, end);
     il.MarkLabel(l_false);
     il.EmitNull();
     il.MarkLabel(end);
     st.Push(typeof(System.Object));
 }
예제 #4
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     for (int k = 0; k < args.Length; k++)
     {
         engine.CompileExpr(il, locals, st, args[k]);
         if (k > 0)
         {
             st.Pop();
             il.Emit(OpCodes.Pop);
         }
     }
 }
예제 #5
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     locals.EnterScope(form, _activeScope);
     foreach (object arg in Lisp.getIterator(args[0]))
     {
         object[] pair = Lisp.ToArray(arg);
         engine.CompileExpr(il, locals, st, pair[1]);
         LocalBuilder localvar = locals.BindLocal(pair[0], st.Pop());
         il.Emit(OpCodes.Stloc, localvar);
     }
     if (!_activeScope)
         locals.ActivateScope();
     for (int k = 1; k < args.Length; k++)
     {
         engine.CompileExpr(il, locals, st, args[k]);
         if (k < args.Length - 1)
         {
             st.Pop();
             il.Emit(OpCodes.Pop);
         }
     }
     locals.DestroyScope();
 }
예제 #6
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     if (args.Length < 2)
         throw new ArgumentException();
     engine.CompileExpr(il, locals, st, args[0]);
     Type inst = st.Pop();
     il.Emit(OpCodes.Castclass, inst);
     String name = args[1].ToString();
     MethodInfo methodInfo;
     if (args.Length > 2)
     {
         Type[] parameters = new Type[args.Length - 2];
         ParameterModifier modifier = new ParameterModifier(parameters.Length);
         LocalBuilder[] localVar = new LocalBuilder[parameters.Length];
         for (int k = 0; k < args.Length - 2; k++)
         {
             engine.CompileExpr(il, locals, st, args[k + 2]);
             parameters[k] = st.Pop();
             localVar[k] = il.DeclareLocal(parameters[k]);
             il.Emit(OpCodes.Stloc, localVar[k]);
         }
         methodInfo = inst.GetMethod(name, parameters, new ParameterModifier[] { modifier });
         if (methodInfo == null)
             throw new ArgumentException("Method not found in class", name);
         ParameterInfo[] pi = methodInfo.GetParameters();
         for (int k = 0; k < pi.Length; k++)
         {
             il.Emit(OpCodes.Ldloc, localVar[k]);
             if (pi[k].ParameterType != parameters[k] && parameters[k].IsValueType)
                 il.Emit(OpCodes.Box, parameters[k]);
             il.FreeLocal(localVar[k]);
         }
     }
     else
     {
         methodInfo = inst.GetMethod(name, null);
         if (methodInfo == null)
             throw new ArgumentException("Method not found in class", name);
     }
     il.Emit(OpCodes.Callvirt, methodInfo);
     Type resType = methodInfo.GetReturnType();
     if (resType == typeof(System.Boolean))
     { // Implict boolean convertion
         Label l_false = il.DefineLabel();
         Label end = il.DefineLabel();
         il.Emit(OpCodes.Brfalse_S, l_false);
         il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
         il.Emit(OpCodes.Br_S, end);
         il.MarkLabel(l_false);
         il.EmitNull();
         il.MarkLabel(end);
         st.Push(typeof(System.Object));
     }
     else if (resType == typeof(void))
     { // assume that all procedures returns t
         il.Emit(OpCodes.Ldsfld, typeof(RuntimeOps).GetField("True"));
         st.Push(typeof(System.Object));
     }
     else
         st.Push(resType);
 }
예제 #7
0
 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     Type resType = null;
     List<Branch> branches = new List<Branch>();
     for (int k = 0; k < args.Length; k++)
     {
         Label next = il.DefineLabel();
         object cur = args[k];
         if (!Lisp.IsCons(cur))
             throw new ArgumentException("Unproperly formated expression");
         object[] pair = Lisp.ToArray(cur);
         if (pair.Length != 2)
             throw new ArgumentException("Unproperly formated expression");
         engine.CompileExpr(il, locals, st, pair[0]);
         if (st.Pop() != typeof(System.Object))
             throw new ArgumentException("Expecting boolean value");
         il.Emit(OpCodes.Brfalse, next);
         engine.CompileExpr(il, locals, st, pair[1]);
         Type type = st.Pop();
         Branch branch = GetBranch(branches, il, type);
         il.Emit(OpCodes.Stloc, branch.localVar);
         il.Emit(OpCodes.Br, branch.handler);
         il.MarkLabel(next);
         if (resType == null)
             resType = type;
         else
             if (resType != type)
                 resType = typeof(System.Object);
     }
     il.EmitCall(_raiseError);
     Label end = il.DefineLabel();
     for (int k = 0; k < branches.Count; k++)
     {
         Branch b = branches[k];
         il.MarkLabel(b.handler);
         il.Emit(OpCodes.Ldloc, b.localVar);
         il.FreeLocal(b.localVar);
         if (resType != b.type)
         {
             if (ValueProxy.IsProxyType(b.type))
                 il.EmitPropertyGet(typeof(ValueProxy), "Value");
             else if (b.type.IsValueType)
                 il.Emit(OpCodes.Box, b.type);
         }
         if (k < branches.Count -1)
             il.Emit(OpCodes.Br, end);                
     }
     il.MarkLabel(end);
     st.Push(resType);
 }