You must be 18+ to view this content

FLIES FLIES FLIES may contain content you must be 18+ to view.

Are you 18 years of age or older?

or Return to itch.io

while I'm at it


while I'm at it

let me tell you about another embarrassing bug I found in my custom Lisp.

Code: (custom lisp test case)
(function _testWhile []
    (let [max 8
            &mut current 0
            &mut iterations 0]
        (while (>= max (+= current 1))
            (+= iterations 1))
        (assertEquals 8 iterations)))


Outputs:

Assertion failed: expected 8 but it was 4


Somehow I've been working with while loops that evaluate their condition twice per iteration!!!!

This is a pretty good opportunity to delve into the language internals.

My language is just a very complicated Haxe macro.

Haxe macros are basically functions written in Haxe, which return a data structure representing haxe expressions, which haxe compiles into your program.

Here is the code where my language is generating a data structure for the while loop:

Code: (haxe macro)
        function whileForm(invert:Bool, wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) {
            var funcName = if (invert) "until" else "while";
            var b = wholeExp.expBuilder();
            var cond = k.convert(b.callSymbol("Prelude.truthy", [args[0]));
            if (invert) {
                cond = macro !$cond;
                cond = b.haxeExpr(cond);
            }
            return EWhile(cond, k.convert(b.begin(args)), true).withMacroPosOf(wholeExp);
        }
        k.doc("while", 2, null, '(while <condition> <body...>)');
        map["while"] = whileForm.bind(false);
        k.doc("until", 2, null, '(until <condition> <body...>)');
        map["until"] = whileForm.bind(true);

This registers two variations of while loops into my custom lisp: one for normal while loops, and one for inverted while loops: "until" loops where the body is repeated UNTIL the condition becomes true.

The problem, which took me a few minutes to pinpoint, is that I'm accessing the condition expression, args[0], but LEAVING it in the args list, which then gets passed into the data structure as part of the BODY of the while loop. So effectively, (while (checkCond) (doThing)) would turn into (while (checkCond) (checkCond) (doThing)). If any side-effects take place in the condition expression, kaboom!!

Get FLIES FLIES FLIES

Buy Now$5.99 USD or more

Leave a comment

Log in with itch.io to leave a comment.