[nap] tags example

This commit is contained in:
2021-05-21 17:27:19 -06:00
parent 165657d497
commit f48318bee4
22 changed files with 84 additions and 106 deletions

View File

@@ -553,6 +553,7 @@ class Macros {
argList.push(propExp); argList.push(propExp);
propertyDefs.push( propertyDefs.push(
b.call(b.symbol("defprop"), [propExp])); b.call(b.symbol("defprop"), [propExp]));
// TODO allow &prop &mut or &mut &prop
switch (propExp.def) { switch (propExp.def) {
case TypedExp(_, {pos: _, def: Symbol(name)}): case TypedExp(_, {pos: _, def: Symbol(name)}):
propertySetExps.push( propertySetExps.push(

View File

@@ -1,7 +0,0 @@
-lib uuid
-lib kiss
-lib hscript
-lib tink_json
-cp src
--main nap.Main
--interp

View File

@@ -1 +0,0 @@
{"name":"Villain Alcohol","id":"song1","components":[["Tag", ["song"]]]}

View File

@@ -8,7 +8,6 @@
"releasenote": "It isn't safe to use this library yet.", "releasenote": "It isn't safe to use this library yet.",
"contributors": ["NQNStudios"], "contributors": ["NQNStudios"],
"classPath": "src/", "classPath": "src/",
"main": "nap.Main",
"dependencies": { "dependencies": {
"kiss": "", "kiss": "",
"tink_json": "" "tink_json": ""

View File

@@ -1,10 +1,10 @@
package nap; package nap;
import kiss.Prelude;
import sys.FileSystem; import sys.FileSystem;
import kiss.Prelude;
import sys.io.File; import sys.io.File;
import tink.Json; import tink.Json;
import nap.systems.TagSystem; import uuid.Uuid;
using haxe.io.Path; using haxe.io.Path;

View File

@@ -1,16 +1,18 @@
(defnew [archiveDir] (defnew [&prop :String archiveDir
&prop :Array<System> systems]
[:Map<String,Entry> entries [:Map<String,Entry> entries
(let [entryFiles (FileSystem.readDirectory archiveDir)] (let [entryFiles (FileSystem.readDirectory (Path.join [archiveDir "entries"]))]
(for file entryFiles =>(file.withoutExtension) ~(the Entry (Json.parse (File.getContent (Path.join [archiveDir file])))))) (for file entryFiles =>(file.withoutExtension) ~(the Entry (Json.parse (File.getContent (Path.join [archiveDir "entries" file]))))))]
:Array<System> systems [
(the System (new TagSystem "song"))]] // Assign entries to the Systems that care about them
(doFor system systems (doFor system systems
(doFor =>id entry entries (doFor =>id entry entries
(when (system.canProcessEntry entry) (when (system.canProcessEntry entry)
(system.entries.push entry))))) (system.entries.push entry)))))
(defmethod :Void handleEvent [:Event e] (defun :Entry _newEntry []
(throw "can't handle $e")) (object
id (Uuid.v4)
(defmethod :Void process [] components (new Map)
(doFor system systems (system.process))) files []))

View File

@@ -1,7 +1,10 @@
package nap; package nap;
import kiss.KissInterp; import kiss.KissInterp;
import hscript.Parser;
import kiss.Prelude;
@:build(kiss.Kiss.build())
class BoolExpInterp extends KissInterp { class BoolExpInterp extends KissInterp {
public function new() { public function new() {
super(); super();

View File

@@ -0,0 +1,9 @@
(defun eval [:String expStr :Array<String> activeConditions]
(let [hscriptExp
(.parseString (new Parser)
(Prelude.convertToHScript expStr))
interp
(new BoolExpInterp)]
(doFor condition activeConditions
(interp.variables.set condition true))
?(interp.execute hscriptExp)))

View File

@@ -2,6 +2,6 @@ package nap;
typedef Entry = { typedef Entry = {
id:String, id:String,
name:String, components:Map<String, String>,
components:Map<String, Array<Dynamic>> files:Array<String>
}; };

View File

@@ -1,7 +0,0 @@
package nap;
/**
* All types of user input events to the NAP system. Archive handles these, acting as a backend
* for whichever front-end generates the Events.
*/
enum Event {}

View File

@@ -1,10 +1,11 @@
package nap; package nap;
import uuid.Uuid;
import kiss.Prelude; import kiss.Prelude;
import kiss.Stream; import sys.io.File;
import hscript.Parser; import tink.Json;
import hscript.Interp; import uuid.Uuid;
using haxe.io.Path;
@:build(kiss.Kiss.build()) @:build(kiss.Kiss.build())
class Lib {} class Lib {}

View File

@@ -1,15 +1,20 @@
(defun evalBoolExp [:String expStr :Array<String> activeConditions] // Lib is its own class because, while it would make sense to group its functions and macros in Archive.kiss,
(let [hscriptExp // other files would not be able to (load "Archive.kiss") for the macro definitions without taking on Archive's constructor.
(.parseString (new Parser)
(Prelude.convertToHScript expStr))
interp
(new BoolExpInterp)]
(doFor condition activeConditions
(interp.variables.set condition true))
?(interp.execute hscriptExp)))
(defun :Entry newEntry [:String name] (defmacro hasComponent [e componentType]
(object `(.exists .components ,e ,(symbolName componentType)))
id (Uuid.v4)
name name // TODO add to the documentation a hint that macros should use fully qualified paths so macro caller classes don't need to import everything
components (new Map))) (defmacro getComponent [archive e componentType]
`(the nap.components ,componentType
(tink.Json.parse
(sys.io.File.getContent
(haxe.io.Path.join [.archiveDir (the nap.Archive ,archive) "components" (+ (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType)) ".json")])))))
(defun tagList [archive e]
(let [t
(getComponent archive e Tags)]
(collect (t.keys))))
(defun tagsMatch [archive e tagsBoolExp]
(BoolExpInterp.eval tagsBoolExp (tagList archive e)))

View File

@@ -1,7 +0,0 @@
package nap;
import kiss.Kiss;
import kiss.Prelude;
@:build(kiss.Kiss.build())
class Main {}

View File

@@ -1,27 +0,0 @@
(defun :Void main []
~(Lib.evalBoolExp "true" [])
~(Lib.evalBoolExp "false" [])
~(Lib.evalBoolExp "flag" [])
~(Lib.evalBoolExp "flag" ["flag"])
~(Lib.evalBoolExp "(and flag false)" ["flag"])
~(Lib.evalBoolExp "(or flag otherFlag)" ["otherFlag"])
//trace(error);
(let [archiveDir
// TODO optional flags like --cache will complicate this way of handling args
(.shift (Sys.args))
archive
(new Archive archiveDir)]
// TODO run a front-end -- could be a test frontend that sends predetermined list of events
(archive.process)))
/*
(let [e (new Entry "name")]
(dictSet e.components "f" [5])
(dictSet e.components "b" [(object c "d")])
(let [s (haxe.Json.stringify e)
:Entry e2 (haxe.Json.parse s)]
// can't call Entry methods on e2
(print s))))
*/

View File

@@ -1,3 +0,0 @@
package nap.components;
typedef Tag = String;

View File

@@ -1,2 +0,0 @@
(defun :Array<String> getTags [:Entry e]
(or (dictGet e.components "Tag") []))

View File

@@ -0,0 +1,3 @@
package nap.components;
typedef Tags = Map<String, Int>;

View File

@@ -1,6 +1,4 @@
(load "../components/Tag.kiss")
(defnew [&prop :String tagFilterString] []) (defnew [&prop :String tagFilterString] [])
(defmethod &override :Bool canProcessEntry [:Entry e] (defmethod &override :Bool canProcessEntry [:Entry e] (print false))
(Lib.evalBoolExp tagFilterString (getTags e))) // (Lib.evalBoolExp tagFilterString (getTags e)))

View File

@@ -4,6 +4,8 @@ import kiss.Kiss;
import kiss.Prelude; import kiss.Prelude;
import nap.BoolExpInterp; import nap.BoolExpInterp;
import nap.Archive; import nap.Archive;
import nap.Lib;
import nap.components.*;
@:build(kiss.Kiss.build()) @:build(kiss.Kiss.build())
class TestMain {} class TestMain {}

View File

@@ -1,3 +1,7 @@
// TODO external programs need to be able to find and (load) this path to get the macros:
(load "../nap/Lib.kiss")
(defun :Void main [] (defun :Void main []
(assert (BoolExpInterp.eval "true" [])) (assert (BoolExpInterp.eval "true" []))
(assert !(BoolExpInterp.eval "false" [])) (assert !(BoolExpInterp.eval "false" []))
@@ -9,17 +13,16 @@
(let [systems (let [systems
[] []
archive archive
(new Archive "src/test/example-archive" systems)] (new Archive "src/test/example-archive" systems)
(print "TODO"))) song1
(dictGet archive.entries "song1")
song2
(dictGet archive.entries "song2")]
/*
(let [e (new Entry "name")] (assert (hasComponent song1 Tags))
(dictSet e.components "f" [5]) (assert (hasComponent song2 Tags))
(dictSet e.components "b" [(object c "d")]) (assert (tagsMatch archive song1 "(and song western)"))
(let [s (haxe.Json.stringify e) (assert !(tagsMatch archive song1 "(and song religious)"))
:Entry e2 (haxe.Json.parse s)] (assert (tagsMatch archive song2 "(and song religious)"))
// can't call Entry methods on e2 (assert !(tagsMatch archive song2 "(and song western)"))
(print s)))) ))
*/

6
projects/nap/test.hxml Normal file
View File

@@ -0,0 +1,6 @@
-D test
-lib kiss
-lib nap
-cp test
--main test.TestMain
--interp

View File

@@ -1,4 +1,4 @@
#! /bin/bash #! /bin/bash
haxelib dev nap . haxelib dev nap .
haxelib run nap example-archive haxe test.hxml