``` shell script reader macro
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user