示例#1
0
        private BoundIf BuildSetWithScope(BlockBuilder builder, WithScope withScope, IIdentifier fallback, BoundTemporary value)
        {
            var withLocal = builder.CreateTemporary();

            builder.Add(new BoundSetVariable(
                withLocal,
                new BoundGetVariable(_withIdentifiers[withScope.Identifier]), SourceLocation.Missing
            ));

            var setter = new BoundSetMember(
                new BoundGetVariable(withLocal),
                BoundConstant.Create(fallback.Name),
                new BoundGetVariable(value),
                SourceLocation.Missing
            );

            BoundBlock @else;

            if (withScope.Parent == null)
            {
                @else = BuildBlock(BuildSet(
                    fallback,
                    new BoundGetVariable(value)
                ));
            }
            else
            {
                @else = BuildBlock(BuildSetWithScope(
                    builder,
                    withScope.Parent,
                    fallback,
                    value
                ));
            }

            return new BoundIf(
                new BoundHasMember(
                    new BoundGetVariable(withLocal),
                    fallback.Name
                ),
                BuildBlock(setter),
                @else,
                SourceLocation.Missing
            );
        }
示例#2
0
        private BoundIf BuildGetWithScope(BlockBuilder builder, WithScope withScope, IIdentifier fallback, BoundTemporary result, BoundTemporary withTarget)
        {
            var withLocal = builder.CreateTemporary();

            builder.Add(new BoundSetVariable(
                withLocal,
                new BoundGetVariable(_withIdentifiers[withScope.Identifier]),
                SourceLocation.Missing
            ));

            var getter = new BlockBuilder(this);

            if (withTarget != null)
            {
                getter.Add(new BoundSetVariable(
                    withTarget,
                    new BoundGetVariable(withLocal),
                    SourceLocation.Missing
                ));
            }

            getter.Add(new BoundSetVariable(
                result,
                BuildGetMember(
                    new BoundGetVariable(withLocal),
                    BoundConstant.Create(fallback.Name)
                ),
                SourceLocation.Missing
            ));

            BoundBlock @else;

            if (withScope.Parent == null)
            {
                @else = BuildBlock(new BoundSetVariable(
                    result,
                    BuildGet(
                        fallback,
                        null
                    ),
                    SourceLocation.Missing
                ));
            }
            else
            {
                @else = BuildBlock(BuildGetWithScope(
                    builder,
                    withScope.Parent,
                    fallback,
                    result,
                    withTarget
                ));
            }

            return new BoundIf(
                new BoundHasMember(
                    new BoundGetVariable(withLocal),
                    fallback.Name
                ),
                getter.BuildBlock(SourceLocation.Missing),
                @else,
                SourceLocation.Missing
            );
        }
示例#3
0
        private BoundStatement BuildSet(IIdentifier identifier, BoundExpression value)
        {
            switch (identifier.Type)
            {
                case IdentifierType.Parameter:
                    return new BoundSetVariable(
                        _scope.GetArgument(identifier),
                        value,
                        SourceLocation.Missing
                    );

                case IdentifierType.Scoped:
                    var builder = new BlockBuilder(this);

                    var valueTemporary = builder.CreateTemporary();

                    builder.Add(new BoundSetVariable(
                        valueTemporary,
                        value,
                        SourceLocation.Missing
                    ));

                    builder.Add(BuildSetWithScope(builder, identifier.WithScope, identifier.Fallback, valueTemporary));

                    return builder.BuildBlock(SourceLocation.Missing);

                case IdentifierType.Local:
                case IdentifierType.Global:
                    if (identifier.Type == IdentifierType.Global)
                        _scope.IsGlobalScopeReferenced = true;

                    if (identifier.Closure == null)
                        return new BoundSetVariable(_scope.GetLocal(identifier), value, SourceLocation.Missing);

                    return new BoundSetVariable(
                        _scope.GetClosureField(identifier),
                        value,
                        SourceLocation.Missing
                    );

                    /*
                    // These are handled upstream.
                case IdentifierType.This:
                case IdentifierType.Null:
                case IdentifierType.Undefined:
                case IdentifierType.Arguments:
                     */

                default:
                    throw new InvalidOperationException("Cannot find variable of argument");
            }
        }
示例#4
0
        private BoundExpression BuildGet(IIdentifier identifier, BoundTemporary withTarget)
        {
            switch (identifier.Type)
            {
                case IdentifierType.Null: return new BoundGetVariable(BoundMagicVariable.Null);
                case IdentifierType.Undefined: return new BoundGetVariable(BoundMagicVariable.Undefined);

                case IdentifierType.This:
                    _scope.IsThisReferenced = true;
                    return new BoundGetVariable(BoundMagicVariable.This);

                case IdentifierType.Arguments:
                    _scope.IsArgumentsReferenced = true;
                    return new BoundGetVariable(BoundMagicVariable.Arguments);

                case IdentifierType.Parameter:
                    return new BoundGetVariable(_scope.GetArgument(identifier));

                case IdentifierType.Scoped:
                    var builder = new BlockBuilder(this);
                    var result = builder.CreateTemporary();

                    builder.Add(
                        BuildGetWithScope(builder, identifier.WithScope, identifier.Fallback, result, withTarget)
                    );

                    return builder.BuildExpression(result, SourceLocation.Missing);

                case IdentifierType.Local:
                case IdentifierType.Global:
                    if (identifier.Closure != null)
                        return new BoundGetVariable(_scope.GetClosureField(identifier));

                    return new BoundGetVariable(_scope.GetLocal(identifier));

                default:
                    throw new InvalidOperationException("Cannot find variable of argument");
            }
        }