From 882c4f3a517016d6114fa814fe5763b9e6b49b50 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Wed, 4 Mar 2026 23:33:08 +0100 Subject: [PATCH] Add proper docs --- README.md | 16 +- YesNt.CodeEditor/InputHandler.cs | 12 +- YesNt.Interpreter/Utilities/Evaluator.cs | 3 +- docs/README.md | 47 ++ docs/editor.md | 52 ++ docs/language-reference.md | 811 +++++++++++++++++++++++ docs/library-api.md | 265 ++++++++ 7 files changed, 1198 insertions(+), 8 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/editor.md create mode 100644 docs/language-reference.md create mode 100644 docs/library-api.md diff --git a/README.md b/README.md index bf67f69..59da794 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,17 @@ # YesNt - + > YesNt is a imperative and interpreted language inspired by the Assembly language. -## Syntax +## Documentation -Current language syntax is documented in [SYNTAX_V2.md](SYNTAX_V2.md). +| Document | Description | +| -------------------------------------------------------- | ----------------------------------------- | +| [docs/README.md](docs/README.md) | Getting started | +| [docs/language-reference.md](docs/language-reference.md) | Full language reference | +| [docs/library-api.md](docs/library-api.md) | Embedding the interpreter as a C# library | +| [docs/editor.md](docs/editor.md) | Using the terminal code editor | -Example: +## Quick example ```ynt var name = world @@ -16,6 +21,5 @@ print_line Hello ${name} ## Run ```bash -dotnet run --project YesNt.Interpreter -- path/to/script.ynt +dotnet run --project YesNt.Interpreter.App -- path/to/script.ynt ``` - diff --git a/YesNt.CodeEditor/InputHandler.cs b/YesNt.CodeEditor/InputHandler.cs index 5eb365d..b937493 100644 --- a/YesNt.CodeEditor/InputHandler.cs +++ b/YesNt.CodeEditor/InputHandler.cs @@ -48,6 +48,14 @@ internal class InputHandler(TextEditor textEditor) textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0; return true; + case ConsoleKey.R: + ExecuteWithDebugScreen("run", false, false); + return true; + + case ConsoleKey.D: + ExecuteWithDebugScreen("debug", true, false); + return true; + case ConsoleKey.F: textEditor.FormatLines(); textEditor.Display(true); @@ -352,6 +360,8 @@ internal class InputHandler(TextEditor textEditor) return; } + Mode previousMode = textEditor.EditMode; + textEditor.EditMode = Mode.Debug; textEditor.IsStepDebugMode = stepMode; Console.Clear(); @@ -373,6 +383,6 @@ internal class InputHandler(TextEditor textEditor) _ = Console.ReadKey(); WriteStatus(string.Empty); textEditor.IsStepDebugMode = false; - textEditor.EditMode = Mode.Command; + textEditor.EditMode = previousMode; } } diff --git a/YesNt.Interpreter/Utilities/Evaluator.cs b/YesNt.Interpreter/Utilities/Evaluator.cs index 427731a..339e1b5 100644 --- a/YesNt.Interpreter/Utilities/Evaluator.cs +++ b/YesNt.Interpreter/Utilities/Evaluator.cs @@ -81,7 +81,8 @@ internal static partial class Evaluator /// /// Evaluates a numeric arithmetic expression string and returns the result as a string. - /// Supports +, -, *, and / operators. + /// Supports +, -, *, /, % (modulo), and ^ (power) operators + /// with standard precedence (^ highest, +/- lowest) and parentheses. /// Adjacent sign characters (++, --, -+, +-) are normalised before evaluation. /// /// The arithmetic expression to evaluate. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..3076695 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,47 @@ +# YesNt Documentation + +YesNt is a line-based, interpreted scripting language inspired by assembly. +Each line is one statement. There are no multi-line expressions. + +## Guides + +| Document | Description | +| ------------------------------------------- | ---------------------------------------------------- | +| [Language Reference](language-reference.md) | Every statement, token, and operator in the language | +| [Library API](library-api.md) | How to embed the interpreter in a C# project | +| [Editor](editor.md) | How to use the terminal code editor | + +## Quick start + +### Running a script from the command line + +```bash +dotnet run --project YesNt.Interpreter.App -- path/to/script.ynt +``` + +### Hello world + +```ynt +print_line Hello, world! +``` + +### Variables and output + +```ynt +var name = Alice +print_line Hello, ${name}! +``` + +### Functions + +```ynt +func greet: + var msg = Hello, ${name}! + print_line ${msg} +return + +var name = Bob +call greet +``` + +Script files use the `.ynt` extension by convention. diff --git a/docs/editor.md b/docs/editor.md new file mode 100644 index 0000000..0253100 --- /dev/null +++ b/docs/editor.md @@ -0,0 +1,52 @@ +# YesNt Code Editor + +`YesNt.CodeEditor` is a terminal editor for writing, formatting, running, and debugging YesNt scripts. + +## Start the editor + +```bash +dotnet run --project YesNt.CodeEditor -- [optional-path-to-file.ynt] +``` + +If you pass a file path, it is loaded on startup. + +## Modes + +- **Command mode:** enter editor commands in the `>>>` prompt. +- **Edit mode:** direct text editing with keyboard navigation. +- **Debug mode:** script output/debug information while running. + +## Command mode commands + +| Command | Description | +| --------------------- | --------------------------------------------------------- | +| `edit` | Switch to edit mode | +| `line ` | Jump to line `n` and switch to edit mode | +| `save [path]` | Save to current path or a new path | +| `load ` | Load a file | +| `new` | Create new file | +| `format` | Auto-format indentation | +| `run [path]` | Run script | +| `debug [path] [step]` | Run in debug mode (`step` enables step-by-step execution) | +| `exit` | Close the editor | + +## Edit mode controls + +- Arrow keys: move cursor +- Enter: split line +- Backspace/Delete: remove characters/merge lines +- **Alt+C:** return to command mode +- **Alt+T:** jump to top +- **Alt+B:** jump to bottom +- **Alt+S:** jump to start of line +- **Alt+E:** jump to end of line +- **Alt+R:** run script +- **Alt+D:** run debug mode +- **Alt+F:** format current file + +## Formatter behavior (quick summary) + +- Indents `func`, `if`, `else`, and `while` blocks. +- Dedents on `return`, `end_if`, and `end_while`. +- `exit` / `throw` / `error` close active non-function blocks for following lines. +- Comment lines (`# ...`) are kept unindented. diff --git a/docs/language-reference.md b/docs/language-reference.md new file mode 100644 index 0000000..834e207 --- /dev/null +++ b/docs/language-reference.md @@ -0,0 +1,811 @@ +# YesNt Language Reference + +YesNt is a line-based scripting language. Every non-empty, non-comment line is one statement. +Execution proceeds top-to-bottom unless a control-flow statement changes the line counter. + +--- + +## Table of contents + +1. [Basic rules](#basic-rules) +2. [Comments](#comments) +3. [String literals](#string-literals) +4. [Variables](#variables) +5. [Console I/O](#console-io) +6. [Arithmetic](#arithmetic) +7. [Conditions](#conditions) +8. [Control flow](#control-flow) +9. [Functions](#functions) +10. [Lists](#lists) +11. [Processing](#processing) +12. [System](#system) +13. [Predefined tokens](#predefined-tokens) +14. [Termination](#termination) + +--- + +## Basic rules + +- Lines are trimmed of leading and trailing whitespace before execution. +- Blank lines are silently skipped. +- Lines starting with `#` are comments and are silently skipped. +- Variable interpolation uses `${name}` and is evaluated before the statement runs. +- Special characters inside string literals are encoded internally and decoded on output — this is transparent to scripts. + +--- + +## Comments + +```ynt +# This is a comment. +print_line Hello # inline comments are NOT supported — everything after print_line is the argument +``` + +Only whole-line comments (lines whose first non-whitespace character is `#`) are supported. + +--- + +## String literals + +Double-quoted strings protect their content from keyword matching and allow escape sequences. + +```ynt +print_line "Hello, world!" +print_line "Line one\nLine two" +print_line "She said \"hi\"" +``` + +| Escape | Meaning | +| ------ | -------------------- | +| `\n` | Newline | +| `\r` | Carriage return | +| `\t` | Horizontal tab | +| `\"` | Literal double-quote | +| `\\` | Literal backslash | + +Variable interpolation (`${name}`) is **not** evaluated inside string literals — the braces +and content are passed through verbatim. + +```ynt +var x = world +print_line "${x}" # prints the literal text: ${x} +print_line "hello " ${x} # prints: hello world (interpolation outside the literal) +``` + +--- + +## Variables + +### Local variables — `var` + +``` +var = +``` + +Defines or updates a variable scoped to the current function (or the top level if called outside a function). +The value is everything after `=`, trimmed. + +```ynt +var count = 0 +var greeting = Hello, world! +``` + +Variable names may only contain letters and digits (`[a-zA-Z0-9]`). + +### Global variables — `global` + +``` +global = +``` + +Defines or updates a variable that is visible across all function scopes and background tasks. + +```ynt +global total = 100 +``` + +### Reading a variable — `${name}` + +`${name}` is an inline token that is replaced with the variable's value before the statement executes. +It can appear anywhere in a line and multiple occurrences are replaced left to right. +Local variables are checked first; if not found, the global table is checked. + +```ynt +var a = 5 +var b = 10 +print_line ${a} plus ${b} +``` + +### Deleting a variable — `delete` + +``` +delete +``` + +Removes the variable. Local scope is checked first; if not found, the global table is used. +Raises an error if the variable does not exist in either scope. + +```ynt +var temp = scratch +delete temp +``` + +--- + +## Console I/O + +### Print with newline — `print_line` + +``` +print_line +print_line +``` + +Writes `` followed by a newline. With no argument, writes a blank line. + +```ynt +print_line Hello! +print_line +print_line Done. +``` + +### Print without newline — `print` + +``` +print +``` + +Writes `` without a trailing newline. + +```ynt +print Enter your name: +var name = %read_line +print_line Hello, ${name}! +``` + +### Read a line of input — `%read_line` + +`%read_line` is an inline token that is replaced with one line of text read from standard input. + +```ynt +var answer = %read_line +print_line You typed: ${answer} +``` + +### Read a single key — `%read_key` + +`%read_key` is an inline token that is replaced with the single character pressed by the user (no Enter required). + +```ynt +print Press any key... +var key = %read_key +print_line You pressed: ${key} +``` + +### Clear the console — `clear` + +``` +clear +``` + +Clears the console window. + +--- + +## Arithmetic + +Arithmetic is a **postfix** modifier applied at the end of a line with the `calc` keyword. + +``` + calc +``` + +Any numeric sub-expression matching the pattern `number op number [op number …]` is evaluated +and replaced with the result. Supported operators (highest to lowest precedence): + +| Operator | Operation | +| -------- | ----------------------------- | +| `(…)` | Parentheses (evaluated first) | +| `^` | Exponentiation | +| `%` | Modulo | +| `/` | Division | +| `*` | Multiplication | +| `-` | Subtraction | +| `+` | Addition (lowest precedence) | + +Adjacent sign characters (`++`, `--`, `-+`, `+-`) are normalised before evaluation. + +```ynt +var x = 3 +var y = 4 +var sum = ${x} + ${y} calc # 7 +var expr = 2 + 3 * 4 calc # 14 (* before +) +var parens = (2 + 3) * 4 calc # 20 +var power = 2 ^ 10 calc # 1024 +var remainder = 17 % 5 calc # 2 +``` + +--- + +## Conditions + +Conditions are used in `if` and `while` statements. A condition is a string of the form: + +``` + +``` + +| Operator | Meaning | +| -------- | --------------------------------------------- | +| `==` | Equal (string comparison, case-sensitive) | +| `!=` | Not equal (string comparison, case-sensitive) | +| `<` | Less than (numeric) | +| `>` | Greater than (numeric) | +| `<=` | Less than or equal (numeric) | +| `>=` | Greater than or equal (numeric) | + +Numeric comparisons (`<`, `>`, `<=`, `>=`) parse both sides with +culture-invariant decimal rules (`.` or `,` as decimal separator). + +A bare value of `True` or `False` (case-insensitive) is also a valid condition. + +```ynt +var x = 10 +if ${x} > 5: + print_line x is greater than 5 +end_if +``` + +--- + +## Control flow + +### If / else / end_if + +``` +if : + +else: + +end_if +``` + +`else:` is optional. `if` / `else:` / `end_if` blocks can be nested. + +```ynt +var score = 75 +if ${score} >= 60: + print_line Pass +else: + print_line Fail +end_if +``` + +### While loop + +``` +while : + +end_while +``` + +The condition is checked before each iteration. `while` / `end_while` blocks can be nested. + +```ynt +var i = 1 +while ${i} <= 5: + print_line ${i} + var i = ${i} + 1 calc +end_while +``` + +### Labels and goto + +``` +label : +goto +``` + +`label` marks a target. `goto` performs an unconditional jump to that label. +Labels are scoped to the current function; you cannot jump to a label outside the calling function. + +```ynt +label loop: + print_line tick + goto loop +``` + +### Conditional goto + +``` +if goto