Пример #1
0
        public static RObject CreateUserdataRObject(VM vm, RClass @class, object userdata)
        {
            var obj = new RObject();

            obj.vm     = vm;
            obj.type   = ValueType.Data;
            obj.@class = @class;
            obj.SetIV(VM.FIELD_USERDATA, Value.Ptr(userdata));
            return(obj);
        }
Пример #2
0
        public override Value Evaluate(RubyContext context)
        {
#if DEBUG
            context.VM.CurrentEvalNode = this;
#endif

            RClass cls = car.Evaluate(context).As <RClass> ();
            if (cls != null)
            {
                if (cls.constants.HasLocalValue((( INamedNode )cdr).name))
                {
                    return(cls.constants.GetLocalValue((( INamedNode )cdr).name));
                }
            }

            return(null);
        }
Пример #3
0
 internal RubyContext(RClass module, RubyContext parent)
 {
     this.module = module;
     this.parent = parent;
     self        = module;
 }
Пример #4
0
        public override Value Evaluate(RubyContext context)
        {
#if DEBUG
            context.VM.CurrentEvalNode = this;
#endif

            string name   = AstParser.GetNamePathFinalName(this.name);
            RClass target = (context.Self is RClass) ? ( RClass )context.Self : null;
            Value  value  = null;

            if (context.Module != null)
            {
                if (context.Module.constants.HasLocalValue(name))
                {
                    value = context.Module.constants.GetLocalValue(name);
                }
            }
            else if (context.HasValue(name))
            {
                value = context.GetValue(name);
            }

            if (value == null || !(value is RClass))
            {
                var classclass = context.RootContext.GetLocalValue("Class").As <RClass> ();
                var superclass = context.RootContext.GetLocalValue("Object").As <RClass> ();
                var parent     = target == null ? context.Module : target;

                if (super != null)
                {
                    superclass = super.Evaluate(context)?.As <RClass> ();
                    if (superclass == null)
                    {
                        VM.ThrowException($"superclass '{super}' not found.");
                    }
                }

                var newclass = context.VM.DefClass(classclass, name, superclass, parent);
                value = Value.Class(newclass);

                if (context.VM.IsCustomClass(superclass))
                {
                    context.VM.WriteCustomClassFlag(newclass, context.VM.GetCustomClassType(superclass));
                    context.VM.WriteCustomClassRClass(newclass, context.VM.GetCustomClassRClass(superclass));
                }

                if (parent == null)
                {
                    context.RootContext.SetLocalValue(name, value);
                }
                else
                {
                    parent.constants.SetLocalValue(name, value);
                }
            }

            var dclass = value.As <RClass> ();

            RubyContext classcontext = context.VM.NewContext(dclass, context);

            body.Evaluate(classcontext);

            return(null);
        }
Пример #5
0
 internal void SetClass(RClass @class)
 {
     this.@class = @class;
 }
Пример #6
0
        public static RClass RegCustomClass(VM vm, Type type)
        {
            // Console.WriteLine ( $"Namespace: {type.Namespace}" );
            // Console.WriteLine ( $"FullName: {type.FullName}" );

            RClass @class = null;

            string[] namespacePath = type.FullName.Split('.');
            foreach (var className in namespacePath)
            {
                if (className.Equals(namespacePath[0]))
                {
                    @class = vm.DefClass(className, vm.object_class);
                }
                else
                {
                    @class = vm.DefClass(className, vm.object_class, @class);
                }
            }

            vm.WriteCustomClassFlag(@class, type);
            vm.WriteCustomClassRClass(@class, @class);

            ConstructorInfo      publicCtor          = type.Constructors(Flags.InstancePublic).OrderBy(c => c.GetParameters().Length).FirstOrDefault();
            IList <FieldInfo>    publicStaticFields  = type.Fields(Flags.StaticPublicDeclaredOnly);
            IList <FieldInfo>    publicFields        = type.Fields(Flags.InstancePublic);
            IList <PropertyInfo> publicPropertys     = type.Properties(Flags.InstancePublic);
            IList <MethodInfo>   publicMethods       = type.Methods(Flags.InstancePublic);
            IList <MethodInfo>   publicStaticMethods = type.Methods(Flags.StaticPublic);

            if (publicCtor != null)
            {
                @class.SetInstanceMethod(VM.INITIALIZE, GenCtor(publicCtor));
            }

            foreach (var field in publicStaticFields)
            {
                @class.SetInstanceMethod(field.Name, GenGetField(field));
            }

            foreach (var field in publicFields)
            {
                @class.SetInstanceMethod(field.Name, GenGetField(field));
                @class.SetInstanceMethod($"{field.Name}=", GenSetField(field));
            }

            foreach (var property in publicPropertys)
            {
                if (property.CanRead)
                {
                    @class.SetInstanceMethod(property.Name, GenGetProperty(property));
                }

                if (property.CanWrite)
                {
                    @class.SetInstanceMethod($"{property.Name}=", GenSetProperty(property));
                }
            }

            foreach (var method in publicMethods)
            {
                @class.SetInstanceMethod(method.Name, GenMethod(method));
            }

            //foreach ( var method in publicStaticMethods ) {
            //	@class.SetClassMethod ( method.Name, GenMethod ( method, true ) );
            //}

            foreach (var kv in operator_methods)
            {
                Gen_BaseOp_IfExist(type, @class, kv.Key);
            }

            @class.SetInstanceMethod(VM.TO_S, GenToString(type.Method("ToString", Type.EmptyTypes)));
            @class.SetInstanceMethod(VM.TO_STR, GenToString(type.Method("ToString", Type.EmptyTypes)));

            return(@class);
        }
Пример #7
0
        public static Func <Value, RubyContext, IList <Value>, Value> Gen_BaseOp_IfExist(Type type, RClass @class, string op)
        {
            var methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public)
                             .Where(m => {
                if (!m.Name.Equals(op))
                {
                    return(false);
                }
                var parameters = m.GetParameters();
                if (parameters.Length != 2)
                {
                    return(false);
                }
                if (parameters[0].ParameterType != type)
                {
                    return(false);
                }
                return(true);
            }).FirstOrDefault();

            if (methodInfo != null)
            {
                Func <Value, RubyContext, IList <Value>, Value> func = (self, context, values) => {
                    object   userdata   = (( RObject )self.p).GetIV(VM.FIELD_USERDATA).p;
                    object[] parameters = new [] {
                        userdata,
                        context.VM.ValueToObject(context.VM.GetArg <Value> (values, 0))
                    };

                    object ret = methodInfo.Invoke(null, parameters);
                    if (ret == null)
                    {
                        return(Value.Nil());
                    }
                    if (ret.GetType() == typeof(int))
                    {
                        return(Value.Fixnum(( int )ret));
                    }
                    if (ret.GetType() == typeof(float))
                    {
                        return(Value.Float(( float )ret));
                    }
                    if (ret.GetType() == typeof(bool))
                    {
                        return(Value.Bool(( bool )ret));
                    }
                    if (ret.GetType() == typeof(string))
                    {
                        return(Value.Str(( string )ret));
                    }
                    return(Value.Data(RObject.CreateUserdataRObject(context.VM, context.VM.FindCustomClass(ret), ret)));
                };

                @class.SetInstanceMethod(operator_methods[op], func);

                return(func);
            }

            return(null);
        }