Make syntax more readable

This commit is contained in:
Stone_Red
2026-03-04 14:04:00 +01:00
parent 11200cbff8
commit 9d43f1373f
12 changed files with 216 additions and 98 deletions
+16 -1
View File
@@ -2,4 +2,19 @@
> YesNt is a imperative and interpreted language inspired by the Assembly language. > YesNt is a imperative and interpreted language inspired by the Assembly language.
Check out the [Wiki](https://github.com/Stone-Red-Code/YesNt-Interpreter/wiki) (Work in progress) ## Syntax
Current language syntax is documented in [SYNTAX_V2.md](SYNTAX_V2.md).
Example:
```ynt
let name = world
print_line Hello ${name}
```
## Run
```bash
dotnet run --project YesNt.Interpreter -- path/to/script.ynt
```
+93
View File
@@ -0,0 +1,93 @@
# YesNt v2 Syntax
This document describes the current, word-based YesNt syntax.
## Goals
- Keep current semantics and execution model.
- Replace terse mnemonics and symbols with readable words.
- Preserve line-based scripting.
- Keep the language line-based and lightweight.
## v2 Core Rules
- Statements are line-based.
- `# ...` remains a comment.
- Variable interpolation inside text uses `${name}`.
- Function and label declarations are block markers with a trailing `:`.
- Conditions retain current evaluator expressions (for example: `a == b`, `x > 5`, `10 + 2 == 12`).
## Quick Example
v1:
```ynt
<name = world
fnc greet
cwl Hello >name
ret
cal greet
```
v2:
```ynt
let name = world
func greet:
print_line Hello ${name}
return
call greet
```
## Full v1 -> v2 Mapping
| Area | v1 Syntax | v2 Syntax | Notes |
|---|---|---|---|
| Variables | `<x = value` | `let x = value` | Local variable define/update. |
| Variables | `!<x = value` | `global x = value` | Global variable define/update. |
| Variables | `del x` | `delete x` | Deletes local first, then global. |
| Variables | `>x` | `${x}` | Variable read/interpolation token. |
| Console | `cwl` | `print_line` | Empty line print. |
| Console | `cwl text` | `print_line text` | Print with newline. |
| Console | `cw text` | `print text` | Print without newline. |
| Console | `%crl` | `%read_line` | Inline token, inserts user line input. |
| Console | `%cr` | `%read_key` | Inline token, inserts user key input. |
| Console | `cls` | `clear` | Clear console. |
| Code flow | `lbl name` | `label name:` | Label declaration/target. |
| Code flow | `jmp name` | `goto name` | Unconditional jump. |
| Code flow | `jif name \| cond` | `if cond goto name` | Conditional jump. |
| Functions | `fnc name` | `func name:` | Function declaration. |
| Functions | `cal name` | `call name` | Function call without args. |
| Functions | `cal name \| a,b,c` | `call name with a, b, c` | Function call with args. |
| Functions | `in value` | `push_in value` | Push in-arg onto input stack. |
| Functions | `%get` | `%in` | Inline token, pop current call input arg. |
| Functions | `%isi` | `%has_in` | Inline token, bool if input arg exists. |
| Functions | `put value` | `push_out value` | Push out-arg in function. |
| Functions | `%out` | `%out` | Keep token name for familiarity. |
| Functions | `%iso` | `%has_out` | Inline token, bool if out arg exists. |
| Functions | `ret` | `return` | Return from function. |
| Functions | `ccs` | `clear_call_stack` | Clear call stack. |
| Condition-call | `cif name \| cond` | `if cond call name` | Conditional function call. |
| Termination | `end` | `exit` | Planned termination. |
| Termination | `trm` | `abort_all` | Planned termination + cancel tasks. |
| Errors | `trw message` | `throw message` | Error termination. |
| Errors | `err message` | `error message` | Non-fatal/runtime message end state. |
| Processing | `expr !calc` | `expr calc` | Evaluate arithmetic fragments. |
| Processing | `text !eval` | `text eval` | Decode safe string literals. |
| Processing | `line !task` | `line task` | Run line in background task runtime. |
| Processing | `slp ms` | `sleep ms` | Sleep with runtime-aware cancellation. |
| Processing | `len text` | `length text` | Push text length to out stack. |
| Processing | `imp file` | `import file` | Inline include of another `.ynt` file. |
| System | `exc prog` | `exec prog` | Execute process with in-stack args. |
| System | `exc prog \| a,b,c` | `exec prog with a, b, c` | Execute process with explicit args. |
| Predefined | `%time` | `%time` | Unix timestamp token. |
| Predefined | `%os` | `%os` | OS platform token. |
| Predefined | `%cpu` | `%cpu` | Processor architecture token. |
| Predefined | `%is64` | `%is64` | 64-bit OS bool token. |
| Predefined | `%pi` | `%pi` | PI token. |
| Predefined | `%rnd` | `%rand` | Random number token. |
## Notes
- `%out` is intentionally kept as `%out`.
- Postfix operations are `calc`, `eval`, and `task`.
+4 -4
View File
@@ -167,15 +167,15 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
return result; return result;
} }
[GeneratedRegex("^<[a-zA-Z0-9]+")] [GeneratedRegex("^let\\s+[a-zA-Z0-9]+")]
private static partial Regex VariableDeclarationRegex(); private static partial Regex VariableDeclarationRegex();
[GeneratedRegex("^!<[a-zA-Z0-9]+")] [GeneratedRegex("^global\\s+[a-zA-Z0-9]+")]
private static partial Regex GlobalVariableDeclarationRegex(); private static partial Regex GlobalVariableDeclarationRegex();
[GeneratedRegex(">[a-zA-Z0-9]+")] [GeneratedRegex("\\$\\{[a-zA-Z0-9]+\\}")]
private static partial Regex VariableRegex(); private static partial Regex VariableRegex();
[GeneratedRegex("(?<=(\\v))(.*)(?=\\v)")] [GeneratedRegex("(?<=(\\v))(.*)(?=\\v)")]
private static partial Regex StringColorRegex(); private static partial Regex StringColorRegex();
} }
@@ -12,11 +12,11 @@ public class CodeFlowTests
{ {
List<string> lines = List<string> lines =
[ [
"cal yes", "call yes",
"fnc yes", "func yes:",
"!<result = 1", "global result = 1",
"ret", "return",
">result" "${result}"
]; ];
YesNtAssert.IsLastLineEqual(lines, "1"); YesNtAssert.IsLastLineEqual(lines, "1");
} }
@@ -26,12 +26,12 @@ public class CodeFlowTests
{ {
List<string> lines = List<string> lines =
[ [
"<result = 1", "let result = 1",
"jmp yes", "goto yes",
"<result = 0", "let result = 0",
"lbl yes", "label yes:",
">result" "${result}"
]; ];
YesNtAssert.IsLastLineEqual(lines, "1"); YesNtAssert.IsLastLineEqual(lines, "1");
} }
} }
@@ -8,36 +8,36 @@ public class ProcessingStatementsTests
[TestMethod] [TestMethod]
public void MultiplicationTest() public void MultiplicationTest()
{ {
YesNtAssert.IsLineEqual("10 * 10 !calc", "100"); YesNtAssert.IsLineEqual("10 * 10 calc", "100");
} }
[TestMethod] [TestMethod]
public void DivisionTest() public void DivisionTest()
{ {
YesNtAssert.IsLineEqual("90 / 4 !calc", "22.5"); YesNtAssert.IsLineEqual("90 / 4 calc", "22.5");
} }
[TestMethod] [TestMethod]
public void AdditionTest() public void AdditionTest()
{ {
YesNtAssert.IsLineEqual("10 + 10 !calc", "20"); YesNtAssert.IsLineEqual("10 + 10 calc", "20");
} }
[TestMethod] [TestMethod]
public void SubtractionTest() public void SubtractionTest()
{ {
YesNtAssert.IsLineEqual("10 - 10 !calc", "0"); YesNtAssert.IsLineEqual("10 - 10 calc", "0");
} }
[TestMethod] [TestMethod]
public void ModulusTest() public void ModulusTest()
{ {
YesNtAssert.IsLineEqual("10 % 3 !calc", "1"); YesNtAssert.IsLineEqual("10 % 3 calc", "1");
} }
[TestMethod] [TestMethod]
public void ExponentiationTest() public void ExponentiationTest()
{ {
YesNtAssert.IsLineEqual("2 ^ 3 !calc", "8"); YesNtAssert.IsLineEqual("2 ^ 3 calc", "8");
} }
} }
@@ -10,10 +10,10 @@ namespace YesNt.Interpreter.Statements;
internal class CodeFlowStatements : StatementRuntimeInformation internal class CodeFlowStatements : StatementRuntimeInformation
{ {
[Statement("jmp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow)] [Statement("goto", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow)]
public void Jump(string args) public void Jump(string args)
{ {
string key = args.Trim(); string key = NormalizeBlockName(args);
if (RuntimeInfo.Labels.TryGetValue(key, out int value)) if (RuntimeInfo.Labels.TryGetValue(key, out int value))
{ {
@@ -26,18 +26,18 @@ internal class CodeFlowStatements : StatementRuntimeInformation
} }
} }
[Statement("jif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow, Separator = "|")] [Statement("if", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, Priority = Priority.VeryLow, Separator = " goto ")]
public void JumpIf(string args) public void JumpIf(string args)
{ {
string[] parts = args.Split('|'); string[] parts = args.Split(" goto ", 2, StringSplitOptions.None);
if (parts.Length != 2) if (parts.Length != 2)
{ {
RuntimeInfo.Exit("Invalid syntax", true); RuntimeInfo.Exit("Invalid syntax", true);
return; return;
} }
string key = parts[0].Trim(); string condition = parts[0].Trim();
string condition = parts[1].Trim(); string key = NormalizeBlockName(parts[1]);
bool? result = Evaluator.EvaluateCondition(condition); bool? result = Evaluator.EvaluateCondition(condition);
@@ -63,10 +63,10 @@ internal class CodeFlowStatements : StatementRuntimeInformation
} }
} }
[Statement("lbl", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, ExecuteInSearchMode = true)] [Statement("label", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Green, ExecuteInSearchMode = true)]
public void FindLabel(string args) public void FindLabel(string args)
{ {
string key = args.Trim(); string key = NormalizeBlockName(args);
if (RuntimeInfo.Labels.ContainsKey(key)) if (RuntimeInfo.Labels.ContainsKey(key))
{ {
RuntimeInfo.Labels[key] = RuntimeInfo.LineNumber; RuntimeInfo.Labels[key] = RuntimeInfo.LineNumber;
@@ -83,10 +83,10 @@ internal class CodeFlowStatements : StatementRuntimeInformation
} }
} }
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow)] [Statement("call", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow)]
public void Call(string args) public void Call(string args)
{ {
string key = args.Trim(); string key = NormalizeBlockName(args);
RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack))); RuntimeInfo.FunctionCallStack.Push(new FunctionScope(RuntimeInfo.LineNumber, new Stack<string>(RuntimeInfo.InParametersStack)));
RuntimeInfo.InParametersStack.Clear(); RuntimeInfo.InParametersStack.Clear();
@@ -101,18 +101,18 @@ internal class CodeFlowStatements : StatementRuntimeInformation
} }
} }
[Statement("cif", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow, Separator = "|")] [Statement("if", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.VeryLow, Separator = " call ")]
public void CallIf(string args) public void CallIf(string args)
{ {
string[] parts = args.Split('|'); string[] parts = args.Split(" call ", 2, StringSplitOptions.None);
if (parts.Length != 2) if (parts.Length != 2)
{ {
RuntimeInfo.Exit("Invalid syntax", true); RuntimeInfo.Exit("Invalid syntax", true);
return; return;
} }
string key = parts[0].Trim(); string condition = parts[0].Trim();
string condition = parts[1].Trim(); string key = NormalizeBlockName(parts[1]);
bool? result = Evaluator.EvaluateCondition(condition); bool? result = Evaluator.EvaluateCondition(condition);
@@ -140,7 +140,7 @@ internal class CodeFlowStatements : StatementRuntimeInformation
} }
} }
[Statement("end", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)] [Statement("exit", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void End(string _) public void End(string _)
{ {
if (RuntimeInfo.IsSearching) if (RuntimeInfo.IsSearching)
@@ -161,7 +161,7 @@ internal class CodeFlowStatements : StatementRuntimeInformation
RuntimeInfo.Exit("Planned termination by code", false); RuntimeInfo.Exit("Planned termination by code", false);
} }
[Statement("trm", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)] [Statement("abort_all", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red, ExecuteInSearchMode = true)]
public void Terminate(string _) public void Terminate(string _)
{ {
if (RuntimeInfo.IsSearching) if (RuntimeInfo.IsSearching)
@@ -182,15 +182,20 @@ internal class CodeFlowStatements : StatementRuntimeInformation
RuntimeInfo.Exit("Planned termination by code. Canceling all tasks", true); RuntimeInfo.Exit("Planned termination by code. Canceling all tasks", true);
} }
[Statement("trw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)] [Statement("throw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Throw(string message) public void Throw(string message)
{ {
RuntimeInfo.Exit(message, true); RuntimeInfo.Exit(message, true);
} }
[Statement("err", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)] [Statement("error", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Red)]
public void Error(string message) public void Error(string message)
{ {
RuntimeInfo.Exit(message, false); RuntimeInfo.Exit(message, false);
} }
}
private static string NormalizeBlockName(string value)
{
return value.Trim().TrimEnd(':').Trim();
}
}
@@ -10,29 +10,29 @@ namespace YesNt.Interpreter.Statements;
internal class ConsoleStatements : StatementRuntimeInformation internal class ConsoleStatements : StatementRuntimeInformation
{ {
[Statement("cwl", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)] [Statement("print_line", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)]
public void WriteLineEmpty(string _) public void WriteLineEmpty(string _)
{ {
RuntimeInfo.WriteLine(string.Empty); RuntimeInfo.WriteLine(string.Empty);
} }
[Statement("cwl", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)] [Statement("print_line", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)]
public void WriteLine(string args) public void WriteLine(string args)
{ {
RuntimeInfo.WriteLine(args); RuntimeInfo.WriteLine(args);
} }
[Statement("cw", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)] [Statement("print", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkGreen, Priority = Priority.VeryLow)]
public void Write(string args) public void Write(string args)
{ {
RuntimeInfo.Write(args); RuntimeInfo.Write(args);
} }
[Statement("%crl", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%read_line", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void ReadLine(string args) public void ReadLine(string args)
{ {
args += " "; args += " ";
while (args.Contains("%crl")) while (args.Contains("%read_line"))
{ {
string input = Console.ReadLine(); string input = Console.ReadLine();
if (input is null) if (input is null)
@@ -40,27 +40,27 @@ internal class ConsoleStatements : StatementRuntimeInformation
RuntimeInfo.Exit("Terminated by external process", true); RuntimeInfo.Exit("Terminated by external process", true);
return; return;
} }
args = args.ReplaceFirstOccurrence("%crl ", input.ToSafeString() + " "); args = args.ReplaceFirstOccurrence("%read_line ", input.ToSafeString() + " ");
} }
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%cr", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%read_key", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkGreen, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void ReadKey(string args) public void ReadKey(string args)
{ {
args += " "; args += " ";
while (args.Contains("%cr")) while (args.Contains("%read_key"))
{ {
string input = ConsoleExtensions.ReadKey(RuntimeInfo).ToString(); string input = ConsoleExtensions.ReadKey(RuntimeInfo).ToString();
args = args.ReplaceFirstOccurrence("%cr ", input.ToSafeString() + " "); args = args.ReplaceFirstOccurrence("%read_key ", input.ToSafeString() + " ");
} }
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("cls", SearchMode.Exact, SpaceAround.None, ConsoleColor.Magenta)] [Statement("clear", SearchMode.Exact, SpaceAround.None, ConsoleColor.Magenta)]
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Won't work if static")] [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Won't work if static")]
public void Clear(string _) public void Clear(string _)
{ {
Console.Clear(); Console.Clear();
} }
} }
@@ -10,7 +10,7 @@ namespace YesNt.Interpreter.Statements;
internal class FunctionStatements : StatementRuntimeInformation internal class FunctionStatements : StatementRuntimeInformation
{ {
[Statement("fnc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)] [Statement("func", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
public void FindFunction(string args) public void FindFunction(string args)
{ {
if (RuntimeInfo.InternalIsInFunction) if (RuntimeInfo.InternalIsInFunction)
@@ -19,7 +19,7 @@ internal class FunctionStatements : StatementRuntimeInformation
return; return;
} }
string key = args.Trim(); string key = NormalizeBlockName(args);
if (RuntimeInfo.Functions.ContainsKey(key)) if (RuntimeInfo.Functions.ContainsKey(key))
{ {
RuntimeInfo.Functions[key] = RuntimeInfo.LineNumber; RuntimeInfo.Functions[key] = RuntimeInfo.LineNumber;
@@ -37,7 +37,7 @@ internal class FunctionStatements : StatementRuntimeInformation
RuntimeInfo.IsInFunction = true; RuntimeInfo.IsInFunction = true;
} }
[Statement("in", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)] [Statement("push_in", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void AddInParameter(string args) public void AddInParameter(string args)
{ {
RuntimeInfo.InParametersStack.Push(args); RuntimeInfo.InParametersStack.Push(args);
@@ -60,25 +60,25 @@ internal class FunctionStatements : StatementRuntimeInformation
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%iso", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%has_out", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void CheckIfOutParameterAvailable(string args) public void CheckIfOutParameterAvailable(string args)
{ {
args = args.Replace("%iso", (RuntimeInfo.OutParametersStack.Count > 0).ToString()); args = args.Replace("%has_out", (RuntimeInfo.OutParametersStack.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("cal", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.Low, Separator = "|")] [Statement("call", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.DarkYellow, Priority = Priority.Low, Separator = " with ")]
public void Call(string args) public void Call(string args)
{ {
string[] parts = args.Split('|'); string[] parts = args.Split(" with ", 2, StringSplitOptions.None);
if (parts.Length != 2) if (parts.Length != 2)
{ {
RuntimeInfo.Exit("Invalid syntax", true); RuntimeInfo.Exit("Invalid syntax", true);
return; return;
} }
string key = parts[0].Trim(); string key = NormalizeBlockName(parts[0]);
string[] functionArguments = parts[1].Split(','); string[] functionArguments = parts[1].Split(',');
foreach (string argument in functionArguments) foreach (string argument in functionArguments)
@@ -100,7 +100,7 @@ internal class FunctionStatements : StatementRuntimeInformation
} }
} }
[Statement("%get", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%in", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetInParameter(string args) public void GetInParameter(string args)
{ {
if (!RuntimeInfo.IsInFunction) if (!RuntimeInfo.IsInFunction)
@@ -109,7 +109,7 @@ internal class FunctionStatements : StatementRuntimeInformation
return; return;
} }
while (args.Contains("%get")) while (args.Contains("%in"))
{ {
if (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count == 0) if (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count == 0)
{ {
@@ -117,13 +117,13 @@ internal class FunctionStatements : StatementRuntimeInformation
return; return;
} }
args = args.ReplaceFirstOccurrence("%get", RuntimeInfo.FunctionCallStack.Peek().Arguments.Pop()); args = args.ReplaceFirstOccurrence("%in", RuntimeInfo.FunctionCallStack.Peek().Arguments.Pop());
} }
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%isi", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%has_in", SearchMode.Contains, SpaceAround.None, ConsoleColor.Yellow, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void CheckIfInParameterAvailable(string args) public void CheckIfInParameterAvailable(string args)
{ {
if (!RuntimeInfo.IsInFunction) if (!RuntimeInfo.IsInFunction)
@@ -132,12 +132,12 @@ internal class FunctionStatements : StatementRuntimeInformation
return; return;
} }
args = args.Replace("%isi", (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count > 0).ToString()); args = args.Replace("%has_in", (RuntimeInfo.FunctionCallStack.Peek().Arguments.Count > 0).ToString());
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("put", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)] [Statement("push_out", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Yellow)]
public void AddOutParameter(string args) public void AddOutParameter(string args)
{ {
if (!RuntimeInfo.IsInFunction) if (!RuntimeInfo.IsInFunction)
@@ -149,7 +149,7 @@ internal class FunctionStatements : StatementRuntimeInformation
RuntimeInfo.FunctionCallStack.Peek().Results.Push(args); RuntimeInfo.FunctionCallStack.Peek().Results.Push(args);
} }
[Statement("ret", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)] [Statement("return", SearchMode.Exact, SpaceAround.None, ConsoleColor.DarkYellow, ExecuteInSearchMode = true)]
public void Return(string _) public void Return(string _)
{ {
if (!RuntimeInfo.IsInFunction) if (!RuntimeInfo.IsInFunction)
@@ -186,9 +186,14 @@ internal class FunctionStatements : StatementRuntimeInformation
} }
} }
[Statement("ccs", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red)] [Statement("clear_call_stack", SearchMode.Exact, SpaceAround.None, ConsoleColor.Red)]
public void ClearCallStack(string _) public void ClearCallStack(string _)
{ {
RuntimeInfo.FunctionCallStack.Clear(); RuntimeInfo.FunctionCallStack.Clear();
} }
}
private static string NormalizeBlockName(string value)
{
return value.Trim().TrimEnd(':').Trim();
}
}
@@ -51,14 +51,14 @@ internal class PredefinedVariableStatements : StatementRuntimeInformation
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
[Statement("%rnd", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)] [Statement("%rand", SearchMode.Contains, SpaceAround.None, ConsoleColor.Blue, KeepStatementInArgs = true, Priority = Priority.Highest)]
public void GetRandom(string args) public void GetRandom(string args)
{ {
while (args.Contains("%rnd")) while (args.Contains("%rand"))
{ {
args = args.ReplaceFirstOccurrence("%rnd", random.Next(32767, int.MaxValue).ToString()); args = args.ReplaceFirstOccurrence("%rand", random.Next(32767, int.MaxValue).ToString());
} }
RuntimeInfo.CurrentLine = args.TrimEnd(); RuntimeInfo.CurrentLine = args.TrimEnd();
} }
} }
@@ -13,7 +13,7 @@ namespace YesNt.Interpreter.Statements;
internal partial class ProcessingStatements : StatementRuntimeInformation internal partial class ProcessingStatements : StatementRuntimeInformation
{ {
[Statement("!calc", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.High)] [Statement("calc", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.High)]
public void Calculate(string args) public void Calculate(string args)
{ {
MatchCollection matches = CalculationRegex().Matches(args.FromSafeString()); MatchCollection matches = CalculationRegex().Matches(args.FromSafeString());
@@ -32,13 +32,13 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
RuntimeInfo.CurrentLine = args; RuntimeInfo.CurrentLine = args;
} }
[Statement("!eval", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)] [Statement("eval", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void Evaluate(string args) public void Evaluate(string args)
{ {
RuntimeInfo.CurrentLine = args.FromSafeString(); RuntimeInfo.CurrentLine = args.FromSafeString();
} }
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)] [Statement("task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
public void RunTask(string line) public void RunTask(string line)
{ {
int lineNumber = RuntimeInfo.LineNumber; int lineNumber = RuntimeInfo.LineNumber;
@@ -57,7 +57,7 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
RuntimeInfo.CurrentLine = string.Empty; RuntimeInfo.CurrentLine = string.Empty;
} }
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)] [Statement("sleep", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Sleep(string args) public void Sleep(string args)
{ {
if (int.TryParse(args, out int millisecondsTimeout)) if (int.TryParse(args, out int millisecondsTimeout))
@@ -70,7 +70,7 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
} }
} }
[Statement("len", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)] [Statement("length", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Length(string args) public void Length(string args)
{ {
RuntimeInfo.InParametersStack.Clear(); RuntimeInfo.InParametersStack.Clear();
@@ -79,7 +79,7 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
RuntimeInfo.OutParametersStack.Push(args.FromSafeString().Length.ToString()); RuntimeInfo.OutParametersStack.Push(args.FromSafeString().Length.ToString());
} }
[Statement("imp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)] [Statement("import", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
public void Import(string path) public void Import(string path)
{ {
path = Path.Combine(RuntimeInfo.WorkingDirectory, path); path = Path.Combine(RuntimeInfo.WorkingDirectory, path);
@@ -115,4 +115,4 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
[GeneratedRegex("[0-9*+().,^%/-]+[0-9*+ ().,^%/-]+[0-9*+().,^%/-]+")] [GeneratedRegex("[0-9*+().,^%/-]+[0-9*+ ().,^%/-]+[0-9*+().,^%/-]+")]
private static partial Regex CalculationRegex(); private static partial Regex CalculationRegex();
} }
@@ -14,10 +14,10 @@ namespace YesNt.Interpreter.Statements;
internal class SystemStatements : StatementRuntimeInformation internal class SystemStatements : StatementRuntimeInformation
{ {
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.Low, Separator = "|")] [Statement("exec", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.Low, Separator = " with ")]
public void ExecuteProgramWithArgs(string input) public void ExecuteProgramWithArgs(string input)
{ {
string[] parts = input.FromSafeString().Split('|'); string[] parts = input.FromSafeString().Split(" with ", 2, StringSplitOptions.None);
parts[0] = parts[0].Trim(); parts[0] = parts[0].Trim();
string[] functionArguments = parts[1].Split(','); string[] functionArguments = parts[1].Split(',');
@@ -29,7 +29,7 @@ internal class SystemStatements : StatementRuntimeInformation
try try
{ {
StartProcess(parts[0], string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse())); StartProcess(parts[0], string.Join(" ", RuntimeInfo.InParametersStack.Reverse()));
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@@ -40,16 +40,16 @@ internal class SystemStatements : StatementRuntimeInformation
RuntimeInfo.Exit($"Failed to start \"{parts[0]}\". {ex.Message}", false); RuntimeInfo.Exit($"Failed to start \"{parts[0]}\". {ex.Message}", false);
} }
//HACK: Clear line to avoid execution from other "exc" statement // HACK: Clear line to avoid execution from another "exec" statement.
RuntimeInfo.CurrentLine = string.Empty; RuntimeInfo.CurrentLine = string.Empty;
} }
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.VeryLow)] [Statement("exec", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.VeryLow)]
public void ExecuteProgram(string input) public void ExecuteProgram(string input)
{ {
try try
{ {
StartProcess(input, string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse())); StartProcess(input, string.Join(" ", RuntimeInfo.InParametersStack.Reverse()));
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@@ -113,4 +113,4 @@ internal class SystemStatements : StatementRuntimeInformation
RuntimeInfo.OutParametersStack = new(outputStack); RuntimeInfo.OutParametersStack = new(outputStack);
RuntimeInfo.OutParametersStack.Push(process.ExitCode.ToString()); RuntimeInfo.OutParametersStack.Push(process.ExitCode.ToString());
} }
} }
@@ -8,7 +8,7 @@ namespace YesNt.Interpreter.Statements;
internal partial class VariableStatements : StatementRuntimeInformation internal partial class VariableStatements : StatementRuntimeInformation
{ {
[Statement("<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)] [Statement("let", SearchMode.StartOfLine, SpaceAround.End, Priority = Priority.VeryLow)]
public void DefineVariable(string args) public void DefineVariable(string args)
{ {
string[] parts = args.Split('='); string[] parts = args.Split('=');
@@ -35,7 +35,7 @@ internal partial class VariableStatements : StatementRuntimeInformation
} }
} }
[Statement("!<", SearchMode.StartOfLine, SpaceAround.None, Priority = Priority.VeryLow)] [Statement("global", SearchMode.StartOfLine, SpaceAround.End, Priority = Priority.VeryLow)]
public void DefineGlobalVariable(string args) public void DefineGlobalVariable(string args)
{ {
string[] parts = args.Split('='); string[] parts = args.Split('=');
@@ -62,7 +62,7 @@ internal partial class VariableStatements : StatementRuntimeInformation
} }
} }
[Statement("del", SearchMode.StartOfLine, SpaceAround.End, System.ConsoleColor.Red, Priority = Priority.VeryLow)] [Statement("delete", SearchMode.StartOfLine, SpaceAround.End, System.ConsoleColor.Red, Priority = Priority.VeryLow)]
public void DeleteVariable(string args) public void DeleteVariable(string args)
{ {
string key = args.Trim(); string key = args.Trim();
@@ -81,10 +81,10 @@ internal partial class VariableStatements : StatementRuntimeInformation
} }
} }
[Statement(">", SearchMode.Contains, SpaceAround.None, Priority = Priority.Highest)] [Statement("${", SearchMode.Contains, SpaceAround.None, Priority = Priority.Highest, Separator = "}")]
public void ReadVariable(string _) public void ReadVariable(string _)
{ {
if (!RuntimeInfo.CurrentLine.Contains('>')) if (!RuntimeInfo.CurrentLine.Contains("${"))
{ {
return; return;
} }
@@ -98,14 +98,14 @@ internal partial class VariableStatements : StatementRuntimeInformation
for (int i = 0; i < matches.Count; i++) for (int i = 0; i < matches.Count; i++)
{ {
string varName = matches[i].Value.Replace(">", string.Empty); string varName = matches[i].Groups[1].Value;
if (RuntimeInfo.Variables.TryGetValue(varName, out string value)) if (RuntimeInfo.Variables.TryGetValue(varName, out string value))
{ {
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value); RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace(matches[i].Value, value);
} }
else if (RuntimeInfo.GlobalVariables.TryGetValue(varName, out value)) else if (RuntimeInfo.GlobalVariables.TryGetValue(varName, out value))
{ {
RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace($">{varName}", value); RuntimeInfo.CurrentLine = RuntimeInfo.CurrentLine.Replace(matches[i].Value, value);
} }
else if (!RuntimeInfo.IsSearching) else if (!RuntimeInfo.IsSearching)
{ {
@@ -115,6 +115,6 @@ internal partial class VariableStatements : StatementRuntimeInformation
} }
} }
[GeneratedRegex(">[a-zA-Z0-9]+")] [GeneratedRegex("\\$\\{([a-zA-Z0-9]+)\\}")]
private static partial Regex VariableStatementRegex(); private static partial Regex VariableStatementRegex();
} }