(once) and (oncePerInstance)
This commit is contained in:
@@ -9,7 +9,9 @@ import kiss.Reader;
|
||||
import kiss.CompileError;
|
||||
import kiss.Kiss;
|
||||
import kiss.SpecialForms;
|
||||
import uuid.Uuid;
|
||||
|
||||
using uuid.Uuid;
|
||||
using tink.MacroApi;
|
||||
using kiss.Reader;
|
||||
using kiss.Helpers;
|
||||
@@ -364,6 +366,7 @@ class Helpers {
|
||||
list: (exps:Array<ReaderExp>) -> ListExp(exps).withPosOf(posRef),
|
||||
str: (s:String) -> StrExp(s).withPosOf(posRef),
|
||||
symbol: (name:String) -> Symbol(name).withPosOf(posRef),
|
||||
gensym: () -> Symbol('_${Uuid.v4().toShort()}').withPosOf(posRef),
|
||||
raw: (code:String) -> RawHaxe(code).withPosOf(posRef),
|
||||
typed: (path:String, exp:ReaderExp) -> TypedExp(path, exp).withPosOf(posRef),
|
||||
meta: (m:String, exp:ReaderExp) -> MetaExp(m, exp).withPosOf(posRef),
|
||||
|
@@ -2,12 +2,10 @@ package kiss;
|
||||
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Context;
|
||||
import uuid.Uuid;
|
||||
import kiss.Reader;
|
||||
import kiss.Kiss;
|
||||
import kiss.CompileError;
|
||||
|
||||
using uuid.Uuid;
|
||||
using kiss.Kiss;
|
||||
using kiss.Reader;
|
||||
using kiss.Helpers;
|
||||
@@ -178,8 +176,8 @@ class Macros {
|
||||
macros["or"] = (wholeExp:ReaderExp, args:Array<ReaderExp>, k) -> {
|
||||
wholeExp.checkNumArgs(2, null, "(or [v1] [v2] [values...])");
|
||||
var b = wholeExp.expBuilder();
|
||||
var uniqueVarName = "_" + Uuid.v4().toShort();
|
||||
var uniqueVarSymbol = b.symbol(uniqueVarName);
|
||||
|
||||
var uniqueVarSymbol = b.gensym();
|
||||
|
||||
b.begin([
|
||||
b.call(b.symbol("deflocal"), [
|
||||
@@ -204,8 +202,8 @@ class Macros {
|
||||
macros["and"] = (wholeExp:ReaderExp, args:Array<ReaderExp>, k) -> {
|
||||
wholeExp.checkNumArgs(2, null, "(and [v1] [v2] [values...])");
|
||||
var b = wholeExp.expBuilder();
|
||||
var uniqueVarName = "_" + Uuid.v4().toShort();
|
||||
var uniqueVarSymbol = b.symbol(uniqueVarName);
|
||||
|
||||
var uniqueVarSymbol = b.gensym();
|
||||
|
||||
var condCases = [
|
||||
for (arg in args) {
|
||||
@@ -552,8 +550,20 @@ class Macros {
|
||||
wholeExp.checkNumArgs(1, 1, "(collect [iterator or iterable])");
|
||||
var b = wholeExp.expBuilder();
|
||||
b.call(b.symbol("for"), [b.symbol("elem"), exps[0], b.symbol("elem")]);
|
||||
};
|
||||
|
||||
function once(macroName:String, wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
||||
wholeExp.checkNumArgs(1, null, '($macroName [body...])');
|
||||
var b = wholeExp.expBuilder();
|
||||
var flag = b.gensym();
|
||||
// define the field:
|
||||
k.convert(b.call(b.symbol(macroName), [b.meta("mut", flag), b.symbol("true")]));
|
||||
return b.call(b.symbol("when"), [flag, b.call(b.symbol("set"), [flag, b.symbol("false")])].concat(exps));
|
||||
}
|
||||
|
||||
macros["once"] = once.bind("defvar");
|
||||
macros["oncePerInstance"] = once.bind("defprop");
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
|
17
src/test/cases/OnceTestCase.hx
Normal file
17
src/test/cases/OnceTestCase.hx
Normal file
@@ -0,0 +1,17 @@
|
||||
package test.cases;
|
||||
|
||||
import utest.Test;
|
||||
import utest.Assert;
|
||||
import kiss.Prelude;
|
||||
|
||||
class OnceTestCase extends Test {
|
||||
function testOnce() {
|
||||
new OnceTestObject();
|
||||
new OnceTestObject();
|
||||
Assert.equals(1, OnceTestObject.staticCount);
|
||||
Assert.equals(2, OnceTestObject.instanceCount);
|
||||
}
|
||||
}
|
||||
|
||||
@:build(kiss.Kiss.build("OnceTestObject.kiss"))
|
||||
class OnceTestObject {}
|
8
src/test/cases/OnceTestObject.kiss
Normal file
8
src/test/cases/OnceTestObject.kiss
Normal file
@@ -0,0 +1,8 @@
|
||||
(defvar &mut staticCount 0)
|
||||
(defvar &mut instanceCount 0)
|
||||
|
||||
(defmethod new []
|
||||
(once
|
||||
(+= staticCount 1))
|
||||
(oncePerInstance
|
||||
(+= instanceCount 1)))
|
Reference in New Issue
Block a user