kiss-lang / kiss

A type-safe, compiled Lisp for Haxe programs
GNU Lesser General Public License v2.1
3 stars 0 forks source link

unclosed macro is allowed?! #11

Closed NQNStudios closed 9 months ago

NQNStudios commented 9 months ago

The following compiles and succeeds:

UnclosedMacroCase.hx

package test.cases;

import utest.Test;
import utest.Assert;
import kiss.Prelude;
import kiss.List;
import kiss.Stream;
import haxe.ds.Option;
import kiss.Kiss;
#if js
import js.lib.Promise;
#end

using StringTools;

@:build(kiss.Kiss.build())
class UnclosedMacroCase extends Test {
    function testSplitByAll() {
        Assert.pass();
    }
}

UnclosedMacroCase.kiss

(defMacro addSkips [flxMovieClass]
    `{
        (method &override :Void prepareForSkip []
            (print "prepareForSkip override called")
            // TODO these things could/should all be in HollywooDSL:
            (kiss_tools.TimerWithPause.stopAll)
            (flxDirector.pause)
            (.clear (director.shortcutHandler))
            (flxDirector.cleanup)
            (cond
                (~didLoading
                    (set skipMovie (new ,flxMovieClass flxDirector))
                    (skipMovie.scavengeObjects this)
                    (doCleanup))
                (true
                    (set skipMovie ~this)))

        (preload
            (unless (FlxG.inputs.list.contains flxDirector.actionManager)
                (FlxG.inputs.add flxDirector.actionManager))

            (set onCommitLabel ->:Void label {
                (FlxDirector.lastSceneForMovie this label)
            }))

        (cleanup
            (when skipMovie?.running
                (callPrivate skipMovie "doCleanup")))

        (cleanup
            (set tweens [])
            (set flxDirector.nextCC null)
            (loopingSoundPlays.clear)
            (destroyAndClear actors)
            (destroyAndClear props)
            (destroyAndClear sets)
            (destroyAndClear sounds)
            (destroyAndClear voiceTracks)
            (destroyAndClear songs)
            (when (flixel.FlxG.cameras.list.contains uiCamera)
                (flixel.FlxG.cameras.remove uiCamera true))
            (when (flixel.FlxG.cameras.list.contains screenCamera)
                (flixel.FlxG.cameras.remove screenCamera true))

            // I hope this disposes of references to actors, props, sets, etc.:
            (scenes.clear)

            (propScales.m.clear)
            (propsInScene.clear)
            (overlaidPropsInScenes.clear)
            (doFor m tweenedPositionsOfSpritesInScenes
                (doFor p m
                    (p.put))
                (m.clear))
            (tweenedPositionsOfSpritesInScenes.clear)

            (doFor =>key lightSourceList lightSources
                (whileLet [lightSource (lightSourceList.elements.pop)]
                    (lightSource.destroy)))

            (#when cpp
                (cpp.vm.Gc.run true)
                (cpp.vm.Gc.compact)))

        (#when debug
            (preload
                (.registerItem (director.shortcutHandler) "[n]ext label"
                                ->cc {
                                    (prepareForSkip)
                                    (runFromNextLabel skipMovie)
                                })       

                (.registerItem (director.shortcutHandler) "skip to [l]abel"
                                ->cc
                                    (flxDirector.sceneSelection ->:Void {}))))
    })
NQNStudios commented 9 months ago

Unfortunately, this also passes the compiler if defMacro is replaced with function

NQNStudios commented 9 months ago

It doesn't happen when the {} reader macro isn't used