How are statements calculated?


#1

I’m thinking this is another instance of bug https://github.com/codecombat/aether/issues/73, but I’m not entirely sure. Maybe I’m misunderstanding how statement count is done…

I have the following Clojure (yes, it’s ugly, or beautiful depending on how you feel about LISP):

(dotimes [n 3]

    (dotimes [n 2]
        (.moveRight this))
    
    (dotimes [n 2]
        (.moveUp this))

)

The bonus for the level, Haunted Kithmaze, is awarded for under 6 statements, but I am not rewarded the bonus for this code. Are statements supposed to be counted as “statements executed” or LOC? By my thinking, this should be 5 statements unless there are “hidden statements”, ie in a for loop for(int ct = 0; ct < i; ct++) // == 2 statements per iteration, 3 for the first iteration if ct<i.


Forgetful Gemsmith Bonus
#2

NM, answered in the FAQ under language status. Still, I’m curious about how the actual statements are counted if anyone knows, off the top of their head, instead of me digging into the code to find out.


#3

No one really knows how the statements are counted in Clojure, because unfortunately, statement counting is done after transpilation to JS, and so you’d have to look at the Closer.js demo page to see what it outputs for any given bit of code. For this code, it gives this output:

// equivalent javascript code:
(function () {
    for (var n = 0, __$max2 = 3; n < __$max2; ++n) {
        (function () {
            for (var n = 0, __$max0 = 2; n < __$max0; ++n) {
                typeof __$this['moveRight'] === 'function' && __$this['moveRight'].length === 0 ? __$this['moveRight']() : __$this['moveRight'];
            }
        }.call(__$this));
        (function () {
            for (var n = 0, __$max1 = 2; n < __$max1; ++n) {
                typeof __$this['moveUp'] === 'function' && __$this['moveUp'].length === 0 ? __$this['moveUp']() : __$this['moveUp'];
            }
        }.call(__$this));
    }
}.call(__$this));

But even that’s not the full story, because Aether does another pass on it before counting statements, turning it into this:

