// @TODO: Rewrite using C# 7 features protected virtual void _Generate(AstNodeStmAssign assign) { //Assign.Local.LocalBuilder.LocalIndex var astNodeExprLocal = assign.LeftValue as AstNodeExprLocal; var astNodeExprArgument = assign.LeftValue as AstNodeExprArgument; var astNodeExprFieldAccess = assign.LeftValue as AstNodeExprFieldAccess; var astNodeExprStaticFieldAccess = assign.LeftValue as AstNodeExprStaticFieldAccess; var astNodeExprIndirect = assign.LeftValue as AstNodeExprIndirect; var astNodeExprArrayAccess = assign.LeftValue as AstNodeExprArrayAccess; var astNodeExprPropertyAccess = assign.LeftValue as AstNodeExprPropertyAccess; var astNodeExprSetGetLValue = assign.LeftValue as AstNodeExprSetGetLValue; if (astNodeExprLocal != null) { Generate(assign.Value); Emit(OpCodes.Stloc, _GetLocalBuilderFromAstLocal(astNodeExprLocal.AstLocal)); } else if (astNodeExprArgument != null) { Generate(assign.Value); Emit(OpCodes.Starg, astNodeExprArgument.AstArgument.Index); } else if (astNodeExprFieldAccess != null) { Generate(astNodeExprFieldAccess.Instance); Generate(assign.Value); Emit(OpCodes.Stfld, astNodeExprFieldAccess.Field); } else if (astNodeExprStaticFieldAccess != null) { Generate(assign.Value); Emit(OpCodes.Stsfld, astNodeExprStaticFieldAccess.Field); } else if (astNodeExprArrayAccess != null) { Generate(astNodeExprArrayAccess.ArrayInstance); Generate(astNodeExprArrayAccess.Index); Generate(assign.Value); Emit(OpCodes.Stelem, astNodeExprArrayAccess.ArrayInstance.Type.GetElementType()); } else if (astNodeExprIndirect != null) { var pointerType = AstUtils.GetSignedType(astNodeExprIndirect.PointerExpression.Type.GetElementType()); Generate(astNodeExprIndirect.PointerExpression); Generate(assign.Value); if (pointerType == typeof(sbyte)) { Emit(OpCodes.Stind_I1); } else if (pointerType == typeof(short)) { Emit(OpCodes.Stind_I2); } else if (pointerType == typeof(int)) { Emit(OpCodes.Stind_I4); } else if (pointerType == typeof(long)) { Emit(OpCodes.Stind_I8); } else if (pointerType == typeof(float)) { Emit(OpCodes.Stind_R4); } else if (pointerType == typeof(double)) { Emit(OpCodes.Stind_R8); } else if (pointerType == typeof(bool)) { Emit(OpCodes.Stind_I1); } else { throw new NotImplementedException("Can't store indirect value"); } } else if (astNodeExprPropertyAccess != null) { Generate(astNodeExprPropertyAccess.Instance); Generate(assign.Value); Emit(OpCodes.Callvirt, astNodeExprPropertyAccess.Property.SetMethod); } else if (astNodeExprSetGetLValue != null) { _placeholderStack.Push(assign.Value); Generate(astNodeExprSetGetLValue.SetExpression); if (astNodeExprSetGetLValue.SetExpression.Type != typeof(void)) { Emit(OpCodes.Pop); } } else { throw new NotImplementedException("Not implemented AstNodeStmAssign LValue: " + assign.LeftValue.GetType()); } //Assign.Local }
protected virtual void _Generate(AstNodeExprImm item) { var itemType = AstUtils.GetSignedType(item.Type); var itemValue = item.Value; if (itemType.IsEnum) { itemType = itemType.GetEnumUnderlyingType(); itemValue = AstUtils.CastType(itemValue, itemType); } if ( itemType == typeof(int) || itemType == typeof(sbyte) || itemType == typeof(short) || itemType == typeof(bool) ) { var value = (int)Convert.ToInt64(itemValue); switch (value) { case -1: Emit(OpCodes.Ldc_I4_M1); break; case 0: Emit(OpCodes.Ldc_I4_0); break; case 1: Emit(OpCodes.Ldc_I4_1); break; case 2: Emit(OpCodes.Ldc_I4_2); break; case 3: Emit(OpCodes.Ldc_I4_3); break; case 4: Emit(OpCodes.Ldc_I4_4); break; case 5: Emit(OpCodes.Ldc_I4_5); break; case 6: Emit(OpCodes.Ldc_I4_6); break; case 7: Emit(OpCodes.Ldc_I4_7); break; case 8: Emit(OpCodes.Ldc_I4_8); break; default: Emit(OpCodes.Ldc_I4, value); break; } } else if (itemType == typeof(long) || itemType == typeof(ulong)) { Emit(OpCodes.Ldc_I8, Convert.ToInt64(itemValue)); } else if (itemType == typeof(IntPtr)) { #if false Emit(OpCodes.Ldc_I8, ((IntPtr)Item.Value).ToInt64()); Emit(OpCodes.Conv_I); #else if (Environment.Is64BitProcess) { Emit(OpCodes.Ldc_I8, ((IntPtr)item.Value).ToInt64()); Emit(OpCodes.Conv_I); } else { Emit(OpCodes.Ldc_I4, ((IntPtr)item.Value).ToInt32()); Emit(OpCodes.Conv_I); } #endif } else if (itemType == typeof(float)) { Emit(OpCodes.Ldc_R4, (float)item.Value); } else if (item.Value == null) { Emit(OpCodes.Ldnull); } else if (itemType == typeof(string)) { Emit(OpCodes.Ldstr, (string)item.Value); } else if (itemType == typeof(Type)) { Emit(OpCodes.Ldtoken, (Type)item.Value); Emit(OpCodes.Call, ((Func <RuntimeTypeHandle, Type>)Type.GetTypeFromHandle).Method); //IL_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) } else { throw new NotImplementedException($"Can't handle immediate type {itemType}"); } }