diff --git a/mshell/Program.cs b/mshell/Program.cs index 4d1af83..e1c1168 100755 --- a/mshell/Program.cs +++ b/mshell/Program.cs @@ -116,6 +116,8 @@ private TokenNew ScanToken() return MakeToken(TokenType.EXECUTE); case '|': return MakeToken(TokenType.PIPE); + case '?': + return MakeToken(TokenType.QUESTION); default: return ParseLiteralOrNumber(); } @@ -157,7 +159,7 @@ private TokenNew ParseLiteralOrNumber() while (true) { char c = Peek(); - if (!char.IsWhiteSpace(c) && c != ']' && c != ')' && c != '<' && c != '>' && c != ';') Advance(); + if (!char.IsWhiteSpace(c) && c != ']' && c != ')' && c != '<' && c != '>' && c != ';' && c != '?') Advance(); else break; } @@ -279,6 +281,23 @@ public EvalResult Evaluate(List tokens, Stack stack, Exe } else return FailWithMessage($"Nothing on stack to duplicate for 'dup'.\n"); } + else if (t.RawText == "drop") + { + if (!stack.TryPop(out MShellObject? _)) + { + return FailWithMessage($"Nothing on stack to drop.\n"); + } + } + else if (t.RawText == ".s") + { + Console.Error.Write("Current stack:"); + + foreach (var v in stack) + { + Console.Error.Write(v.DebugString()); + Console.Error.Write('\n'); + } + } else { _push(new LiteralToken(t), stack); @@ -460,7 +479,7 @@ public EvalResult Evaluate(List tokens, Stack stack, Exe } else { - Console.Error.Write($"Can't evaluate condition for type.\n"); + return FailWithMessage($"Can't evaluate condition for type {condition.TypeName()}.\n"); } } else @@ -515,7 +534,7 @@ public EvalResult Evaluate(List tokens, Stack stack, Exe index++; } - else if (t.TokenType == TokenType.EXECUTE) + else if (t.TokenType == TokenType.EXECUTE || t.TokenType == TokenType.QUESTION) { if (stack.TryPop(out var arg)) { @@ -531,7 +550,10 @@ public EvalResult Evaluate(List tokens, Stack stack, Exe if (!result.Success) return result; - _push(new IntToken(new TokenNew(t.Line, t.Column, t.Start, exitCode.ToString(), TokenType.INTEGER)), stack); + if (t.TokenType == TokenType.QUESTION) + { + _push(new IntToken(new TokenNew(t.Line, t.Column, t.Start, exitCode.ToString(), TokenType.INTEGER)), stack); + } } else { @@ -918,6 +940,7 @@ private void ExecuteQuotation(MShellQuotation q) StartInfo = info }; + int exitCode; try { using (p) @@ -947,9 +970,9 @@ private void ExecuteQuotation(MShellQuotation q) } p.WaitForExit(); - // Console.Out.Write(stdout); // Console.Error.Write(stderr); + exitCode = p.ExitCode; } } catch (Exception e) @@ -957,7 +980,7 @@ private void ExecuteQuotation(MShellQuotation q) return (FailWithMessage($"There was an exception running process with args { string.Join(", ", arguments.Select(s => $"'{s}'")) }.\n{e.Message}\n"), 1); } - return (new EvalResult(true, -1), p.ExitCode); + return (new EvalResult(true, -1), exitCode); } public (EvalResult, int) RunProcess(MShellPipe pipe, ExecuteContext context) @@ -1064,8 +1087,10 @@ private void ExecuteQuotation(MShellQuotation q) } foreach (var p in processes) p.WaitForExit(); + var exitCodes = processes.Select(process => process.ExitCode).ToList(); + foreach (var p in processes) p.Dispose(); - return (new EvalResult(true, -1), 1); + return (new EvalResult(true, -1), exitCodes.Last()); } public byte[] ReadAllBytesFromStream(Stream stream) @@ -1120,6 +1145,7 @@ public enum TokenType PLUS, PIPE, INTERPRET, + QUESTION } public class TokenNew diff --git a/mshell/tests/if_on_process.msh b/mshell/tests/if_on_process.msh new file mode 100644 index 0000000..a9da131 --- /dev/null +++ b/mshell/tests/if_on_process.msh @@ -0,0 +1,7 @@ +[ + # This is running the process command false. The '?' pushes the exit code on the stack when finished. + # 0 results in the true branch in mshell. + (["false"]?) + ([echo "The command run had a successful exit code"];) + ([echo "The command run had an unsuccessful code"];) +] if diff --git a/mshell/tests/if_on_process.msh.stdout b/mshell/tests/if_on_process.msh.stdout new file mode 100644 index 0000000..f3e8569 --- /dev/null +++ b/mshell/tests/if_on_process.msh.stdout @@ -0,0 +1 @@ +The command run had an unsuccessful code