``` shell script reader macro

This commit is contained in:
2022-05-20 22:43:35 +00:00
parent f5359ff118
commit 97b5271ec0
2 changed files with 63 additions and 8 deletions

View File

@@ -643,6 +643,30 @@ class Prelude {
return assertProcess("haxelib", ["libpath", haxelibName]).trim();
}
public static function shellExecute(script:String, shell:String) {
#if (sys || hxnodejs)
if (shell.length == 0) {
shell = if (Sys.systemName() == "Windows") "cmd /c" else "bash";
}
var tempScript = 'tempScript.${shell.split(" ")[0]}';
File.saveContent(tempScript, script);
try {
if (Sys.systemName() != "Windows") tempScript = joinPath(Sys.getCwd(), tempScript);
var parts = shell.split(" ").concat([tempScript]);
var shell = parts.shift();
assertProcess(shell, parts);
FileSystem.deleteFile(tempScript);
} catch (e) {
FileSystem.deleteFile(tempScript);
throw e;
}
#else
throw "Can't run a shell script on this target.";
#end
}
public static function filter<T>(l:Iterable<T>, ?p:(T) -> Bool):kiss.List<T> {
if (p == null)
p = Prelude.truthy;

View File

@@ -8,6 +8,7 @@ import kiss.ReaderExp;
using kiss.Reader;
using kiss.Stream;
using kiss.Helpers;
using StringTools;
class UnmatchedBracketSignal {
public var type:String;
@@ -107,6 +108,21 @@ class Reader {
readTable[","] = (stream:Stream, k) -> Unquote(assertRead(stream, k));
readTable[",@"] = (stream:Stream, k) -> UnquoteList(assertRead(stream, k));
// Command line syntax:
readTable["```"] = (stream:Stream, k) -> {
var shell = switch (stream.takeLine()) {
case Some(shell): shell;
default: "";
};
var pos = stream.position();
var script = readString(stream, k, true).withPos(pos);
CallExp(
Symbol("Prelude.shellExecute").withPos(pos), [
script,
StrExp(shell).withPos(pos)
]);
};
// Lambda arrow syntaxes:
// ->[args] body
// ->arg body
@@ -363,7 +379,9 @@ class Reader {
do {
var next = switch (stream.takeChars(1)) {
case Some(c): c;
default: throw new StreamError(pos, 'Unterminated string literal. Expected "');
default:
var type = if (shell) "shell block" else "string literal";
throw new StreamError(pos, 'Unterminated $type. Expected $terminator');
}
switch (next) {
@@ -390,14 +408,27 @@ class Reader {
stream.error('unsupported escape sequence \\$escapeSequence');
return null;
}
case t if (t == terminator):
endCurrentStringPart();
return if (stringParts.length == 1) {
stringParts[0].def;
case t if (terminator.startsWith(t)):
if (terminator.length == 1 ||
switch (stream.takeChars(terminator.length - 1)) {
case Some(rest) if (rest == terminator.substr(1)):
true;
case Some(other):
stream.putBackString(other);
false;
default:
throw new StreamError(pos, 'Unterminated shell block. Expected $terminator');
}) {
endCurrentStringPart();
return if (stringParts.length == 1) {
stringParts[0].def;
} else {
var b = stringParts[0].expBuilder();
b.the(b.symbol("String"), b.callSymbol("+", stringParts)).def;
};
} else {
var b = stringParts[0].expBuilder();
b.the(b.symbol("String"), b.callSymbol("+", stringParts)).def;
};
currentStringPart += t;
}
default:
currentStringPart += next;
}