greg

From Esolang
Jump to navigation Jump to search
greg logo
greg logo

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