From 6bdd496f61c592083dbefe95042a468f8edf30c5 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sun, 13 Jun 2021 23:20:03 -0600 Subject: [PATCH] (loadFrom [haxelib] [file]) macro --- src/kiss/Kiss.hx | 13 +++++++++---- src/kiss/Macros.hx | 26 ++++++++++++++++++++++++-- src/kiss/Main.hx | 1 + 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/kiss/Kiss.hx b/src/kiss/Kiss.hx index 3b6d63a..d1e22c2 100644 --- a/src/kiss/Kiss.hx +++ b/src/kiss/Kiss.hx @@ -124,9 +124,12 @@ class Kiss { }); } - public static function load(kissFile:String, k:KissState) { - k.loadedFiles[kissFile] = true; - var stream = Stream.fromFile(Path.join([k.loadingDirectory, kissFile])); + public static function load(kissFile:String, k:KissState, ?loadingDirectory:String) { + if (loadingDirectory == null) + loadingDirectory = k.loadingDirectory; + var fullPath = Path.join([loadingDirectory, kissFile]); + k.loadedFiles[fullPath] = true; + var stream = Stream.fromFile(fullPath); Reader.readAndProcess(stream, k, (nextExp) -> { #if test Sys.println(nextExp.def.toString()); @@ -134,7 +137,9 @@ class Kiss { var expr = readerExpToHaxeExpr(nextExp, k); - // if non-null, stuff it in main() + // TODO There are two ideas for how to handle expressions at the top level of a Kiss file: + // 1. Throw an error, because the top level should only contain field definitions + // 2. Append the expression to the body of an automatically generated main() function }); } diff --git a/src/kiss/Macros.hx b/src/kiss/Macros.hx index 129f6d7..590dbc7 100644 --- a/src/kiss/Macros.hx +++ b/src/kiss/Macros.hx @@ -6,10 +6,12 @@ import kiss.Reader; import kiss.ReaderExp; import kiss.Kiss; import kiss.CompileError; +import sys.io.Process; using kiss.Kiss; using kiss.Reader; using kiss.Helpers; +using StringTools; // Macros generate new Kiss reader expressions from the arguments of their call expression. typedef MacroFunction = (wholeExp:ReaderExp, args:Array, k:KissState) -> Null; @@ -19,14 +21,34 @@ class Macros { var macros:Map = []; macros["load"] = (wholeExp:ReaderExp, args:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, "(load \"[file]\")"); + wholeExp.checkNumArgs(1, 1, '(load "[file]")'); switch (args[0].def) { case StrExp(otherKissFile): if (!k.loadedFiles.exists(otherKissFile)) { Kiss.load(otherKissFile, k); } default: - throw CompileError.fromExp(args[0], "only argument to load should be a string literal"); + throw CompileError.fromExp(args[0], "only argument to load should be a string literal of a .kiss file path"); + } + null; + }; + + macros["loadFrom"] = (wholeExp:ReaderExp, args:Array, k:KissState) -> { + wholeExp.checkNumArgs(2, 2, '(loadFrom "[haxelib name]" "[file]")'); + + var libPath = switch (args[0].def) { + case StrExp(libName): + new Process("haxelib", ["libpath", libName]).stdout.readAll().toString().trim(); + default: + throw CompileError.fromExp(args[0], "first argument to loadFrom should be a string literal of a haxe library's name"); + }; + switch (args[1].def) { + case StrExp(otherKissFile): + if (!k.loadedFiles.exists(otherKissFile)) { + Kiss.load(otherKissFile, k, libPath); + } + default: + throw CompileError.fromExp(args[1], "second argument to loadFrom should be a string literal of a .kiss file path"); } null; }; diff --git a/src/kiss/Main.hx b/src/kiss/Main.hx index 426894f..d63dcfa 100644 --- a/src/kiss/Main.hx +++ b/src/kiss/Main.hx @@ -77,6 +77,7 @@ class Main { static function newProject(args:Array) { var name = promptFor("name"); + // TODO put the prompted description in a README.md var pkg = name.replace("-", "_"); var haxelibJson = { "name": name,