Greg

esolang by thejonymyster
== Official documentation ==
Below is greg's official documentation
(originally a text document)
 Opening notes: anchored long implicit parenthesis matching
 undefined vars are implicit string literals
 ints can be coerced to string by char code
 space as a disambiguating command delimiter (space does not need to be escaped)
 returning outside of functions or subexpressions prints to stdout
 no newlines on print
 valid token chars are: all alphabetical characters [ascii 65-90, 97-122],
 underscore [ascii 95], and all non-ascii characters [anything 128+]
 instructions/operations apply to the left hand side of an expression
 i.e. greg<op1>tim<op2> applies op2 to greg after op1 is performed
 
 Instructions:
 
 .{comment} - comment
 if . is used (outside of a string) without the following {comment} block, error
 
 " - escape character
 if nothing is escaped, error
 
 & - parenthesis anchor, matches all unmatched () parentheses between itself and the next parenthesis anchor
 beginning and end of program are implicitly also parenthesis anchors
 
 greg - defines int greg with one char of user input for value
 if no input is given, greg is null [ascii 0]
 
 greg? - prompts user for input to define greg with
 if greg is not present, error
 
 greg# - defines int greg with value abs(#)
 
 :greg: - explicit string literal greg
 
 greg:tim: - defines str greg with value tim
 
 greg! - return greg
 if greg is not present, return current function name (or program name if used outside of function)
 if greg is a function, return its code (except for comments, which are removed)
 
 greg; - print greg to stdout
 if greg is not present, print current function name (or program name if used outside of function)
 if greg is a function, print its code (except for comments, which are replaced with .)
 
 greg{tim} - define function greg that executes tim
 
 greg{} - execute function greg and act as an anonymous var of its return value
 note: to define a function that does nothing, youd have to do greg{ }
 
 greg|tim - defines alias greg that refers to tim
 if tim is not present, undefines greg
 if greg is not present, undefines all aliases to tim
 if neither is present, error
 if greg is an explicit literal, error
 
 (code) - subexpression returns left hand side of code as an anonymous var after execution
 note: this means you can do, for example, (greg+tim)+bob to add both tim and bob to greg
 
 Maths:
 
 greg<op>tim - (re)defines greg as <op>(greg,tim) according to table
 n = number of <op> used and cannot be 0
 functions get parsed as strings, but remain functions
 trying to write to an explicit literal returns the result instead 
 ints concatenated to strings are coerced to strings by char code
 
 greg+tim - see table:
 
 tim is... greg is... 
 | +-----------------------+---------------------+-------------------+
 V | int | string | not present |
 +-------------+-----------------------+---------------------+-------------------+
 | int | greg + tim * n | append tim to greg | return tim * n |
 | | | n times | |
 +-------------+-----------------------+---------------------+-------------------+
 | string | coerce greg to string | append tim to greg | return tim |
 | | and do -> | n times | n times |
 +-------------+-----------------------+---------------------+-------------------+
 | not present | greg + n | append n to greg | return n |
 | | | | |
 +-------------+-----------------------+---------------------+-------------------+
 
 greg-tim - see table:
 
 tim is... greg is... 
 | +-----------------------+---------------------+-------------------+
 V | int | string | not present |
 +-------------+-----------------------+---------------------+-------------------+
 | int | max(greg - tim * n,0) | remove tim*n chars | return -tim * n |
 | | | off the end of greg | |
 +-------------+-----------------------+---------------------+-------------------+
 | string | coerce greg to string | remove first n | delete first n |
 | | and do -> | instances of tim | instances of tim |
 | | | from greg | from return value |
 +-------------+-----------------------+---------------------+-------------------+
 | not present | max(greg - n, 0) | remove n chars off | return -n as a |
 | | | the end of greg | string |
 +-------------+-----------------------+---------------------+-------------------+
 
 greg*tim - see table:
 
 tim is... greg is... 
 | +-------------------+-------------------------+-------------------+
 V | int | string | not present |
 +-------------+-------------------+-------------------------+-------------------+
 | int | greg * tim ^ n | concat tim^n copies | return newline |
 | | | of greg together | tim n times |
 +-------------+-------------------+-------------------------+-------------------+
 | string | coerce greg to | prepend tim, rotate | return newline |
 | | string and do -> | left n times, return | tim n times |
 | | | last length(greg) chars | |
 +-------------+-------------------+-------------------------+-------------------+
 | not present | greg * 2 ^ n | rotate greg | return n newlines |
 | | | left n times | |
 +-------------+-------------------+-------------------------+-------------------+
 
 note: rotating a string left means taking its first character and moving it to the end
 
 greg/tim - see table:
 
 tim is... greg is... 
 | +-------------------+-------------------------+-------------------+
 V | int | string | not present |
 +-------------+-------------------+-------------------------+-------------------+
 | int | integer division | substring from | return floor of |
 | | greg / (tim * n) | tim * n to tim * (n+1) | nth root of tim |
 +-------------+-------------------+-------------------------+-------------------+
 | string | coerce greg to | prepend tim, rotate | return nth char |
 | | string and do -> | right n times, return | of tim |
 | | | last length(greg) chars | |
 +-------------+-------------------+-------------------------+-------------------+
 | not present | integer division | rotate greg | nasal demons |
 | | greg / n | right n times | |
 +-------------+-------------------+-------------------------+-------------------+
 
 notes: rotating a string right means taking its last character and moving it to the start
 division by 0 gives the string Inf
 
 Search/Regex:
 
 bob|greg>tim|# - replace instances greg in bob with tim, starting at char # of bob. 
 # can be any int (0 indexed, defaults to 0 if not present or invalid)
 greg can be any variable or gregex (gregular expression)
 tim can be any variable or timex (tim expression)
 greg and tim are read as strings if they aren't already (but not modified)
 if greg is not present, search string is an empty string
 if tim is not present, replace string is an empty string
 bob is coerced to string at the start of execution,
 but is not modified again until the end of the command
 if bob is not present, error
 
 greg<tim|bob - set greg to the index of the first instance of tim in bob
 tim can be any variable or gregex (gregular expression)
 tim and bob are read as strings if they aren't already (but not modified)
 if greg is not present or an explicit literal, the value is returned instead
 if tim is not present, search string is an empty string
 if bob is not present, source string is an empty string
 
 gregex syntax: ~pattern;flags~
 notes: ;flags is optional, both ~abc;~ and ~abc~ are both valid ways to specify no flags
 gregular expressions are just strings, so any string in this format will parse as a pattern in regex contexts
 this also means that gregex must be contained within a string, as there are no gregex literals
 a~b;~c will parse as ~abc;~ when used as a search string
 metacharacters implicitly included in the pattern in this fashion 
 are escaped by default, so <a>~bc~ will parse as ~"<a">bc~
 to avoid gregex parsing, simply escape either ~. for example: "~abc~ will not parse as gregex
 
 metacharacters:
 
 " - still the escape char
 
 ? - matches any char
 
 < - matches the start of the string
 
 > - matches the end of the string
 
 - - range
 
 [] - bracket expression, matches any char in the brackets
 
 []! - negative bracket expression, matches any char not in the brackets
 
 () - reference group / subexpression
 
 ^() - replace group, nonmatching, see below
 
 ()= - positive lookahead, nonmatching
 
 =() - positive lookbehind, nonmatching
 
 ()! - negative lookahead, nonmatching
 
 !() - negative lookbehind, nonmatching
 
 | - or
 
 \# - backreference to #th reference group
 (0 indexed, defaults to 0 if no # is given)
 \n - character class n, see below
 
 $# - match unicode # (defaults to newline [10], you're welcome)
 
 *m,n - match preceding element at least m and at most n times
 m defaults to 0 if not given, n defaults to 1 if not given,
 but no upper bound if comma is not present
 
 {greg} - var injection, parses as the value of greg
 non recursive, so greg:~{greg}~: wont parse as an infinite cascade of ~s, it will parse as ~{greg}~ literally
 
 character classes:
 
 w - word
 
 W - non word
 
 b - word boundary
 
 B - non word boundary
 
 d - digit
 
 D - non digit
 
 t - valid token char
 
 T - non valid token char
 
 flags:
 
 g - global
 
 i - case insensitive
 
 s - substring, makes < match the beginning of the search rather than 
 the beginning of the entire string
 
 r - reverse, matches starting from the end backwards
 
 timex syntax: /pattern-greg/
 notes: timex expressions are just strings, so any string in this format will parse as a pattern in timex contexts
 this also means that timex must be contained within a string, as there are no timex literals
 -greg (re)defines greg to be an int, specifically the number of which match it is replacing (index 0)
 after the replacement, greg remains the final match number
 -greg is optional, both /abc-/ and /abc/ are valid ways to specify no variable
 
 metacharacters:
 
 \# - insert match from #th reference group
 (0 indexed, defaults to 0 if no # is given)
 
 ^# - insert match from #th replace group
 (0 indexed, defaults to 0 if no # is given)
 
 @# - insert entire #th match
 (0 indexed defaults to current match)
 /@/ is the same as /@;{greg}-greg/
 
 $# - insert unicode # (defaults to newline [10] again)
 
 ;{greg} - var injection, parses as the value of greg
 non recursive, so greg:/{greg}/: wont parse as an infinite cascade of /s, it will parse /{greg}/ literally
 
 ${code} - code injection, execute code,
 can use \# ^# and @# within code block
 note: if the timex itself is altered, the replacements will still read from the original value
 
 Other:
 
 ~greg|tim{bob} - import tim from bob as greg
 if greg, tim, or bob are missing, error
 if bob is not a string, error
 
 =greg - export greg
== Examples ==
Quine
 cc:"::qq:"":dd:c+c+cc+qq++cc++q+cc++qq+cc++d++(cc+dd);:c+c+cc+qq++cc++q+cc++qq+cc++d++(cc+dd); 
== Computational class ==
turing complete proof via conversion to Turing machine
 tape:
 101`1`a11001: .{some initial position}
 
 .{simulate infinite tape}
 right:~=(`?`?)>~:
 left:~
 (`?`)=~:
 on:0:
 too:
 0:
 
 .{states}
 ao:~(\d)`1`a(\d)~: Ao:/${tape;}\"0`\1`a/:
 az:~(\d)`0`a(\d)~: Az:/${tape;}\"0`\1`b/:
 bo:~(\d)`1`b(\d)~: Bo:/${tape;}HALT/
 bz:~(\d)`0`b(\d)~: Bz:/${tape;}`\`b1\1/
 end:/${tape;0 Keming{ }}/:
 
 .{execute}
 tape;
 Keming{
 tape|right>on| tape|left>too|
 tape|ao>Ao| tape|az>Az|
 tape|bo>Bo| tape|bz>Bz|
 tape|HALT>end|
 Keming{}
 }
 
 Keming{} :Oh my word, it halts!!!:;
named after the Keming machine, which inspired this proof
Category:LanguagesCategory:2021Category:Turing completeCategory:Unimplemented