(once) and (oncePerInstance)

This commit is contained in:
2021-04-27 20:05:57 -06:00
parent 23815e2bfa
commit 2acefb133d
4 changed files with 44 additions and 6 deletions

View File

@@ -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),

View File

@@ -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;
}

View 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 {}

View File

@@ -0,0 +1,8 @@
(defvar &mut staticCount 0)
(defvar &mut instanceCount 0)
(defmethod new []
(once
(+= staticCount 1))
(oncePerInstance
(+= instanceCount 1)))