Beispiel #1
0
        private AstParameters /*!*/ DefineParameters(out MSA.ParameterExpression /*!*/ selfVariable, out MSA.ParameterExpression /*!*/ blockParamVariable)
        {
            var parameters = new AstParameters(
                HiddenParameterCount +
                (HasFormalParametersInArray ? 1 : _parameters.LeftValues.Count) +
                (HasUnsplatParameter ? 1 : 0)
                );

            // hidden parameters:
            // #proc must be the first one - it is used as instance target for method invocation:
            parameters.Add(blockParamVariable = Ast.Parameter(typeof(BlockParam), "#proc"));
            parameters.Add(selfVariable       = Ast.Parameter(typeof(object), "#self"));

            if (HasFormalParametersInArray)
            {
                parameters.Add(Ast.Parameter(typeof(object[]), "#parameters"));
            }
            else
            {
                for (int i = 0; i < _parameters.LeftValues.Count; i++)
                {
                    parameters.Add(Ast.Parameter(typeof(object), "#" + i));
                }
            }

            if (HasUnsplatParameter)
            {
                parameters.Add(Ast.Parameter(typeof(RubyArray), "#array"));
            }

            return(parameters);
        }
Beispiel #2
0
        private ScopeBuilder /*!*/ DefineLocals(out AstParameters /*!*/ parameters)
        {
            parameters = new AstParameters(
                HiddenParameterCount +
                (_parameters.Mandatory != null ? _parameters.Mandatory.Count : 0) +
                (_parameters.Optional != null ? _parameters.Optional.Count : 0) +
                (_parameters.Array != null ? 1 : 0)
                );

            int closureIndex      = 0;
            int firstClosureParam = 1;

            parameters.Add(Ast.Parameter(typeof(object), "#self"));

            if (_parameters.Block != null)
            {
                parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name));
                _parameters.Block.SetClosureIndex(closureIndex++);
            }
            else
            {
                parameters.Add(Ast.Parameter(typeof(Proc), "#block"));
                firstClosureParam++;
            }

            if (_parameters.Mandatory != null)
            {
                foreach (var param in _parameters.Mandatory)
                {
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                }
            }

            if (_parameters.Optional != null)
            {
                foreach (var lvalue in _parameters.Optional)
                {
                    var param = (LocalVariable)lvalue.Left;
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                }
            }

            if (_parameters.Array != null)
            {
                parameters.Add(Ast.Parameter(typeof(object), _parameters.Array.Name));
                _parameters.Array.SetClosureIndex(closureIndex++);
            }

            // allocate closure slots for locals:
            int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex);

            return(new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope));
        }
Beispiel #3
0
        public ScopeBuilder(AstParameters parameters, int firstClosureParam, int localCount, 
            ScopeBuilder parent, LexicalScope/*!*/ lexicalScope) {
            Debug.Assert(parent == null || parent.LexicalScope == lexicalScope.OuterScope);
#if DEBUG
            _id = Interlocked.Increment(ref _Id);
#endif
            _parent = parent;
            _parameters = parameters;
            _localCount = localCount;
            _firstClosureParam = firstClosureParam;
            _lexicalScope = lexicalScope;
            _hiddenVariables = new AstParameters();
            _localsTuple = DefineHiddenVariable("#locals", MakeLocalsTupleType());
            _outermostClosureReferredTo = this;
        }
        public ScopeBuilder(AstParameters parameters, int firstClosureParam, int localCount,
                            ScopeBuilder parent, LexicalScope /*!*/ lexicalScope)
        {
            Debug.Assert(parent == null || parent.LexicalScope == lexicalScope.OuterScope);
#if DEBUG
            _id = Interlocked.Increment(ref _Id);
#endif
            _parent                     = parent;
            _parameters                 = parameters;
            _localCount                 = localCount;
            _firstClosureParam          = firstClosureParam;
            _lexicalScope               = lexicalScope;
            _hiddenVariables            = new AstParameters();
            _localsTuple                = DefineHiddenVariable("#locals", MakeLocalsTupleType());
            _outermostClosureReferredTo = this;
        }
