{"id":22139808,"url":"https://github.com/sampersand/squire","last_synced_at":"2025-05-09T02:44:24.686Z","repository":{"id":43402291,"uuid":"366315127","full_name":"sampersand/squire","owner":"sampersand","description":"The medieval language held together by twine.","archived":false,"fork":false,"pushed_at":"2024-12-19T22:01:00.000Z","size":1074,"stargazers_count":60,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-31T21:33:24.649Z","etag":null,"topics":["esolang","macros","pattern-matching","programming-language","runtime","runtime-typechecking"],"latest_commit_sha":null,"homepage":"","language":"C","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/sampersand.png","metadata":{"files":{"readme":"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}},"created_at":"2021-05-11T08:47:04.000Z","updated_at":"2025-01-30T07:07:46.000Z","dependencies_parsed_at":"2024-04-02T02:44:22.118Z","dependency_job_id":"4092ef0a-4be1-42b1-af2c-1decc968ec82","html_url":"https://github.com/sampersand/squire","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sampersand%2Fsquire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sampersand%2Fsquire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sampersand%2Fsquire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sampersand%2Fsquire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sampersand","download_url":"https://codeload.github.com/sampersand/squire/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253180885,"owners_count":21866988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["esolang","macros","pattern-matching","programming-language","runtime","runtime-typechecking"],"created_at":"2024-12-01T20:18:57.010Z","updated_at":"2025-05-09T02:44:24.664Z","avatar_url":"https://github.com/sampersand.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Squire\nHear ye hear ye! Thou art commandeth to partake in the most novel of programming parlances in this era: Squire. It doth contain a truly awful cohort of subliminal mechanisms for thy writing pleasure.\n\nSquire's a medieval-themed programming language that's meant to parody most mainstream programming languages. While it does definitely contain its fair share of fun quirks, it's first and foremost meant to be a fully-fledged language, completely oblivious to its own ridiculousness.\n\n# Examples\nHere's some examples of Squire. For more examples, you can see [examples](/examples), and for a more complete overview of Squire itself, see [overview](/overview)\n\n## Basic Examples\nSquire uses fun, old-timey words as alternatives to modern-day concepts:\n```squire\ni = 0; # semicolons are optional, but recommended\nwhilst i \u003c 10 { # no parens needed\n\tif i % 2 { # squire uses truthy values\n\t\tproclaim(\"{i} is odd\"); # string interpolation\n\t} alas {\n\t\tproclaim(\"{i} is even\");\n\t}\n\ti += 1;\n}\n```\n\n### Journeys (ie functions)\nInstead of functions, you go on journeys (and get `reward`ed for `return`ing)\n```squire\njourney greet(what) {\n\treward \"Hello, {what}\";\n}\n\nproclaim(greet(\"world\"));\n```\n\nBecause of poor design choices early on, you have to predeclare functions used later on as global variables\n```squire\njourney foo(x) {\n\trenowned bar; # `bar` is a global variable in this scope.\n\treward \"Hello, \" + bar(x)\n}\n\njourney bar(x) {\n\treward x + \"!\";\n}\n\nproclaim(foo(\"world\")); # Hello, world!\n```\n\n### Forms (ie classes)\nThe medieval people were _really_ into Plato's forms, so I decided to name Squire's \"Classes\" after it. (And I majored in Ancient Philosophy):\n\n```squire\nform Person {\n\tmatter name : Text; # type annotations are optional\n\tmatter hungry;\n\n\timitate(name) { # constructor\n\t\tsoul.name = name; # `soul` is `this`/`self`.\n\t\tsoul.hungry = nay;\n\t}\n\n\tchange walk(miles) {\n\t\tif soul.hungry {\n\t\t\tproclaim(\"I'm too hungry to walk.\");\n\t\t} alas {\n\t\t\tproclaim(\"I walked {miles} miles!\");\n\t\t\tsoul.hungry = yea;\n\t\t}\n\t}\n}\n\nme = Person(\"Sam\");\nme.walk(5); # I walked V miles! (more on `V` in the fun quirks section)\nme.walk(5); # I'm too hungry to walk.\n```\n\n# Fun quirks of Squire!\nHere's a (non-exhaustive) list of Squire's quirks. Most of these things are actually encouraged (especially the [Roman Numeral literals](#roman-numeral-literals) and [Fraktur bare word literals](#fraktur-bare-word-literals)) when possible, as they add to the charm of the language.\n\n## Roman Numeral Literals\nBack in the medieval ages, people actually did all their mathematical computations with Roman numerals. As such, Squire supports (and encourages) using roman numeral literals:\n```squire\nproclaim(\"twenty four is: {IV * VI}\") # =\u003e twenty four is: XXIV\n```\nIn fact, all number to string conversions (regardless of whether they were written in Roman or Arabic numerals) will output Roman numerals. If you want Arabic numerals, you have to use the `arabic` function:\n```\nproclaim(\"twenty four is: {arabic(IV * VI)}\") # =\u003e twenty four is: 24\n```\nNote: You can enable the `SQ_NUMERAL_TO_ARABIC` flag to switch the default string output to Arabic numerals. (Though this may be deprecated/removed.)\n\n## `yea`/`nay`/`ni`\nSquire supports the basic concepts of true and false. However, since Mr. Boole wasn't born until 1815, the concepts of Boolean algebra did not exist. So instead we use the phrases `yea` and `nay`.\n\nThe word `ni` is used for null, and is a nod to the skit \"Monte Python and the Holy Grail.\"\n\n## Fraktur Bare word literals\nSquire supports bare words—that is, strings that don't require quotes around them. Now, normally this is a _terrible_ idea, as there's no way to determine if a word is a variable or a string just by looking at it. Squire solves this problem by requiring all bare words to use [Fraktur Unicode characters](https://en.wikipedia.org/wiki/Fraktur#Fraktur_in_Unicode) exclusively. Note that the bare words can also contain spaces in them, and all leading and trailing whitespace will be trimmed.\n\n```\nproclaim(ℌ𝔢𝔩𝔩𝔬 𝔴𝔬𝔯𝔩𝔡) # =\u003e Hello world\n\n# You can also escape characters that'd normally end the fraktur literal:\nproclaim(ℌ𝔢𝔩𝔩𝔬\\, 𝔴𝔬𝔯𝔩𝔡\\!) # =\u003e Hello, world!\n```\n\nThe Fraktur characters will be converted to their ASCII equivalents within the parser, so the actual Fraktur characters are never encountered within Squire (unless you write them in quotes).\n\n## \"Coding Case\"-Insensitivity\nBack in the medieval ages, spelling was not at all standardized—a lot of words simply would be spelled differently from region to region, and sometimes [things got really bad](https://en.wikipedia.org/wiki/Ough_%28orthography%29). Squire embodies this by allowing you to have \"coding case\"-insensitive identifiers. That is, you can use both `snake_case` and `camelCase` and Squire will interpret them as the same name! In fact, you can also use `kebab-case` and `space case` too :-)\n\nThese are all equivalent:\n```\nfoo_bar_baz\nfooBarBaz\nfoo-bar-baz\nfoo bar baz\nfooBar_baz\nfoo-bar baz\n```\n\nThe only caveat to this is if the variable starts with a capital letter, this automatic replacement is not performed. \n\n## Indentation only with tabs\nAs monarchs sometimes decreed arbitrary edicts that were then strictly enforced, Squire also has an (somewhat) arbitrary edict: You _may not_ use spaces when indenting your program. Attempting to use spaces for indentation will greet you with a lovely compile-time error of `THOU SHALT NOT INDENT WITH SPACES!`.\n\nYou don't _have_ to use tabs for indentation—you can always use the tried-and-true tested mechanism of `;` for spacing:\n```squire\n# Basic fizzbuzz, nothing fancy.\n\ni = I\nwhilst i \u003c= C {\n;;;mod-three = i % III\n;;;mod-five = i % V\n\n;;;if mod-three \u0026\u0026 mod-five {\n;;;;;;proclaim(i)\n;;;} alas if mod-three {\n;;;;;;proclaim(𝔉𝔦𝔷𝔷)\n;;;} alas if mod-five {\n;;;;;;proclaim(𝔅𝔲𝔷𝔷)\n;;;} alas {\n;;;;;;proclaim(𝔉𝔦𝔷𝔷𝔅𝔲𝔷𝔷)\n;;;}\n\n;;;i = i + I\n}\n```\n\n## Were-`if`s\nWhat programming language based on the medieval ages would be complete without some form of monsters? In Squire, instead of having werewolfs, we have were-`if`s: On full moons (and only on full moons), `if` statements have a 1% chance of embracing their inner lycanthropy and executing their body when the condition is _false_. That is, this may be executed on a full moon:\n```squire\nif nay {\n\tproclaim(\"'Ello world!\")\n}\n```\nWhat more, this will only occur when the moon is 95% full or greater. This means that certain parts of the world may have were-`if`s occurring where other parts won't. Happy bug hunting! (Note that you _can_ disable this by passing `-DSQ_NMOON_JOKE` when compiling, but that's no fun.)\n\nAnd yes, I did embed a [moon phase calculator](https://github.com/sampersand/squire/blob/master/src/value/moon-phase.c) for a joke. No I do not feel ashamed.\n\n## `whence`\nAs you may have noticed, Squire does not actually have keywords for `break` or `continue`: This is because when I was originally throwing together the language, I wanted to have a one-pass compiler, which doesn't play nicely with `break` and `continue`. So I simply omitted them. The obvious problem is that you can't break out of nested loops easily.\n\nEnter `whence`. A `whence \u003clabel\u003e` statement is akin to the [`COMEFROM` statement](https://en.wikipedia.org/wiki/COMEFROM) in other languages: Whenever `\u003clabel\u003e` is encountered, control flow is actually diverted to the `whence label`. As such, you can write loops like such:\n```\ni = I;\nwhilst yea {\n\tif i \u003e 100 {\n\tdone:\n\t\t# normally you'd `break` here\n\t}\n\ti = i + I\n}\n\nwhence done; # whenever `done:` is hit, we go here.\n```\n\nThat leaves one problem: What happens when multiple `whence`s all point to the same label:\n```\nfoo:\nproclaim(\"1\");\n\nwhence foo;\nproclaim(\"2\");\n\nwhence foo;\nproclaim(\"3\");\n```\nSquire will actually execute all the `whence`s by simply `fork`ing for every `whence` statement but the last one. So the output of the above program would be either `233` or `323`, depending on how the OS scheduled the two processes.\n\n## Macros\nYes, we have macros. And yes, Squire is a runtime language. There's not a ton of them (currently), but more will eventually be implemented:\n```\n@transcribe \"foo.sq\" # copy-paste `foo.sq` in right here\n\n@henceforth $bar = baz; # kinda like `#define bar baz` in C\n@henceforth $quux($a, $b) = $a + $b; # kinda like `#define quux(a,b) a + b` in C\nproclaim($quux(IV, VI)) # =\u003e X\n\n@whereupon $bar # if the macro `$bar` is defined, do this\n\tproclaim(\":-)\"); # =\u003e :-)\n@alas\n\tproclaim(\":-(\");\n@nowhere;\n```\n\nEventually, we'll add stuff like concatenating identifiers, iterations, etc. But that'll come later.\n\n# Actually useful things\nTODO\n## Pattern Matching\nTODO\n## `path`'s body\nTODO\n## Typing\nTODO\n\n# FAQs\n## Why?\nWhy not? \n\n## No seriously, why?\nWell, I originally was working on a language called [Quest](https://github.com/sampersand/quest). I had just written a very simple programming language _within_ Quest (the precursor to [Knight](https://github.com/knight-lang/knight-lang)), and I wanted to write something a bit more complex. I finished a rough sketch of syntax, but never ended up finishing it.\n\nFast forward a few years, when I wanted to write a programming language that's a bit more complex than Knight, but not as complex as Quest. The original Squire looked very much like Go or JavaScript, as it was meant to simply be another toy language. But then it hit me: I could make this a parody, and have it be medieval themed (like the naming scheme of my projects). And thus, Squire was born.\n\n## Why is \u0026lt;code snippet\u0026gt; so poorly written?\nWhen I first was writing Squire, I never intended for it to become anything. In fact, I purposefully wrote it late at night when I was tired/watching TV, and _never_ went back to fix anything. Only much later did I start taking the project a bit more seriously and began writing cleaner code. So the bad code you'll see is from those early stages (most notably the tokenizer, parser, and compiler).\n\n# Possible additions:\n\n- [x] Static fields on `form`s\n- [x] Inheritence for `form`s\n- [x] macros\n\t- [x] Declarative\n\t- [x] Function\n\t- [~] conditional compilation (could be cleaned up)\n\t- [ ] `foreach`\n\t- [ ] `evaluate`\n- [x] pattern matching\n- [~] varidict functions and keyword parameters\n\t- varidict is done, keyword is not\n- [ ] modules\n- [x] dictionaries\n- [x] interpolation\n- [ ] overload\n- [x] pattern matching on functions\n\n\u003c!-- \n# Glossary\nSquire doth contain a multitude of fancy parlance:\n- `tome`s are dictionaries. --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsampersand%2Fsquire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsampersand%2Fsquire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsampersand%2Fsquire/lists"}