{"id":21221859,"url":"https://github.com/dctucker/delish","last_synced_at":"2026-05-03T11:36:33.768Z","repository":{"id":45023808,"uuid":"435025114","full_name":"dctucker/delish","owner":"dctucker","description":"Deli shell. System sandwiches for a world of cold cut scripts.","archived":false,"fork":false,"pushed_at":"2025-10-15T07:10:24.000Z","size":1394,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-15T20:42:41.066Z","etag":null,"topics":["linux","nim","packcc","parsing","peg","shell-scripting"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dctucker.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-12-04T22:46:51.000Z","updated_at":"2025-10-15T07:10:28.000Z","dependencies_parsed_at":"2025-09-22T09:13:37.853Z","dependency_job_id":"e173cd4b-57c0-4ed1-aca2-ad7adec1422f","html_url":"https://github.com/dctucker/delish","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dctucker/delish","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dctucker%2Fdelish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dctucker%2Fdelish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dctucker%2Fdelish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dctucker%2Fdelish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dctucker","download_url":"https://codeload.github.com/dctucker/delish/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dctucker%2Fdelish/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32567675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","nim","packcc","parsing","peg","shell-scripting"],"created_at":"2024-11-20T22:34:44.039Z","updated_at":"2026-05-03T11:36:33.762Z","avatar_url":"https://github.com/dctucker.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Delish language description\n\nDelish is a line-oriented scripting language. A line may contain a statement or a block followed by a comment.\nComments begin with the `#` character.\n\nFull grammar [here](https://github.com/dctucker/delish/blob/main/src/language/delish.packcc)\n\n## Data types\n\n| Type       | Description                         |\n|------------|-------------------------------------|\n| String     | Collection of characters            |\n| Identifier | Object key or function name         |\n| Variable   | Reference to runtime memory         |\n| Arg        | Arguments and flags                 |\n| Path       | Absolute and relative filenames     |\n| Integer    | Numbers 0-9                         |\n| Decimal    | Integer with a base-10 fraction     |\n| DateTime   | Year-month-date hour:minute:second  |\n| Boolean    | Logical true or false               |\n| Array      | Zero-indexed collection             |\n| Object     | Key/value pair collection           |\n| Regex      | Regular expressions                 |\n| Stream     | Standard input/output/error streams |\n| Error      | Standard error values (errno.h)     |\n| Signal     | Standard process signals (signal.h) |\n\n### Casts\n\nCasting (converting between types) is possible for some types. The following table shows which conversions are possible:\n\n| \u003cins\u003efrom\u003c/ins\u003e ➡️\u003cbr/\u003eto ⬇️ | String\u003cbr/\u003e\u0026nbsp; | Identifier\u003cbr/\u003e\u0026nbsp; | Variable\u003cbr/\u003e\u0026nbsp; | Arg\u003cbr/\u003e\u0026nbsp;  | Path\u003cbr/\u003e\u0026nbsp; | Integer\u003cbr/\u003e\u0026nbsp; | Boolean\u003cbr/\u003e\u0026nbsp; | Array\u003cbr/\u003e\u0026nbsp; | Object\u003cbr/\u003e\u0026nbsp; | Regex\u003cbr/\u003e\u0026nbsp; | Stream\u003cbr/\u003e\u0026nbsp; |\n|-----------:|:------:|:----------:|:--------:|:----:|:----:|:-------:|:-------:|:-----:|:------:|:-----:|:------:|\n| String     |     =  |   :ok:     |   :ok:   | :ok: | :ok: |   :ok:  |   :ok:  |  :ok: |   :ok: |  :ok: |   :ok: |\n| Identifier |   :ok: |     =      |   :ok:   | :ok: |  :x: |    :x:  |    :x:  |   :x: |    :x: |   :x: |    :x: |\n| Variable   |   :ok: |   :ok:     |     =    | :ok: |  :x: |    :x:  |    :x:  |   :x: |    :x: |   :x: |    :x: |\n| Arg        |   :ok: |   :ok:     |   :ok:   |   =  |  :x: |    :x:  |    :x:  |   :x: |    :x: |   :x: |    :x: |\n| Path       |   :ok: |   :ok:     |    :x:   | :ok: |   =  |   :ok:  |   :ok:  |  :ok: |    :x: |   :x: |   :ok: |\n| Integer    |   :ok: |    :x:     |    :x:   |  :x: |  :x: |     =   |   :ok:  |  :ok: |   :ok: |   :x: |   :ok: |\n| Boolean    |   :ok: |   :ok:     |   :ok:   | :ok: | :ok: |   :ok:  |     =   |  :ok: |   :ok: |   :x: |   :ok: |\n| Array      |   :ok: |   :ok:     |   :ok:   | :ok: | :ok: |   :ok:  |   :ok:  |    =  |   :ok: |  :ok: |    :x: |\n| Object     |   :ok: |   :ok:     |   :ok:   | :ok: |  :x: |   :ok:  |   :ok:  |  :ok: |     =  |   :x: |   :ok: |\n| Regex      |   :ok: |    :x:     |    :x:   |  :x: |  :x: |    :x:  |    :x:  |  :ok: |    :x: |    =  |    :x: |\n| Stream     |   :ok: |    :x:     |    :x:   |  :x: |  :x: |   :ok:  |    :x:  |  :ok: |    :x: |   :x: |     =  |\n\nAs shown in the table, anything can be converted to/from a `String`, while `Regex` is much more selective. Here are some details about how casts are expected to work:\n\n- A cast where the type is the same as the input will return the input itself as a copy.\n- `String` to `Array` depends on the type of string. Multi-line strings are split into lines, and single-line strings are split by `IFS`.\n- `Boolean` conversions should be intuitive, allowing for safe lazy evaluation of an undefined `Identifier`, returning `false` when a `Path` does not exist or when an `Array` (or other collection) is empty. All non-zero `Integer` values are `true`.\n- Converting an `Array` into a `Regex` will yield a regular expression that can match any of the values in the collection.\n- `Stream` and `Integer` are interchangeable since streams are an abstraction of numbered file descriptors.\n- Attempting to cast an incompatible type will result in an error.\n\nCasts are performed by using the type name as a function:\n\n```\n$path = Path(\"/usr/local/bin\")\n$str = String($path)\n```\n\n## Keywords\n\nThese are reserved words that cannot be used as a function name.\n\n| Keyword    | Description           |\n|------------|-----------------------|\n| `if`       | Conditional           |\n| `elif`     | \" \"                   |\n| `else`     | \" \"                   |\n| `do`       | Post-test loop        |\n| `while`    | Pre-test loop         |\n| `for`      | Iterator loop         |\n| `sub`      | Subshell              |\n| `local`    | Local variable        |\n| `arg`      | Argument variable     |\n| `env`      | Environment variable  |\n| `include`  | Inclusion directive   |\n| `in`       | Input stream          |\n| `out`      | Output stream         |\n| `err`      | Error stream          |\n| `open`     | File handle acquire   |\n| `close`    | File handle release   |\n| `run`      | Process execution     |\n| `async`    | Background process    |\n| `redir`    | Stream redirection    |\n| `return`   | Return statement      |\n| `break`    | Loop exit             |\n| `continue` | Early next iteration  |\n| `push`     | Stack addition        |\n| `pop`      | Stack removal         |\n| `true`     | Boolean literal       |\n| `false`    | Boolean literal       |\n| `shl`      | Bitwise shift left    |\n| `shr`      | Bitwise shift right   |\n| `not`      | Negation              |\n| `and`      | Conjunction           |\n| `or`       | Disjunction           |\n| `xor`      | Exclusive disjunction |\n| `nand`     | Non-conjunction       |\n| `nor`      | Non-disjunction       |\n| `xnor`     | Connective            |\n\n## Operators\n\nOperators are symbols that have specific usage and meaning when placed next to other identifiers.\n\n| Operator | Description             |\n|----------|-------------------------|\n|          | *Assignment*            |\n| `=`      | Direct assign           |\n| `\\|=`    | Default assign          |\n| `+=`     | Append                  |\n| `-=`     | Remove                  |\n|          |                         |\n|          | *Redirection*           |\n| `\u003e\u003e`     | Redirect append         |\n| `\u003c`      | Redirect read           |\n| `\u003e`      | Redirect write          |\n| `\u003c\u003e`     | Redirect duplex         |\n|          |                         |\n|          | *Comparison*            |\n| `\u003e=`     | Greater or equal        |\n| `\u003e`      | Greater                 |\n| `\u003c=`     | Less or equal           |\n| `\u003c`      | Less                    |\n| `==`     | Equality                |\n| `!=`     | Inequality              |\n| `=~`     | Matching                |\n|          |                         |\n|          | *Array / object access* |\n| `.`      | Dereferencing           |\n| `:`      | Key/value separator     |\n| `,`      | Value separator         |\n|          |                         |\n|          | *Mathematical*          |\n| `+`      | Addition                |\n| `-`      | Subtraction             |\n| `*`      | Multiplication          |\n| `/`      | Division                |\n| `%`      | Modulo                  |\n\n## Identifiers and variables\n\nIdentifiers must start with letters, and can contain numbers, underscores and hyphens. Identifiers can be used as lookup values when dereferencing objects and arrays.\n\nVariables start with a `$`. Variables can also be used as lookup values.\n\n## Arguments and flags\n\nArguments are always declared. This rule applies to both scripts and functions alike, and argument declarations will normally appear as the first few lines of a block. This encourages self-documenting code.\n\nExpected arguments are declared using the `arg` keyword. For string arguments, the variable name will be specified:\n```\narg $message\n```\n\nFlags start with `-`. Long flags start with an additional `-`. They are also declared using the `arg` keyword:\n```\narg -k --key\n```\n\nTo specify a default value for an argument, use the `|=` assign default operator:\n```\narg $message   |= \"\"\narg -key --key |= false\n```\n\n## Strings\n\nStrings are collections of characters. Single-line string literals use '`' single quotes or `\"` double quotes, while multi-line string literals use `\"\"\"` triple quotes.\n\n## Paths\n\nPath names must begin with a dot or a slash.\n\n## Blocks\n\nBlocks begin with a keyword followed by `{`, some code, and finally `}`.\n\n## RegEx\n\nRegular expression literals use the `r/.../` syntax. They can be checked against a string using the `=~` matching operator.\n\n## Objects and Arrays\n\nArrays and objects are similar in function. Objects are composed of key/value pairs, and arrays are generally treated as objects with zero-indexed integer keys.\n\nTo create and assign an object, use the `[` `]` symbols. Let's create an empty object:\n```\n$obj = []\n```\n\nNow, let's create an array with two flags as elements:\n```\n$arr = [\n  --list\n  --color\n]\n```\n\nDereferencing an object is done by using the `.` operator. Let's print the second element of the array we created:\n```\nout $arr.1\n```\n\n## Functions\n\n### Built-in functions\n\nThese functions can be called directly using the identifier:\n\n```\njson \"[1,2,3]\"\n```\n\n#### `json`\n\nConvert a string to JSON.\n\n### Type functions\n\nThese functions are invoked by dereferencing a type or a typed variable. See the [function reference](functions.md).\n\nThe following two code blocks do the same thing.\n\nPass the target as the first parameter in a type call:\n\n```\n$src = ./src\nout Path.stat $src\n```\n\nDereference the target in a value call:\n\n```\n$src = ./src\nout $src.stat\n```\n\n### User-defined functions\n\nFunctions can be defined as an identifier followed by a block of code. Here is a simple \"hello world\" function:\n```\nhello = {\n  out \"Hello world\"\n}\n```\n\nFunctions can receive arguments, which must be declared. Let's make our function accept an argument and print it out:\n```\nhello = {\n  arg $message\n  out $message\n}\n```\n\nFunctions are called by name, followed by any arguments:\n```\nfunc \"Hello world\"\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdctucker%2Fdelish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdctucker%2Fdelish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdctucker%2Fdelish/lists"}