var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();
return (function (__global) {
    var tmp0, tmp1;
    tmp1 = function () {
        _aether.logCallStart(_aether._userInfo); var n, __$max2, __$max0, __$max1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65, tmp66;
        n = 0;
        __$max2 = 3;
        tmp3 = n;
        tmp4 = __$max2;
        tmp2 = tmp3 < tmp4;
        tmp9: {
            while (tmp2) {
                tmp10: {
                    n = 0;
                    __$max0 = 2;
                    tmp12 = n;
                    tmp13 = __$max0;
                    tmp11 = tmp12 < tmp13;
                    tmp18: {
                        while (tmp11) {
                            tmp19: {
                                tmp25 = __interceptThis(this, __global);
                                _aether.logStatementStart([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}]); tmp26 = 'moveRight';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp24 = tmp25[tmp26];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp22 = typeof tmp24;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp23 = 'function';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp21 = tmp22 === tmp23;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                if (tmp21) {
                                    tmp31 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}]); tmp32 = 'moveRight';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp29 = tmp31[tmp32];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    tmp30 = 'length';
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp27 = tmp29[tmp30];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp28 = 0;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp20 = tmp27 === tmp28;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                } else {
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp20 = tmp21;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                }
                                if (tmp20) {
                                    tmp33 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}]); tmp34 = 'moveRight';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp35 = tmp33[tmp34]();  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                } else {
                                    tmp36 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}]); tmp37 = 'moveRight';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 45, row: 3, col: 10}, {ofs: 54, row: 3, col: 19}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}]); tmp38 = tmp36[tmp37];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 44, row: 3, col: 9}, {ofs: 45, row: 3, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                }
                            }
                            tmp16 = n;
                            tmp17 = 1;
                            n = tmp16 + tmp17;
                            tmp14 = n;
                            tmp15 = __$max0;
                            tmp11 = tmp14 < tmp15;
                        }
                    }
                    n = 0;
                    __$max1 = 2;
                    tmp40 = n;
                    tmp41 = __$max1;
                    tmp39 = tmp40 < tmp41;
                    tmp46: {
                        while (tmp39) {
                            tmp47: {
                                tmp53 = __interceptThis(this, __global);
                                _aether.logStatementStart([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}]); tmp54 = 'moveUp';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp52 = tmp53[tmp54];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp50 = typeof tmp52;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp51 = 'function';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp49 = tmp50 === tmp51;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                if (tmp49) {
                                    tmp59 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}]); tmp60 = 'moveUp';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp57 = tmp59[tmp60];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    tmp58 = 'length';
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp55 = tmp57[tmp58];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp56 = 0;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp48 = tmp55 === tmp56;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                } else {
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp48 = tmp49;  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                }
                                if (tmp48) {
                                    tmp61 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}]); tmp62 = 'moveUp';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp63 = tmp61[tmp62]();  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                } else {
                                    tmp64 = __interceptThis(this, __global);
                                    _aether.logStatementStart([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}]); tmp65 = 'moveUp';  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 96, row: 6, col: 10}, {ofs: 102, row: 6, col: 16}], _aether._userInfo, !_aether._shouldSkipFlow);
                                    _aether.logStatementStart([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}]); tmp66 = tmp64[tmp65];  if (!_aether._shouldSkipFlow) { _aether.vars['n'] = typeof n == 'undefined' ? undefined : n; _aether.vars['__$max2'] = typeof __$max2 == 'undefined' ? undefined : __$max2; _aether.vars['__$max0'] = typeof __$max0 == 'undefined' ? undefined : __$max0; _aether.vars['__$max1'] = typeof __$max1 == 'undefined' ? undefined : __$max1; _aether.vars['foo'] = typeof foo == 'undefined' ? undefined : foo; } _aether.logStatement([{ofs: 95, row: 6, col: 9}, {ofs: 96, row: 6, col: 10}], _aether._userInfo, !_aether._shouldSkipFlow);
                                }
                            }
                            tmp44 = n;
                            tmp45 = 1;
                            n = tmp44 + tmp45;
                            tmp42 = n;
                            tmp43 = __$max1;
                            tmp39 = tmp42 < tmp43;
                        }
                    }
                }
                tmp7 = n;
                tmp8 = 1;
                n = tmp7 + tmp8;
                tmp5 = n;
                tmp6 = __$max2;
                tmp2 = tmp5 < tmp6;
            }
        }
        _aether.logCallEnd(); return;
    };
    tmp0 = 'foo';
    __global[tmp0] = tmp1;
}(this));

I count 30 statement start logs there, since it’s including even things like the numeric literals present in the original source, plus the stuff that Closer.js does to turn things into for-loops behind the scenes. So that’s definitely going to blow up the statement counter. Alas! See, we need a much better architecture for counting statements if it’s going to work outside of Python, JS, and maybe CoffeeScript.


#4

Oh, wow. That’s… something. I can only imagine what bad code looks like in its final JS “bytecode” form. :slight_smile:

I started reading through the code on Github, but I only know enough JS/CS to be dangerous to myself. Is it possible to pre-process the raw code either before the parser is called (if I’m understanding the code flow correctly from my extremely limited JS/CS understanding) or as the first step of parsing? Kind of like the C/C++ pre-processor, but without actually doing full token parsing/code replacement. More like a regex engine than an actual pre-processor.

Or does the architecture dictate that it has to be calculated at the end because you have no idea what you actually started with when you’re that deep? I was thinking you could just pass that value down the stack rather than parsing the emitted JavaScript on the tail end, or even make it global since the scope of “global” in this context is a single run.

I’d take a crack at it, but I don’t know where in the code to begin without sitting down with it for an evening or three.


#5

Ah, that would indeed be a good idea–to make each parser count unique statements before we do any of our transformations. We’d lose the ability to count based on which statements were actually run, but we don’t need that–unused statements can incur the penalty okay.

I’ve opened up a new issue to track this idea here.