예제 #1
0
        public Value Invoke(Value self, RubyContext context, IList <Value> values)
        {
            RubyContext newContext = context.VM.NewContext(context.VM.rb_obj_ptr(self), this.context);

            int k = 0;

            // int cv = values.Count;

            foreach (var parameter in parameters.args)
            {
                switch (parameter.type)
                {
                case AstNodeType.CONST:
                case AstNodeType.LVAR:
                case AstNodeType.SYM:
                    newContext.SetLocalValue(
                        (parameter as INamedNode).name,
                        context.VM.GetArg <Value> (values, k)
                        );
                    k++;
                    break;

                default:
                    Console.WriteLine($"DefinedFunction::Invoke param type: {parameter.type} 未实现");
                    break;
                }
            }

            // if ( isConstructor ) {
            //  body.Evaluate ( newContext );
            //  return self;
            // }

            return(body.Evaluate(newContext));
        }
예제 #2
0
        public override Value Evaluate(RubyContext context)
        {
#if DEBUG
            context.VM.CurrentEvalNode = this;
#endif

            for (Value value = cond.Evaluate(context); value; value = cond.Evaluate(context))
            {
                body.Evaluate(context);
            }

            return(null);
        }
예제 #3
0
        public Value Invoke(Value self, RubyContext context, IList <Value> values)
        {
            if (argumentNames == null || argumentNames.args.Count == 0)
            {
                return(body.Evaluate(this.context));
            }

            RubyBlockContext blockContext = context.VM.NewBlockContext(context.Self, context);

            for (int k = 0; k < argumentNames.args.Count; k++)
            {
                if (values != null && k < values.Count)
                {
                    blockContext.SetLocalValue((( INamedNode )argumentNames.args[k]).name, values[k]);
                }
                else
                {
                    blockContext.SetLocalValue((( INamedNode )argumentNames.args[k]).name, Value.Nil());
                }
            }

            return(body.Evaluate(blockContext));
        }
예제 #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);
        }