Beispiel #5
0
        private ScopeBuilder/*!*/ DefineLocals(out AstParameters/*!*/ parameters) {
            parameters = new AstParameters(
                HiddenParameterCount +
                (_parameters.Mandatory != null ? _parameters.Mandatory.Count : 0) +
                (_parameters.Optional != null ? _parameters.Optional.Count : 0) +
                (_parameters.Array != null ? 1 : 0)
            );

            int closureIndex = 0;
            int firstClosureParam = 1;
            parameters.Add(Ast.Parameter(typeof(object), "#self"));

            if (_parameters.Block != null) {
                parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name));
                _parameters.Block.SetClosureIndex(closureIndex++);
            } else {
                parameters.Add(Ast.Parameter(typeof(Proc), "#block"));
                firstClosureParam++;
            }

            if (_parameters.Mandatory != null) {
                foreach (var param in _parameters.Mandatory) {
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                }
            }

            if (_parameters.Optional != null) {
                foreach (var lvalue in _parameters.Optional) {
                    var param = (LocalVariable)lvalue.Left;
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                }
            }

            if (_parameters.Array != null) {
                parameters.Add(Ast.Parameter(typeof(object), _parameters.Array.Name));
                _parameters.Array.SetClosureIndex(closureIndex++);
            }

            // allocate closure slots for locals:
            int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex);

            return new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope);
        }
Beispiel #6
0
        private AstParameters /*!*/ DefineParameters(out MSA.ParameterExpression /*!*/ selfVariable, out MSA.ParameterExpression /*!*/ blockParamVariable)
        {
            // Block signature:
            // <proc>, <self>, <leading-mandatory>, <trailing-mandatory>, <optional>, &<block>, *<unsplat>
            // or
            // <proc>, <self>, object[] { <leading-mandatory>, <trailing-mandatory>, <optional>, &<block> } *<unsplat>,
            var parameters = new AstParameters(
                HiddenParameterCount +
                (HasFormalParametersInArray ? 1 : ParameterCount) +
                (HasUnsplatParameter ? 1 : 0) +
                (HasProcParameter ? 1 : 0)
                );

            // hidden parameters:
            // #proc must be the first one - it is used as instance target for method invocation:
            parameters.Add(blockParamVariable = Ast.Parameter(typeof(BlockParam), "#bp"));
            parameters.Add(selfVariable       = Ast.Parameter(typeof(object), "#self"));

            if (HasFormalParametersInArray)
            {
                parameters.Add(Ast.Parameter(typeof(object[]), "#parameters"));
            }
            else
            {
                for (int i = 0; i < ParameterCount; i++)
                {
                    parameters.Add(Ast.Parameter(typeof(object), "#" + i));
                }
            }

            if (HasUnsplatParameter)
            {
                parameters.Add(Ast.Parameter(typeof(RubyArray), "#array"));
            }

            if (HasProcParameter)
            {
                parameters.Add(Ast.Parameter(typeof(Proc), "#proc"));
            }

            return(parameters);
        }
Beispiel #7
0
        private static MSA.LambdaExpression /*!*/ CreateLambda(string /*!*/ name, AstParameters /*!*/ parameters, MSA.Expression /*!*/ body)
        {
            var result = MethodDispatcher.CreateRubyMethodLambda(body, name, parameters);

            if (result != null)
            {
                return(result);
            }

            // to many parameters for Func<> delegate -> use object[]:
            MSA.ParameterExpression array = Ast.Parameter(typeof(object[]), "#params");
            var actualParameters          = new AstParameters()
            {
                parameters[0], parameters[1], array
            };

            parameters.RemoveAt(0);
            parameters.RemoveAt(1);

            var bodyWithParamInit = new AstExpressions(parameters.Count + 1);

            for (int i = 0; i < parameters.Count; i++)
            {
                bodyWithParamInit[i] = Ast.Assign(parameters[i], Ast.ArrayIndex(array, AstUtils.Constant(i)));
            }
            bodyWithParamInit[parameters.Count] = body;

            return(Ast.Lambda <Func <object, Proc, object[], object> >(
                       Ast.Block(
                           parameters,
                           bodyWithParamInit
                           ),
                       name,
                       actualParameters
                       ));
        }
Beispiel #8
0
        private static MSA.LambdaExpression/*!*/ CreateLambda(string/*!*/ name, AstParameters/*!*/ parameters, MSA.Expression/*!*/ body) {
            var result = MethodDispatcher.CreateRubyMethodLambda(body, name, parameters);
            if (result != null) {
                return result;
            } 

            // to many parameters for Func<> delegate -> use object[]:
            MSA.ParameterExpression array = Ast.Parameter(typeof(object[]), "#params");
            var actualParameters = new AstParameters() { parameters[0], parameters[1], array };
            parameters.RemoveAt(0);
            parameters.RemoveAt(1);

            var bodyWithParamInit = new AstExpressions(parameters.Count + 1);
            for (int i = 0; i < parameters.Count; i++) {
                bodyWithParamInit[i] = Ast.Assign(parameters[i], Ast.ArrayIndex(array, AstUtils.Constant(i)));
            }
            bodyWithParamInit[parameters.Count] = body;

            return Ast.Lambda<Func<object, Proc, object[], object>>(
                Ast.Block(
                    parameters, 
                    bodyWithParamInit
                ),
                name,
                actualParameters
            );
        }
