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); }
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)); }
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)); }
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); } } }
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(); }
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); }
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); }