Esempio n. 1
0
 public override Et Walk(EtGenerator etgen)
 {
     return etgen.GenerateAssign(
         Target,
         Value.Walk(etgen)
     );
 }
Esempio n. 2
0
        public override Et Walk(EtGenerator etgen)
        {
            // try ... finally
            if (Catch == null)
            {
                return Et.TryFinally(
                    Body.Walk(etgen),
                    Finally.Walk(etgen)
                );
            }
            else
            {
                var catchParam = Et.Parameter(typeof(JsRuntimeError), "#catch");

                var catchBody = Et.Block(
                    etgen.GenerateAssign(
                        Catch.Target,
                        Et.Property(
                            catchParam,
                            "JsObj"
                        )
                    ),
                    Et.Block(
                        Catch.Body.Walk(etgen)
                    )
                );

                var catchBlock = Et.Catch(
                    catchParam,
                    EtUtils.Cast<object>(catchBody)
                );

                var tryBody = EtUtils.Box(Body.Walk(etgen));

                // try ... catch
                if (Finally == null)
                {
                    return Et.TryCatch(
                        tryBody,
                        catchBlock
                    );
                }
                // try ... catch ... finally
                else
                {
                    return Et.TryCatchFinally(
                        tryBody,
                        Finally.Walk(etgen),
                        catchBlock
                    );
                }
            }
        }
        public override Et Walk(EtGenerator etgen)
        {
            var tmp = Et.Parameter(typeof(double), "#tmp");

            return Et.Block(
                new[] { tmp },

                // the value we will return
                Et.Assign(
                    tmp,
                    Et.Dynamic(
                        etgen.Context.CreateConvertBinder(typeof(double)),
                        typeof(double),
                        Target.Walk(etgen)
                    )
                ),

                // calc new value
                etgen.GenerateAssign(
                    Target,
                    EtUtils.Box(
                        Et.Add(
                            tmp,
                            Et.Constant(
                                Op == ExpressionType.PostIncrementAssign
                                         ? 1.0    // 11.3.1
                                         : -1.0,  // 11.3.2
                                typeof(double)
                            )
                        )
                    )
                ),

                tmp // return the old value
            );
        }
Esempio n. 4
0
        public override Et LoopWalk(EtGenerator etgen)
        {
            /*
            IObj obj = <node.Source>
            IEnumerator<object> keys = null;
            var set = new HashSet<object>();
            object current = null;

            while (true)
            {
                if (obj == null)
                    break;

                keys = obj.GetAllPropertyNames().GetEnumerator();

                while (true)
                {
                    if (!keys.MoveNext())
                        break;

                    current = keys.Current;

                    if (set.Contains(current))
                        continue;

                    if (obj.HasOwnProperty(current))
                    {
                        set.Add(current);
                        <node.Target> = current;
                        <node.Body>
                    }
                }

                keys.Dispose();
                obj = obj.Prototype;
            }
            */

            // tmp variables
            var obj = Et.Variable(typeof(IObj), "#tmp-forin-obj");
            var keys = Et.Variable(typeof(List<object>.Enumerator), "#tmp-forin-keys"); // IEnumerator<object> keys = null;
            var set = Et.Variable(typeof(HashSet<object>), "#tmp-forin-set");
            var current = Et.Variable(typeof(object), "#tmp-forin-current"); // object current = null;

            // labels
            var innerBreak = Et.Label("#tmp-forin-inner-break");
            var innerContinue = etgen.FunctionScope.LabelScope.Continue();
            var outerBreak = etgen.FunctionScope.LabelScope.Break();

            return Et.Block(
                new[] { obj, keys, set, current },

                // IObj obj = <node.Source>
                Et.Assign(
                    obj,
                    Et.Dynamic(
                        etgen.Context.CreateConvertBinder(typeof(IObj)),
                        typeof(IObj),
                        Source.Walk(etgen)
                    )
                ),
                // var set = new HashSet<object>();
                Et.Assign(
                    set,
                    AstUtils.SimpleNewHelper(
                        typeof(HashSet<object>).GetConstructor(System.Type.EmptyTypes)
                    )
                ),

                // while(true) {
                Et.Loop(
                    Et.Block(
                        // if(obj == null)
                        Et.IfThen(
                            Et.Equal(obj, Et.Default(typeof(IObj))),
                            // break;
                            Et.Break(outerBreak)
                        ),

                        // keys = obj.GetAllPropertyNames().GetEnumerator();
                        Et.Assign(
                            keys,
                            Et.Call(
                                Et.Call(
                                    obj,
                                    IObjMethods.MiGetAllPropertyNames
                                ),
                                typeof(List<object>).GetMethod("GetEnumerator")
                            )
                        ),

                        // while(true) {
                        Et.Loop(
                            Et.Block(

                                // if (!keys.MoveNext())
                                Et.IfThen(
                                    Et.Not(
                                        Et.Call(
                                            keys,
                                            typeof(List<object>.Enumerator).GetMethod("MoveNext")
                                        )
                                    ),
                                    // break;
                                    Et.Break(innerBreak)
                                ),

                                // current = keys.Current;
                                Et.Assign(
                                    current,
                                    Et.Property(
                                        keys,
                                        "Current"
                                    )
                                ),

                                // if (set.Contains(current))
                                Et.IfThen(
                                    Et.Call(
                                        set,
                                        typeof(HashSet<object>).GetMethod("Contains"),
                                        current
                                    ),
                                    //  continue;
                                    Et.Continue(innerContinue)
                                ),

                                // if (obj.HasOwnProperty(current)) {
                                Et.IfThen(
                                    Et.Call(
                                        obj,
                                        IObjMethods.MiHasOwnProperty,
                                        current
                                    ),
                                    Et.Block(

                                        // set.Add(current);
                                        Et.Call(
                                            set,
                                            typeof(HashSet<object>).GetMethod("Add"),
                                            current
                                        ),

                                        // <node.Target> = current;
                                        etgen.GenerateAssign(
                                            Target,
                                            current
                                        ),

                                        // <node.Body>
                                        Body.Walk(etgen)
                                    )
                                )
                            ),
                            innerBreak,
                            innerContinue
                        ),

                        // keys.Dispose();
                        Et.Call(
                            keys,
                            typeof(List<object>.Enumerator).GetMethod("Dispose")
                        ),

                        // obj = obj.Prototype;
                        Et.Assign(
                            obj,
                            Et.Property(
                                obj,
                                "Prototype"
                            )
                        )
                    ),
                    outerBreak
                )
            );
        }