Beispiel #9
0
        private MSA.Expression /*!*/ MakeParametersInitialization(AstGenerator /*!*/ gen, AstParameters /*!*/ parameters)
        {
            var result = new AstExpressions(
                _parameters.LeftValues.Count +
                (_parameters.UnsplattedValue != null ? 1 : 0) +
                1
                );

            bool paramsInArray = HasFormalParametersInArray;

            for (int i = 0; i < _parameters.LeftValues.Count; i++)
            {
                var parameter = paramsInArray ? (MSA.Expression)
                                Ast.ArrayAccess(parameters[HiddenParameterCount], AstUtils.Constant(i)) :
                                parameters[HiddenParameterCount + i];

                result.Add(_parameters.LeftValues[i].TransformWrite(gen, parameter));
            }

            if (_parameters.UnsplattedValue != null)
            {
                // the last parameter is unsplat:
                var parameter = parameters[parameters.Count - 1];
                result.Add(_parameters.UnsplattedValue.TransformWrite(gen, parameter));
            }

            result.Add(AstUtils.Empty());
            return(Ast.Block(result));
        }
Beispiel #10
0
        private AstParameters/*!*/ DefineParameters(out MSA.ParameterExpression/*!*/ selfVariable, out MSA.ParameterExpression/*!*/ blockParamVariable) {
            // Block signature:
            // <proc>, <self>, <leading-mandatory>, <trailing-mandatory>, <optional>, &<block>, *<unsplat>
            // or
            // <proc>, <self>, object[] { <leading-mandatory>, <trailing-mandatory>, <optional>, &<block> } *<unsplat>,
            var parameters = new AstParameters(
                HiddenParameterCount +
                (HasFormalParametersInArray ? 1 : ParameterCount) +
                (HasUnsplatParameter ? 1 : 0) +
                (HasProcParameter ? 1 : 0)
            );

            // hidden parameters:
            // #proc must be the first one - it is used as instance target for method invocation:
            parameters.Add(blockParamVariable = Ast.Parameter(typeof(BlockParam), "#bp"));
            parameters.Add(selfVariable = Ast.Parameter(typeof(object), "#self"));

            if (HasFormalParametersInArray) {
                parameters.Add(Ast.Parameter(typeof(object[]), "#parameters"));
            } else {
                for (int i = 0; i < ParameterCount; i++) {
                    parameters.Add(Ast.Parameter(typeof(object), "#" + i));
                }
            }

            if (HasUnsplatParameter) {
                parameters.Add(Ast.Parameter(typeof(RubyArray), "#array"));
            }

            if (HasProcParameter) {
                parameters.Add(Ast.Parameter(typeof(Proc), "#proc"));
            }

            return parameters;
        }
Beispiel #11
0
        private MSA.Expression/*!*/ MakeParametersInitialization(AstGenerator/*!*/ gen, AstParameters/*!*/ parameters) {
            var result = new AstExpressions(
                ParameterCount + 
                (_parameters.Optional.Length > 0 ? 1 : 0) + 
                (_parameters.Unsplat != null ? 1 : 0) +
                (_parameters.Block != null ? 1 : 0) +
                1
             );

            // TODO: we can skip parameters that are locals (need to be defined as parameters, not as #n):

            var paramsArray = HasFormalParametersInArray ? parameters[HiddenParameterCount] : null;

            int parameterIndex = 0;
            for (int i = 0; i < _parameters.Mandatory.Length; i++) {
                result.Add(_parameters.Mandatory[i].TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex)));
                parameterIndex++;
            }

            if (_parameters.Optional.Length > 0) {
                for (int i = 0; i < _parameters.Optional.Length; i++) {
                    result.Add(_parameters.Optional[i].Left.TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex)));
                    parameterIndex++;
                }
                result.Add(_parameters.TransformOptionalsInitialization(gen));
            }

            if (_parameters.Unsplat != null) {
                // the last parameter is unsplat:
                result.Add(_parameters.Unsplat.TransformWrite(gen, parameters[parameters.Count - (_parameters.Block != null ? 2 : 1)]));
            }

            if (_parameters.Block != null) {
                result.Add(_parameters.Block.TransformWrite(gen, parameters[parameters.Count - 1]));
                parameterIndex++;
            }

            result.Add(AstUtils.Empty());
            return Ast.Block(result);
        }
