Пример #1
0
        protected virtual void _Generate(AstNodeStmAssign assign)
        {
            var astNodeExprSetGetLValue = assign.LeftValue as AstNodeExprSetGetLValue;

            if (astNodeExprSetGetLValue != null)
            {
                PlaceholderStack.Push(assign.Value);
                Generate(astNodeExprSetGetLValue.SetExpression);
                Output.Write(";");
            }
            else
            {
                Generate(assign.LeftValue);
                Output.Write(" = ");
                Generate(assign.Value);
                Output.Write(";");
            }
        }
        // @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
        }