Beispiel #12
0
 private MSA.Expression/*!*/ GetParameterAccess(AstParameters/*!*/ parameters, MSA.Expression paramsArray, int i) {
     return (paramsArray != null) ? (MSA.Expression)Ast.ArrayAccess(paramsArray, AstUtils.Constant(i)) : parameters[HiddenParameterCount + i];
 }
Beispiel #13
0
        private AstParameters/*!*/ DefineParameters(out MSA.ParameterExpression/*!*/ selfVariable, out MSA.ParameterExpression/*!*/ blockParamVariable) {
            var parameters = new AstParameters(
                HiddenParameterCount +
                (HasFormalParametersInArray ? 1 : _parameters.LeftValues.Count) + 
                (HasUnsplatParameter ? 1 : 0)
            );

            // hidden parameters:
            // #proc must be the first one - it is used as instance target for method invocation:
            parameters.Add(blockParamVariable = Ast.Parameter(typeof(BlockParam), "#proc"));
            parameters.Add(selfVariable = Ast.Parameter(typeof(object), "#self"));

            if (HasFormalParametersInArray) {
                parameters.Add(Ast.Parameter(typeof(object[]), "#parameters"));
            } else {
                for (int i = 0; i < _parameters.LeftValues.Count; i++) {
                    parameters.Add(Ast.Parameter(typeof(object), "#" + i));
                }
            }

            if (HasUnsplatParameter) {
                parameters.Add(Ast.Parameter(typeof(RubyArray), "#array"));
            }

            return parameters;
        }
Beispiel #14
0
        private MSA.Expression/*!*/ MakeParametersInitialization(AstGenerator/*!*/ gen, AstParameters/*!*/ parameters) {
            var result = new AstExpressions(
                _parameters.LeftValues.Count + 
                (_parameters.UnsplattedValue != null ? 1 : 0) +
                1
            );

            bool paramsInArray = HasFormalParametersInArray;
            for (int i = 0; i < _parameters.LeftValues.Count; i++) {
                var parameter = paramsInArray ? (MSA.Expression)
                    Ast.ArrayAccess(parameters[HiddenParameterCount], AstUtils.Constant(i)) :
                    parameters[HiddenParameterCount + i];

                result.Add(_parameters.LeftValues[i].TransformWrite(gen, parameter));
            }

            if (_parameters.UnsplattedValue != null) {
                // the last parameter is unsplat:
                var parameter = parameters[parameters.Count - 1];
                result.Add(_parameters.UnsplattedValue.TransformWrite(gen, parameter));
            }

            result.Add(AstUtils.Empty());
            return Ast.Block(result);
        }
Beispiel #15
0
        /*!*/
        private ScopeBuilder DefineLocals(out AstParameters/*!*/ parameters)
        {
            // Method signature:
            // <self>, &<block>, <leading-mandatory>, <trailing-mandatory>, <optional>, *<unsplat>

            parameters = new AstParameters(
                HiddenParameterCount +
                _parameters.Mandatory.Length +
                _parameters.Optional.Length +
                (_parameters.Unsplat != null ? 1 : 0)
            );

            int closureIndex = 0;
            int firstClosureParam = 1;
            parameters.Add(Ast.Parameter(typeof(object), "#self"));

            if (_parameters.Block != null) {
                parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name));
                _parameters.Block.SetClosureIndex(closureIndex++);
            } else {
                parameters.Add(Ast.Parameter(typeof(Proc), "#block"));
                firstClosureParam++;
            }

            foreach (LeftValue lvalue in _parameters.Mandatory) {
                var param = lvalue as LocalVariable;
                if (param != null) {
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                } else {
                    // TODO:
                    throw new NotSupportedException("TODO: compound parameters");
                }
            }

            foreach (var lvalue in _parameters.Optional) {
                var param = (LocalVariable)lvalue.Left;
                parameters.Add(Ast.Parameter(typeof(object), param.Name));
                param.SetClosureIndex(closureIndex++);
            }

            if (_parameters.Unsplat != null) {
                var unsplatLocal = (LocalVariable)_parameters.Unsplat;
                parameters.Add(Ast.Parameter(typeof(object), unsplatLocal.Name));
                unsplatLocal.SetClosureIndex(closureIndex++);
            }

            // allocate closure slots for locals:
            int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex);

            return new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope);
        }
Beispiel #16
0
        private MSA.Expression /*!*/ MakeParametersInitialization(AstGenerator /*!*/ gen, AstParameters /*!*/ parameters)
        {
            var result = new AstExpressions(
                ParameterCount +
                (_parameters.Optional.Length > 0 ? 1 : 0) +
                (_parameters.Unsplat != null ? 1 : 0) +
                (_parameters.Block != null ? 1 : 0) +
                1
                );

            // TODO: we can skip parameters that are locals (need to be defined as parameters, not as #n):

            var paramsArray = HasFormalParametersInArray ? parameters[HiddenParameterCount] : null;

            int parameterIndex = 0;

            for (int i = 0; i < _parameters.Mandatory.Length; i++)
            {
                result.Add(_parameters.Mandatory[i].TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex)));
                parameterIndex++;
            }

            if (_parameters.Optional.Length > 0)
            {
                for (int i = 0; i < _parameters.Optional.Length; i++)
                {
                    result.Add(_parameters.Optional[i].Left.TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex)));
                    parameterIndex++;
                }
                result.Add(_parameters.TransformOptionalsInitialization(gen));
            }

            if (_parameters.Unsplat != null)
            {
                // the last parameter is unsplat:
                result.Add(_parameters.Unsplat.TransformWrite(gen, parameters[parameters.Count - (_parameters.Block != null ? 2 : 1)]));
            }

            if (_parameters.Block != null)
            {
                result.Add(_parameters.Block.TransformWrite(gen, parameters[parameters.Count - 1]));
                parameterIndex++;
            }

            result.Add(AstUtils.Empty());
            return(Ast.Block(result));
        }
Beispiel #17
0
 private MSA.Expression /*!*/ GetParameterAccess(AstParameters /*!*/ parameters, MSA.Expression paramsArray, int i)
 {
     return((paramsArray != null) ? (MSA.Expression)Ast.ArrayAccess(paramsArray, AstUtils.Constant(i)) : parameters[HiddenParameterCount + i]);
 }
Beispiel #18
0
        private ScopeBuilder /*!*/ DefineLocals(out AstParameters /*!*/ parameters)
        {
            // Method signature:
            // <self>, &<block>, <leading-mandatory>, <trailing-mandatory>, <optional>, *<unsplat>

            parameters = new AstParameters(
                HiddenParameterCount +
                _parameters.Mandatory.Length +
                _parameters.Optional.Length +
                (_parameters.Unsplat != null ? 1 : 0)
                );

            int closureIndex      = 0;
            int firstClosureParam = 1;

            parameters.Add(Ast.Parameter(typeof(object), "#self"));

            if (_parameters.Block != null)
            {
                parameters.Add(Ast.Parameter(typeof(Proc), _parameters.Block.Name));
                _parameters.Block.SetClosureIndex(closureIndex++);
            }
            else
            {
                parameters.Add(Ast.Parameter(typeof(Proc), "#block"));
                firstClosureParam++;
            }

            foreach (LeftValue lvalue in _parameters.Mandatory)
            {
                var param = lvalue as LocalVariable;
                if (param != null)
                {
                    parameters.Add(Ast.Parameter(typeof(object), param.Name));
                    param.SetClosureIndex(closureIndex++);
                }
                else
                {
                    // TODO:
                    throw new NotSupportedException("TODO: compound parameters");
                }
            }

            foreach (var lvalue in _parameters.Optional)
            {
                var param = (LocalVariable)lvalue.Left;
                parameters.Add(Ast.Parameter(typeof(object), param.Name));
                param.SetClosureIndex(closureIndex++);
            }

            if (_parameters.Unsplat != null)
            {
                var unsplatLocal = (LocalVariable)_parameters.Unsplat;
                parameters.Add(Ast.Parameter(typeof(object), unsplatLocal.Name));
                unsplatLocal.SetClosureIndex(closureIndex++);
            }

            // allocate closure slots for locals:
            int localCount = DefinedScope.AllocateClosureSlotsForLocals(closureIndex);

            return(new ScopeBuilder(parameters, firstClosureParam, localCount, null, DefinedScope));
        }