User:Gilbert189/Languages in concept: Difference between revisions
Gilbert189 (talk | contribs) |
Gilbert189 (talk | contribs) No edit summary Tag: Reverted |
||
Line 1: | Line 1: | ||
These are some of my languages that I made, but only just as a concept. They're not detailed enough to warrant a page by itself, but they're interesting enough to show them here. (And also because I barely contributed here anyway.) |
|||
Note that these are only limited to esolangs that are either really vague/incomplete, needs better writing, or just a big "documenting example". Anything more than those are put on [[User:Gilbert189#Drafts|Drafts]]. |
|||
= Waluigilang = |
|||
''Made in 19 September 2021.'' |
|||
My response to the very un-mematic [[Wariolang]]. (though more towards how Waluigi wahs and less on how he really speaks; if you feel offended, I am sorry) |
|||
WAH "Hello, world!" TO WALUIGI |
|||
<code>WAH a TO b</code> is insertion. It kinda acts like <code>Hello, world!" >> std::cout</code> |
|||
WAH FOREVER! |
|||
WALUIGI SHOULD BE WAH? |
|||
NAH |
|||
<code>WAH?</code> is input, <code>WALUIGI</code> is output. <code>a SHOULD BE b</code> is variable assignment. |
|||
<code>WAH a ... NAH</code> is flow control. <code>a</code> could be <code>IF a IS b</code> ([else-]if statement), <code>a TILL b</code> (for statement), <code>a TIMES</code> (repeat), <code>TILL a IS b</code> (until loop), <code>WHILE a IS b</code> (while loop), <code>FOREVER</code>, or nothing (else statement). |
|||
Also, exclamation mark is the line terminator of Waluigilang. It's optional, but you will probably need to use it if you're doing a one liner. |
|||
INPUT SHOULD BE WAH? |
|||
WAH IF INPUT IS "1" |
|||
WAH FOREVER |
|||
WAH "1" TO WALUIGI |
|||
NAH |
|||
NAH |
|||
WAH "0" TO WALUIGI |
|||
Some added things: There's 3 data types: number, booleans, and strings. Booleans have 2 states, <code>WAH</code> (true) and <code>NAH</code> (false). |
|||
WAH A TILL 100 |
|||
A SHOULD BE A AND 1 |
|||
COND SHOULD BE A STEAL 3 |
|||
O SHOULD BE "" |
|||
WAH IF COND IS 0 |
|||
WAH "WA" TO O |
|||
NAH |
|||
COND SHOULD BE A STEAL 5 |
|||
WAH IF COND IS 0 |
|||
WAH "LUIGI" TO O |
|||
NAH |
|||
WAH IF O IS "" |
|||
O SHOULD BE A BUT O |
|||
NAH |
|||
WAH O TO WALUIGI |
|||
NAH |
|||
<code>a STEAL b</code> is modulus. <code>a BUT b</code> is type casting. <code>a AND b</code> is addition. Others will be <code>TAKE</code> (floor divide), <code>CROSS</code> (multiply), and <code>SHIFT</code> (right bit-shift) |
|||
ADD NUMBER 2! |
|||
A SHOULD BE WAH? |
|||
B SHOULD BE WAH? |
|||
C SHOULD BE A AND B! |
|||
WAH C TO WALUIGI! |
|||
NO, WALUIGI NUMBER 1! |
|||
WAH 1 TO ADD! |
|||
WAH 2 TO ADD! |
|||
WAH ADD TO WALUIGI! |
|||
This is an example of a function in Waluigilang. You can see that it uses purely insertions to work. |
|||
= Penfurs = |
|||
''Made in 9 January 2022.'' |
|||
a = 1; |
|||
out a; |
|||
b = [1, 2, 3]; // decorator of b: int -> int; b: 0 -> 1; b: 1 -> 2;... |
|||
f: int -> int; |
|||
f: 2 -> 4; // mapping |
|||
f: 3.0 -> 9; // error: expecting int as domain, got float |
|||
f 1 // error: 1 is not in domain of f |
|||
f: x -> mult x x; // defined function |
|||
f: 1 -> 2; /* |
|||
error: contradictory statement from statements: |
|||
x -> mult x x |
|||
*/ |
|||
g: int int -> int; |
|||
g: x 1 -> f x; |
|||
g: x 2 -> add x x; |
|||
g: x y -> add y x; /* |
|||
error: contradictory function from statements: |
|||
x 1 -> f x |
|||
x 2 -> add x x |
|||
*/ |
|||
isPainful: function -> int; |
|||
isPainful: x ? equals liquidType x "base" -> 1; |
|||
isPainful: x ? equals liquidType x "acid" -> 1; |
|||
f: int -> int; |
|||
f: 1 -> 2; |
|||
d = domain f; // a list representing the domain of f |
|||
c = codomain f; // a list representing the codomain of f |
|||
g: int -> int; |
|||
g: x -> add x 1; |
|||
d = domain f; // error: g has no defined domains |
|||
list = [1, 2, 3]; |
|||
f: int -> int; |
|||
f: x -> mult 2 x; |
|||
mapped = compose f list; // f(list(x)), keep in mind that lists are just functions |
|||
iterate out mapped; // execute `out mapped x` for all x in defined domain of `mapped` |
|||
fb: int -> string; |
|||
fb: x ? equals mod x 15 0 -> "FizzBuzz"; // highest priority |
|||
fb: x ? equals mod x 3 0 -> "Fizz"; |
|||
fb: x ? equals mod x 5 0 -> "Buzz"; |
|||
fb: x ? -> x; // lowest priority |
|||
list = [1:100:1]; |
|||
iterate out compose fb list; |
|||
What I can recall from this language: |
|||
* Name is a corruption of "functional programming" or something. |
|||
* Made when I was studying functions. (thus the <code>domain</code> and <code>codomain</code> functions) |
|||
* Functions are not curried, instead they are executed after the stack has enough items that it needs. (Calling one makes a new stack frame.) |
|||
= OLIVIA = |
|||
Acronym of "Origami Language Interpreter Via lInear Algebra". This was made when I'm in fan of PMTOK. |
|||
There's also the earlier OLLY language that's just a 2D esolang with tile-moving and wrap-arounds. |
|||
Prepare an origami paper ABCD, with AB facing the north. |
|||
Fold origami paper ABCD diagonally, so that D touches B. |
|||
Note that "Fold origami paper ABCD, so that B touches D." is different than above line. (D goes to B, also this is a comment) |
|||
Fold origami paper ABCD diagonally, so that A touches C. This results in triangle (AC)(BD)E. |
|||
Split line AB to AF and BF, and line CB to CG and BG. |
|||
Fold origami paper ABCD so that C touches B via line EG. Flip the origami paper. |
|||
Fold origami paper ABCD so that A touches B via line EF. This results in square (ABCD)(GF)E(IH). |
|||
Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that G touches I and G and I intersects line AE with fold that intersects A. |
|||
Fold origami paper ABCD so that F touches H and F and H intersects line CE with fold that intersects C. This results in kite (ABCD)(JK)E(LM) with center point (FG). |
|||
Call the global point (FG) N. |
|||
Undo the last 2 folds. |
|||
Make vector N(ABCD) and rotate it 180 degrees. Call it O. |
|||
Fold origami paper ABCD so that A touches the vector point O via line AJ, AL, and JL. Flip the origami paper. |
|||
Fold origami paper ABCD so that C touches the vector point O via line CK, CM, and KM. This results in conjoined parallelogram AJ(BD)L, folded kite E(JK)(BC)(LM), and parallelogram CL(BD)M. |
|||
Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that J touches K and J and K intersects line A(BD). Flip the origami paper. |
|||
Fold origami paper ABCD so that L touches M and L and M intersects line C(BD). This results in conjoined hexagon AOP(BD)QR, kite E(JK)(BC)(LM), and hexagon CST(BD)UV. |
|||
Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line OP touches line QR. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line ST touches line UV. This results in conjoined folded kite E(JK)(BC)(LM), trapezoid A(OR)(PQ)(BD), and trapezoid C(SV)(TU)(BD). |
|||
Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line PT touches OS. Mark that fold as VW. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line QU touches RU. Mark that fold as XY. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line (OP)V touches line (QR)W. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that line (ST)X touches line (UV)Y. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that C is as far-away as possible with E. Flip origami paper ABCD. |
|||
Fold origami paper ABCD so that A is as far-away as possible with E. Flip origami paper ABCD. |
|||
You have successfully made an origami crane. |
|||
= This geometric programming language = |
|||
''Made in 28 March 2023.'' |
|||
# Angles |
|||
Angles are a number that is suffixed by an angle mark. Such angle marks are: |
|||
- °, for denoting angle in degrees |
|||
- r, for denoting angle in radians |
|||
- g, for denoting angle in gradians |
|||
An example of an angle is 30°. |
|||
# Points |
|||
Point names must start with a capital letter and % to denote a guide. |
|||
When prefixed with %, the second character must be a capital letter. |
|||
The rest could be any letters and numbers (but not a percent sign). |
|||
# Complex aliases |
|||
Some complexes may be difficult to be referenced for use at definitions. |
|||
To counteract this, one may create an alias of the complex instead. |
|||
An alias is a point name prefixed by ◘. To define it, use → after a definition. |
|||
# Floating shapes |
|||
Floating shapes are shapes that has no concrete coordinate. |
|||
# Primitives |
|||
↑A Define floating vector A. |
|||
↑A(X,Y) Define vector A based at coordinate (X, Y) |
|||
•A Define floating point A |
|||
•A(X,Y) Define point A at coordinate (X, Y) |
|||
-AB(L) Define line AB with length L (optional) |
|||
-A(M) Define floating line A with intercept M (optional) |
|||
{X,Y} Define a set containing X and Y |
|||
{X|Y} Define a set containing X which satisfies predicate Y |
|||
# Complexes |
|||
○A(R) Define circle A with radius R (optional) |
|||
◠AB Define floating circular arc AB |
|||
◠AB(θ) Define circular arc AB and arc angle θ |
|||
◠AB(θ) Define circular arc AB and arc angle θ |
|||
◠A Define floating circular arc with center A |
|||
◠A(θ) Define floating circular arc with center A and arc angle θ |
|||
# Descriptors |
|||
=X Parallel to X |
|||
⟂X Perpendicular to X |
|||
(⟂ could be replaced by +) |
|||
+(θ)X→Y Intersecting or touching X at Y (optional) at angle θ |
|||
(* could be used as well) |
|||
%X Tangent at X |
|||
≅X Congruent to X |
|||
(≅ could be replaced with ~= or ~!) |
|||
Operations |
|||
A + B A plus B |
|||
A - B A minus B |
|||
A × B A times B |
|||
A / B A divided by B |
|||
ΔAB Euclidean distance of A and B |
|||
ΔA Euclidean distance of A and itself |
|||
Predicates |
|||
A = B A equals B (for numbers) |
|||
A is parallel to B (for geometries) |
|||
A | B A satisfies predicate B |
|||
A ⟂ B A is perpendicular to B |
|||
A * B A intersects B |
|||
A ≅ B A is congruent to B |
|||
(≅ could be replaced with ~= or ~!) |
|||
Complex predicates |
|||
⌊(A) The minimum by operation A |
|||
Here's an example code that makes the flag of Nepal, until I bailed out on "Eight equal and similar triangles of the moon are to be made in the space lying inside the semi-circle of No. (16) and outside the arc of No. (17) of this Schedule." |
|||
; The Flag of Nepal. |
|||
; Section A: Method of Making the Shape inside the Border |
|||
; On the lower portion of a crimson cloth draw a line AB of the required length from left to right. |
|||
•A(0,0) |
|||
•B(1,0) |
|||
-AB |
|||
; From A draw a line AC perpendicular to AB making AC equal to AB plus one third AB. |
|||
-AC⟂-AB(ΔAB × 4 / 3) |
|||
; From AC mark off D making line AD equal to line AB. |
|||
-AD=-AC≅-AB |
|||
; Join BD. |
|||
-BD |
|||
; From BD mark off E making BE equal to AB. |
|||
-BE=-BD≅-AB |
|||
; Touching E draw a line FG, starting from the point F on line AC, parallel to AB to the right hand-side. |
|||
; Mark off FG equal to AB. |
|||
-FG+•E+•C=-AB≅-AB |
|||
; Join CG. |
|||
-CG |
|||
; Section B: Method of Making the Moon |
|||
; From AB mark off AH making AH equal to one-fourth of line AB and starting from H draw a line HI parallel to line AC touching line CG at point I. |
|||
-AH+-AB(ΔAB / 4) |
|||
-HI=-AB+CG |
|||
; Bisect CF at J and draw a line JK parallel to AB touching CG at point K. |
|||
•J(ΔC = ΔJ) |
|||
-JK=-AB+-CG→•K |
|||
; Let L be the point where lines JK and HI cut one another. |
|||
•L+-JK+-HI |
|||
; Join JG. |
|||
-JG |
|||
; Let M be the point where lines JG and HI cut one another. |
|||
•M+-JG+-HI |
|||
; With centre M and with a distance shortest from M to BD mark off N on the lower portion of line HI. |
|||
○%M%-BD+HI→(N|⌊(Δ-FG)) |
|||
; Touching M and starting from O, a point on AC, draw a line from left to right parallel to AB. |
|||
•O+-AC+•M=-AB |
|||
-OM |
|||
; With centre L and radius LN draw a semi-circle on the lower portion and let P and Q be the points where it touches the line OM respectively. |
|||
◠L(ΔLN)+-OM→{•P, •Q}→◘PNQ |
|||
; With centre M and radius MQ draw a semi-circle on the lower portion touching P and Q. |
|||
◠M+•P+•Q+◠L |
|||
; With centre N and radius NM draw an arc touching PNQ [sic] at R and S. |
|||
; Join RS. |
|||
; Let T be the point where RS and HI cut one another. |
|||
○%N+◘PNQ→{•R, •S} |
|||
◠RS+•N |
|||
•T+-RS+-HI |
|||
; With centre T and radius TS draw a semi-circle on the upper portion of PNQ touching it at two points. |
|||
◠RS+•T |
|||
= Fighting Simulator 3 Query Language = |
|||
''Made in 21 June 2023.'' |
|||
A re-imagining of the Esolang language in this RPG I'm on into an SQL-like syntax. |
|||
FS3QL Client v1 |
|||
Connected to server 'fs3". |
|||
FS3QL> UPDATE Players SET Health <- 1 WHERE ID = 10: |
|||
FS3QL> UPDATE Players/Inventory[{1}][{0}] SET ID <- {402}, Count <- {2} WHERE ../ID = {10}: |
|||
FS3QL> .verbose |
|||
FS3QL> CREATE PROCEDURE IncrementCount VALUES AS BEGIN |
|||
... > UPDATE Players/Inventory[((Row))][((Slot))] SET Count <- Count + ((Number)) WHERE ../ID = @Player |
|||
... > END: |
|||
FS3QL> EXEC IncrementCount <{10} - RandInt<{0} - {1}> - RandInt<{0} - {11}> - RandInt<{1} - {5}>>: |
|||
EXEC IncrementCount <{10} - {0} - {0} - {5}>: |
|||
EXEC IncrementCount <{10} - {0} - {9} - {5}>: |
|||
EXEC IncrementCount <{10} - {1} - {6} - {5}>: |
|||
EXEC IncrementCount <{10} - {1} - {11} - {5}>: |
|||
FS3QL> UPDATE Players SET Health <- Health - 15: |
|||
WARNING: Players/ID <- {1} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {2} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {3} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {7} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {8} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {9} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {13} is AFK and cannot be modified |
|||
WARNING: Players/ID <- {14} is AFK and cannot be modified |
|||
FS3QL> UPDATE Players SET Health <- Health + {25} WHERE ID = 10: |
|||
FS3QL> |
|||
= Agent-based esolangs = |
= Agent-based esolangs = |
||
These are two of what I call "agent-based" languages. The main idea is there are agents (which could be anything, inorganic or not) with their certain traits that could communicate with each other. |
These are two of what I call "agent-based" languages. The main idea is there are agents (which could be anything, inorganic or not) with their certain traits that could communicate with each other. |
||
Line 432: | Line 124: | ||
}. |
}. |
||
== Smalltalk-like version 2 == |
|||
= Seedling = |
|||
''Made in |
''Made in 17 July 2024.'' |
||
This one follows the previous Smalltalk-like syntax, but written in the way I envisioned it to be. |
|||
A simple declarative programming language. The initial idea is that it's supposed to be an injective language where the source modifies how statements are parsed. It was supposed to look like a C-like language, but that didn't work out so I made it look ML-like instead. Now it almost looks like an esolang someone else have made before... |
|||
agent: Example traits: [runnable] |
|||
''(Originally the braces and the parentheses role are swapped, but I swapped it to what's shown here for aesthetics)'' |
|||
use: sys/terminal as: Terminal |
|||
use: lang/text as: TextOP |
|||
from $from:int to $to:int do $fn = $fn $from ($from <= $to) {from ($from + 1) to $to do $fn} {} |
|||
on: main do: { |
|||
either $x or $y = ($x = "") $y $x /* might be included in prelude */ |
|||
define var: name. |
|||
fizzbuzz $x:int = print (either (join (($x % 3 = 0) Fizz "") with (($x % 5 = 0) Buzz "")) or $x) |
|||
ask about: "What is your name? " > (name). |
|||
TextOP < compare value: (name) equals: "Gilbert" > if true: () do: { |
|||
print text: "Hello, myself!". |
|||
} else: { |
|||
TextOP < format pattern: "Hello, {}." with: [(name)] > print text: (). |
|||
}. |
|||
} |
|||
on: print args: [text] do: { |
|||
Terminal < write line: (text). |
|||
} |
|||
Execution steps: |
|||
main |
|||
from 1 to 100 do fizzbuzz |
|||
fizzbuzz 1 (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join ((1 % 3 = 0) Fizz "") with ((1 % 5 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join ((1 = 0) Fizz "") with ((1 % 5 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join (false Fizz "") with ((1 % 5 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join ("") with ((1 % 5 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join "" with ((1 % 5 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join "" with ((1 = 0) Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join "" with (false Buzz "")) or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either (join "" with "") or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either ("") or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (either "" or 1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (("" = "") 1 "") (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (true 1 "") (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print (1) (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
print 1 (1 <= 100) {from 2 to 100 do fizzbuzz} {} |
|||
(1 <= 100) {from 2 to 100 do fizzbuzz} {} /* prints 1 */ |
|||
true {from 2 to 100 do fizzbuzz} {} |
|||
from 2 to 100 do fizzbuzz |
|||
... |
|||
(101 <= 100) {from 101 to 100 do fizzbuzz} {} |
|||
false {from 101 to 100 do fizzbuzz} {} |
|||
{} /* success: exit code 0 */ |
|||
== Math == |
|||
#define angle ($decimal)deg |
|||
#import math |
|||
on: ask args: [about] do: { |
|||
$x:angle to radians = (PI / 180 * $x:0) |
|||
Terminal < { |
|||
sin $x:angle = sin ($x to radians) |
|||
write line: (about). |
|||
cos $x:angle = cos ($x to radians) |
|||
read until: "\n" > answer with: (). |
|||
tan $x:angle = tan ($x to radians) |
|||
} > answer with: (). |
|||
sec $x:angle = sec ($x to radians) |
|||
} |
|||
csc $x:angle = csc ($x to radians) |
|||
cot $x:angle = cot ($x to radians) |
|||
ctg $x:angle = ctg ($x to radians) |
|||
cosin $x:angle = cosin ($x to radians) |
|||
cosec $x:angle = cosec ($x to radians) |
|||
cotan $x:angle = cotan ($x to radians) |
|||
main = print (cos 60deg) |
|||
Note the <code>runnable</code> written in lowercase: this is an added lore to this language (more of a retcon really) where initially this language is read in a machine that's case insensitive (like COBOL!) |
|||
= Babalog-1 = |
|||
''Made in 4 April 2024.'' |
|||
Here's an example of how a simulator might run the above script. |
|||
Probably not Turing complete. |
|||
$ aasim -x example.agent |
|||
Babalog-1 |
|||
What is your name? Hale |
|||
Hello, Hale. |
|||
Enter ? to go into query mode, and | to go back into rule mode. |
|||
$ aasim -x example.agent -vv |
|||
|- (this is a comment) |
|||
[INFO] Starting agent Example |
|||
|- BABA IS YOU |
|||
[DEBUG] Sys/Terminal: [INFO] Starting agent Sys/Terminal as required by Example |
|||
|- FLAG IS WIN |
|||
[DEBUG] Lang/Text: [INFO] Starting agent Lang/Text as required by Example |
|||
|- FLAG IS BABA (gives quality BABA) |
|||
[DEBUG] Sys/Terminal: [INFO] Started agent Sys/Terminal as required by Example |
|||
|- KEKE IS MOVE |
|||
[DEBUG] Lang/Text: [INFO] Started agent Lang/Text as required by Example |
|||
|- KEKE MIMIC BABA (copies qualities of BABA) |
|||
[DEBUG] Started agent Example |
|||
|- SKULL IS DEFEAT |
|||
[DEBUG] Calling Example to do `main` |
|||
|- ALL IS OPEN |
|||
What is your name? Gilbert189 |
|||
|- ME IS NOT OPEN |
|||
Hello, myself! |
|||
|- ALL FEELING DEFEAT IS SAFE |
|||
[DEBUG] `main` answered with null |
|||
|- ALL FEELING SHUT IS NOT OPEN |
|||
[INFO] Stopping agent Example |
|||
|- DOOR IS SHUT |
|||
[DEBUG] Sys/Terminal: [INFO] Stopping agent Sys/Terminal |
|||
|- SKULL FEELING OPEN IS SINK |
|||
[DEBUG] Stopped agent Example |
|||
|- ? |
|||
[DEBUG] Lang/Text: [INFO] Stopping agent Lang/Text |
|||
?- BABA |
|||
[DEBUG] Sys/Terminal: [INFO] Stopped agent Sys/Terminal |
|||
IS YOU |
|||
[DEBUG] Lang/Text: [INFO] Stopped agent Lang/Text |
|||
IS OPEN (from ALL) |
|||
$ |
|||
?- FLAG |
|||
IS WIN |
|||
IS BABA |
|||
IS OPEN (from ALL) |
|||
?- KEKE |
|||
IS MOVE |
|||
IS YOU (from BABA) |
|||
IS OPEN (from ALL) |
|||
?- SKULL |
|||
IS DEFEAT |
|||
IS OPEN (from ALL) |
|||
IS SAFE (because FEELING DEFEAT from ALL) |
|||
IS SINK (because FEELING OPEN from SKULL) |
|||
?- ME |
|||
<s>IS OPEN</s> (from ALL) |
|||
IS NOT OPEN |
|||
?- DOOR |
|||
<s>IS OPEN</s> (from ALL) |
|||
IS NOT OPEN (because FEELING SHUT from ALL) |
|||
IS SHUT |
|||
?- IS YOU |
|||
BABA |
|||
KEKE |
|||
?- IS OPEN |
|||
BABA |
|||
FLAG |
|||
KEKE |
|||
SKULL |
|||
?- MIMIC BABA |
|||
KEKE |
|||
?- .? |
|||
(insert help here) |
|||
?- .?? |
|||
Information about Babalog-1 |
|||
Special nouns |
|||
ALL: encapsulates all names (for every name X, X MIMIC ALL) |
|||
Operators |
|||
IS: assigns a quality to a name |
|||
MIMIC: copies all qualities assigned to a name |
|||
FEELING: applies a rule only when the specified quality is assigned to a name |
|||
NOT: falsifies the following phrase (ex. NOT WIN falsifies WIN, NOT NOT WIN falsifies NOT WIN) (a |
|||
?- .X |
|||
Here's an example of an agent that uses <code>Example</code> for their purpose. |
|||
= An esolang as an engelang = |
|||
''Made in late June 2024.'' |
|||
agent: RemoteExample traits: [runnable] |
|||
Usually esolangs and conlangs are made as seperate writing projects. But what if we develop an esolang as if it's a conlang? (Or the other way around?) |
|||
use: Example as: Example |
|||
<blockquote> |
|||
use: lang/text as: TextOP |
|||
:''Isn't this just Loglan/Lojban?'' |
|||
Not quite, Loglan (and its successor Lojban) isn't made as an esolang; it's not meant to be a language for computers. Sure, computers can ''read'' Loglan, and you could make an esolang from Lojban (in fact I'm surprised no one has made one yet), but that alone doesn't qualify Lojban as an esolang. You might as well consider [[English]] an esolang if you follow that logic. |
|||
</blockquote> |
|||
Now, I am by no means the first one coming up with this idea. Probably someone had made something like this before that I didn't know. Also, while I am a fairly competent esolanger, a competent conlanger I am not, in fact I can barely understand what I'm adding and what I need to add on my 3 conlangs I've made so far. Still, it's worth a shot, I guess... |
|||
Also, I need to clean up my browser tabs. My computer is screaming for more RAM space. |
|||
== Phonology == |
|||
Here is the phonemic inventory of this language: |
|||
{| class="wikitable floatleft" style="text-align: center;" |
|||
|+ Consonants |
|||
|- |
|||
! |
|||
! Labial !! Alveolar !! Palatal !! Velar |
|||
|- |
|||
! Nasal |
|||
| m || n || ɲ || ŋ |
|||
|- |
|||
! Plosive |
|||
| p || t || c || k |
|||
|- |
|||
! Fricative |
|||
| f || s || ç || x |
|||
|- |
|||
! Approximant |
|||
| w || l || j || (w) |
|||
|} |
|||
{| class="wikitable" style="text-align: center;" |
|||
|+ Vowels |
|||
|- |
|||
! rowspan=2 | |
|||
! colspan=2 | Front |
|||
! colspan=2 | Central |
|||
! colspan=2 | Back |
|||
|- |
|||
! short !! long !! short !! long !! short !! long |
|||
|- |
|||
! Closed |
|||
| i || iː || || || u || uː |
|||
|- |
|||
! Middle |
|||
| e || eː || || || o || oː |
|||
|- |
|||
! Open |
|||
| || || a || aː || || |
|||
|- |
|||
! Diphthongs |
|||
! colspan=6 | ae ea oa ao iu ui |
|||
|} |
|||
Very regular, huh? Well, that's for a purpose: I want to represent a single syllable as a single byte: a nibble for the consonant, another for the vowel. More on that is at the Orthography section. |
|||
=== Phonotactics === |
|||
The syllable structure is simple; a consonant followed by a vowel. The consonant may be omitted as a prefix. |
|||
== Orthography == |
|||
Orthography is relatively simple: it's just the IPA except /ɲ/ is written as ⟨ny⟩ and /ŋ/ is written as ⟨ng⟩. /ç/ may also be written as ⟨h⟩. Long vowels are written twice ⟨ii⟩ or with a macron ⟨ī⟩. |
|||
As I have written earlier, we can also represent a single syllable as a byte. Here's a conversion table (too lazy to make a Wiki table): |
|||
0 1 2 3 4 5 6 7 8 9 A B C D E F |
|||
Consns. (Nx) m n ɲ ŋ p t c k f s ç x w l j - |
|||
Vowels. (xN) i iu u e o oa a ae iː ui uː eː oː ao aː ea |
|||
The <code>Fx</code> byte is repurposed as control syllables (though some are still spoken). |
|||
lilo |
|||
F0 “ (start of phrase) |
|||
F1 |
|||
F2 ” (end of phrase) |
|||
F3 , (clause joiner) (either spoken as particle /e/ or a short pause) |
|||
F4 |
|||
F5 |
|||
F6 $ (proper noun marker) (spoken as prefix /a/) |
|||
F7 |
|||
F8 # (numeral marker) (spoken as prefix /iː/) |
|||
F9 |
|||
FA |
|||
FB |
|||
FC |
|||
FD |
|||
FE _ (space) |
|||
FF . (sentence seperator) |
|||
== Grammar == |
|||
Generally this language would be in VSO, but there are also some SVO ordering as well in form of infix verbs. This is implemented by making a stack frame that expects one noun, and then using the top value of the previous stack frame. |
|||
Here's a pseudocode of such parser: |
|||
enum Token { |
|||
Noun; |
|||
Function(args); // verbs, maybe adjectives |
|||
Infix; // also verbs |
|||
EOF; |
|||
} |
|||
on: main do: { |
|||
function parse(string) { |
|||
Example < { |
|||
let nounStack = new StackFrames(); |
|||
ask about: "Input anything. " |
|||
nounStack.newFrame(); |
|||
> TextOP < format "Got input {}" with [()] |
|||
let funcStack = new Stack(); |
|||
> print text: (). |
|||
while (typeOf(token = nextToken(string)) != Token.EOF) { |
|||
switch (typeOf(token)) { |
|||
case Token.Noun: |
|||
nounStack.currentFrame.push(token); |
|||
while (!funcStack.isEmpty()) { |
|||
if (typeOf(funcStack.top) == Token.Function && nounStack.currentFrame.length == funcStack.top.args) { |
|||
let func = funcStack.pop(); |
|||
let result = func.eval(...nounStack.currentFrame); |
|||
nounStack.deleteFrame(); |
|||
nounStack.currentFrame.push(token); |
|||
} else if (typeOf(funcStack.top) == Token.Infix && nounStack.currentFrame.length == 1) { |
|||
let func = funcStack.pop(); |
|||
let rightSide = nounStack.currentFrame.pop(); // object |
|||
nounStack.deleteFrame(); |
|||
let leftSide = nounStack.currentFrame.pop(); // subject |
|||
let result = func.eval(leftSide, rightSide); |
|||
nounStack.currentFrame.push(token); |
|||
} |
|||
} |
|||
break; |
|||
case Token.Function: |
|||
case Token.Infix: |
|||
funcStack.push(token); |
|||
nounStack.newFrame(); |
|||
break; |
|||
} |
|||
} |
} |
||
return nounStack.currentFrame; |
|||
} |
} |
||
And here's how it runs in the simulator: |
|||
== Vocabulary == |
|||
Initially I was intending this language to be completely ''a posteriori'' (because I don't think computers would make a good natural lexicon, but now that I think of it that is such a silly reason), so I searched for a proto-language that closely matches this phonetic inventory, which turned out to be Proto-Austronesian, of which its descendant is a language I can speak :) However, eventually I made a word generator since I'm getting tired of finding PAN words on Wiktionary. |
|||
$ aasim remote-example.agent -vv |
|||
Later, I also found Proto-Austroasiatic which has a better-fitting phonemic vocabulary, even down to the vowel length. It has less words though, so not sure if it matters. |
|||
[INFO] Starting agent RemoteExample |
|||
[DEBUG] Example: [INFO] Starting agent Example as required by RemoteExample |
|||
[DEBUG] Sys/Terminal: [INFO] Starting agent Sys/Terminal as required by Example |
|||
[DEBUG] Lang/Text: [INFO] Starting agent Lang/Text as required by Example |
|||
[DEBUG] Sys/Terminal: [INFO] Started agent Sys/Terminal as required by Example |
|||
[DEBUG] Lang/Text: [INFO] Started agent Lang/Text as required by Example |
|||
[DEBUG] Example: [INFO] Started agent Example |
|||
[DEBUG] Started agent RemoteExample |
|||
[DEBUG] Calling RemoteExample to do `main` |
|||
Input anything. 2763 |
|||
Got input 2763 |
|||
[DEBUG] `main` answered with null |
|||
[INFO] Stopping agent RemoteExample |
|||
[DEBUG] Example: [INFO] Stopping agent Example |
|||
[DEBUG] Sys/Terminal: [INFO] Stopping agent Sys/Terminal |
|||
[DEBUG] Example: [INFO] Stopped agent Example |
|||
[DEBUG] Lang/Text: [INFO] Stopping agent Lang/Text |
|||
[DEBUG] Sys/Terminal: [INFO] Stopped agent Sys/Terminal |
|||
[DEBUG] Stopped agent RemoteExample |
|||
[DEBUG] Lang/Text: [INFO] Stopped agent Lang/Text |
|||
$ |
|||
Here's another agent that demonstrates concurrency in this language: |
|||
If there's no PAN word for something, I'll substitute it with their descendant, a word from PAA, something else (currently only Old Chinese), or with the aforementioned word generator. |
|||
agent: ForkedRandom |
|||
Here's the vocabulary for now (see page history for timestamp): |
|||
use: lang/number as: NumberOP |
|||
{| class="wikitable" |
|||
|- |
|||
! Word !! Meaning !! Etymology |
|||
|- |
|||
| kāfa || print || PAN: *kawaS₂, talk |
|||
|- |
|||
| pakae || input || PAN: *bajaq₁, ask |
|||
|- |
|||
| loko || read || OCH: 讀 /*C.lˤok/, read |
|||
|- |
|||
| faja || write || OCH: 寫 /*s-qʰAʔ/, write |
|||
|- |
|||
| kācā || scratch, delete || PAA: *kaːcˀ, to scratch |
|||
|- |
|||
| paxene || to execute, do || PAN*: **paRen<ref group="CELdictnote">derived from *paR-walu-en (do eight times), *paR-Sepat-en (do four times), and *paR-enem-en (do six times).</ref> |
|||
|- |
|||
| nana || way, in manner of || PAN: *-an, instrumental voice (n- added) |
|||
|- |
|||
| pofo || change || OCH: 變 /*pro[n]-s/, to change |
|||
|- |
|||
| pulanga || repeat || PAN: *ulaŋ, repeat (p- added) |
|||
|- |
|||
| na || if || OCH: 如 /*na/, if |
|||
|- |
|||
| tenoana || but if || tenoa + na |
|||
|- |
|||
| pemene || for each || PAN: *qemin, all (p- added) |
|||
|- |
|||
| sufuxu || with || PAN: *CuSuR, string together |
|||
|- |
|||
| paehea || add || GEN: pl |
|||
|- |
|||
| mētea || subtract || GEN: mn |
|||
|- |
|||
| somi || multiply || GEN: ti |
|||
|- |
|||
| līwea || divide || GEN: dv |
|||
|- |
|||
| la || and || PAN: *Na₁, and |
|||
|- |
|||
| tē || or || GEN: or, first syllable elided |
|||
|- |
|||
| xeni || this || PAN: *(i-)ni, this (x- added) |
|||
|- |
|||
| xesu || that || PAN: *(i-)Cu, that (x- added) |
|||
|- |
|||
| tenoa || yes, true || GEN: da |
|||
|- |
|||
| fohao || no, false || GEN: net |
|||
|- |
|||
| pilanga || to count, to calculate || PAN: *bilaŋ₁, to count |
|||
|- |
|||
| poaka || white || PAA: *ɓɔːk, white |
|||
|- |
|||
| cojongo || black || PAA: *Cjoŋ, black (/C/ → /c/) |
|||
|- |
|||
| lōngō || red || PAA: *roːŋ, red |
|||
|- |
|||
| kici || green, blue || PAA: *kciʔ, green |
|||
|- |
|||
| xōcō || finish || PAA: *hoːcˀ, finish |
|||
|- |
|||
| wili || return || PAN: *wili, return |
|||
|- |
|||
| lipaha || continue || PAN: *lipas, pass by |
|||
|- |
|||
| tenēmē || start || PAA: *tnəːm, stem |
|||
|- |
|||
| kāxi || left, before, preceding || PAN: *ka-wiRi, left side |
|||
|- |
|||
| lilo || equal || GEN: is |
|||
|- |
|||
| tama || right, after, succeeding || PAA: *tam, right side |
|||
|- |
|||
| nēcea || 1<sub>SG</sub>, I, myself || GEN: me |
|||
|- |
|||
| kana || 3<sub>SG</sub>, it, itself || PAA: *ʔan (k- added) |
|||
|- |
|||
| keke || animal || Keke from Baba is You |
|||
|- |
|||
| mī || human || Me from Baba is You |
|||
|- |
|||
| kafiu || writing board, memory || PAN: *kaSiw, wood |
|||
|- |
|||
| loana || round, loop || PAA: *lɔːn, round |
|||
|} |
|||
(I know, it's too small. I put this esolang in this article for a reason.) |
|||
<hr> |
|||
<references group="CELdictnote" /> |
|||
Here are some helpful links from my worktable: |
|||
[https://tio.run/##5VdPTxtHFD/bn@JlU6m7iWOH0FMUghBJk1wogvQEtBrvju2B8cxmdgfjUKTckSKkolRRVEWoB87lKyAOBuUz0Te7O2ZnbaNEqnqpBLK97/d@@/7Ne2/iYdqTYv6a9WOpUlC0HnKSJLBGu3SPtDldTxUTXT9JVfC4XotoBzExJyH1E8o7DYhJ2oBUGmEt0W1YQHkTv/iFoAEGF6CUdcAA7ixkTwy@FiN36ne8ffPkAB48hX2EHIDf2kf1g1b2JJV31EHgGQpFU63EpHG6HdTrxrawR0SX/hoT4Q@kihrAYrLwI@EJNQZ6nrcu@7QnB2B4ElhdWgG0QELaYwnEGAnaZyE@2qX4VA1Rpw8CRmdwcVivxZBCCDv1GjoC56ewV68NgMM23KvXawyAadAAFOo1CSAJEABCUXJ1BJqBxg96dYRC/EIkEPObZEbVa8s/raxj6Ly@GJ1dHMZpuNNJzk/3BnwbhYXXfr3m43@t6r1x1ATnLqzIFG3HICgpJJddFhIOKKWqCUs8kbBL1RBCrRIaNVGjaVPpPfMa4I0@eAHAXUwavFpdcuSJkZ@fzpSvG3kyU7xixJfvZ8q3jfzFWOyh3IPW6OTyrOXgzv/O7DybSbSWveidKw8AS0@Y2MQEKNbC7CAGDtsbw5Zztd5kxXjPkaNHCOAF4vJ9Bmlx1@aewewVmF4O2XMhbQOJc4jALEkWok0OJDKQ9FZI10B2boW8yCCsMCaLb2bPDnMNGv1l4@j6@67si7K@gJ8dH/zLS8tVCo3OW/vKz19OLv/MFcMvJ@enqNynqktdnbdGJyx0ClymUjHzQxk3@mBBJfdNC8IexUlK@GRFdwrVJNfsuPTLpaJupV9OClTiosjQwIgNKtnOUaQSUjLIYNrCBgVMuzCdsWnLpgs2XWFjGRuzbKxgYxW20UcDozZAH3MUdUDKY/7igvjt4jDwm/eC71BDeXRzzlK3TEvpMIGtJBlybs4MtGlHKgot0cL2Aq2Lw@nEepJYjon1NxDLCrG/QZimcivY4NtbOTHy3vc29cP5hz/kL9iVAzzrljF/D2dvNIvwWYhjIAEucVgoN006S5O0adJFmmQlmyyD2chisnMYraSJZPEnNpakiBNx/ekYhyiTeivwN/bNLDjYCu5bvzYf2ZgtRVHulilqKiKsbwilSKQgIk0mKC1T@VvxGks9j@TzOfnPIuQ6Salib@lEtHOt4nP/0cH0kC9LEVGRUMCeGvfMYtFN8vlqIl1kxOUm/sYvOev9xYCSjJdsztnIvqSs20uhR1RfiuFjSAYkzuI3rpRKKD1aJkSaopptDqYTYt7GhNUidiyUNxbK2wjlLRZKx0Jpj4W83UJ5Q5jV4l1Ye77@fGlt@eVjeCaxmJcweTj3acKIAI5rkCZdfNwju9Q2QEu6CP6qkm08cUMzFxvQ1im8@p5zTBYWQYQJ7NE@EDEckGEzqB7qkvlMZ@brzTnbslbdV1n7sTON7dcT/afEqFnGyDbnbHebwYgtcczI8oi8VkQknGENE45V3IBXZrETO@4OcWrOZK84ksVkedJ76jbOMwMSQ9s58zn5RAxd2MVhBusWsKJdPRHdp2aVcDdSku8YU9dQJVP5IE8gwfyl2Q6araUUiHGxj/sow@RGU5bU5rdskDO3x5Lvvxun2rlPeC/gMmG7WEldae4HkQ5p5OL/MPjoq/H/2bYz@lxaD2Zh3An5aWqD9kafro4WnVY@E3lcIOUYeVzMsAqS5a@@meF2PFeHuM6BNzuBBVaXgsvj0r56eTxlYf2KXVSVV1o1baMtjSv09X82sf6NzlCCXR0ZWNkiNAQbBq5CId7ghFHqkxD7OjaU6/y6XLrjejFKzCZrrrmvlaZBUJ8EDRjH2pmQEKwHvIvi@Qiur/8B Sound changer] |
|||
[https://tio.run/##XZLBctowEIbP@Cl23JlEaqjHYKAZJuTYJ@iNuhkZL1jFSB5JLmaml54zPfUxcsszwCFPRdcyBSa2D@tvV79@7arauUKr5HiUm0obB4WwRSmzYKtNDjOQqqod40FB8SkVKdyyW1uI5Gk4ntxSLqqrXDhk7ZoI1ULnyDgPcrlC69qFUReSjnVUSGgulYuWRm@esp1Dy7qCeTNt7u7TPoSldK7EkMNSG2jIBhihVsjiPiTDPtzzNFho9RONw86m87tTdsIjp0@qJSqPOXyEhFQzuQp5ZJ2RFcvCbzHpwwdYicq2Cqic1EqUgdHlZESqpdhkuYCmD@spsAYeHmDN4VcbPj4Co5pPBHjQemw3bG2eXU2D3raQJcJXUyP99Azaumzb4Xswj1O4O4VJSulLZpC2Ow0@e3gzg7j58u6hDH1d9TCF7xfNM06u8OCCB1d4eMHxFfZu3sm7a90Z@Aax/6APozHv1vguUP3prDfeO3G57BrkQQwzf6h42nY/1@rWQW0RXCEt1faohU6qGimuTDvZcKPeXg/PlVusl7ZotuWPcO7laAqjNDJYlWKBLHx7DWnIakczPrPDs2c09z6gymdhyC@6EmQNNSBo0ALoRdi/QC3h8AL7v3D4A0LD/jegCCNb0Z1kfH46x2CcXgtmBsX6ePwH Word maker] |
|||
=== Numbering system === |
|||
I've sketched up a numbering system for this language. Not sure if I'll use it, since I don't think computers would benefit from this. |
|||
zero nae |
|||
one kū |
|||
two la |
|||
three jo |
|||
four lā |
|||
five xoa |
|||
six nye |
|||
seven joa |
|||
eight sī |
|||
nine pā |
|||
ace so |
|||
bing ngē |
|||
click li |
|||
dot fe |
|||
elf lī |
|||
fern ngō |
|||
(from "p(number/8)") |
|||
-tix (8-bit) ngāso |
|||
-dix (16-bit) pānoa |
|||
-mix (32-bit) fōnea |
|||
-bix (64-bit) nyaha |
|||
-trix (128-bit) lalō |
|||
-quix (256-bit) taenū |
|||
7 |
|||
seven |
|||
īlā |
|||
8F |
|||
eighttixfern |
|||
īsīngāsongō |
|||
CFC4 |
|||
clicktixferndix clicktixfour |
|||
īlingāsongōpānoalingāsolā |
|||
EDB88320 |
|||
elftixdotdix bingtixeightmix eighttixthreedix twotix |
|||
īlīngāsofepānoangēngāsosīfōneasīngāsojopānoalangāso |
|||
== Example <del>text</del> code == |
|||
Are you serious? This esolang is barely developed... |
|||
Okay, maybe a fizz buzz program. Note that this is just a sketch, I don't think this is how the language should look like eventually, but you may use this as some sort of appetizer, I suppose. |
|||
faja akafiupilanga sufuxu akafiujonanapilanga sufuxu akafiuxoananapilanga īnae. |
|||
on: get-one do: { |
|||
paxene loana. |
|||
NumberOP < random from: 0.0 to: 1.0 > answer with: (). |
|||
pofo akafiupilanga sufuxu akafiujonanapilanga sufuxu akafiujonanapilanga kana paehea īkū. |
|||
} |
|||
na lilo akafiuxoananapilanga īxoa la lilo akafiuxoananapilanga īxoa, |
|||
kāfa “fisi pasa” |
|||
e pofo kana īnae. |
|||
tenoana lilo akafiujonanapilanga ījo, |
|||
kāfa “fisi” |
|||
e pofo kana īnae. |
|||
tenoana lilo akafiuxoananapilanga īxoa, |
|||
kāfa “pasa” |
|||
e pofo kana īnae. |
|||
tenoana tenoa, kāfa akafiupilanga. |
|||
lipaha. |
|||
on: get-three do: { |
|||
na kāxi akafiupilanga īsīngāsopā, paxene loana. |
|||
-- Parallel commands can be done with vertical lines... |
|||
pulanga. |
|||
NumberOP < random from: 0.0 to: 1.0 | NumberOP < random from: 0.0 to: 1.0 | NumberOP < random from: 0.0 to: 1.0 |
|||
> answer with: [(0) (1) (2)]. |
|||
And here is the representation in hex: |
|||
} |
|||
00000000 86 E6 FE F6 76 80 F2 40 D6 36 FE 92 82 B2 FE F6 †æþöv€ò@Ö6þ’‚²þö |
|||
00000010 76 80 F2 E4 16 16 40 D6 36 FE 92 82 B2 FE F6 76 v€òä≠≠@Ö6þ’‚²þöv |
|||
00000020 80 F2 B4 F6 16 16 40 D6 36 FE F8 16 F3 FF 46 B3 €ò´ö≠≠@Ö6þø≠óÿF³ |
|||
00000030 13 FE D4 F6 16 FF 44 84 FE F6 76 80 F2 40 D6 36 ιþÔö≠ÿD„þöv€ò@Ö6 |
|||
00000040 FE 92 82 B2 FE F6 76 80 F2 E4 16 16 40 D6 36 FE þ’‚²þöv€òä≠≠@Ö6þ |
|||
00000050 92 82 B2 FE F6 76 80 F2 E4 16 16 40 D6 36 FE 76 ’‚²þöv€òä≠≠@Ö6þv |
|||
00000060 16 FE 46 F3 A3 F6 FE F8 7A FF 16 FE D0 D4 FE F6 ≠þFó£öþøzÿ≠þÐÔþö |
|||
00000070 76 80 F2 B4 F6 16 16 40 D6 36 FE F8 B4 F6 FE D6 v€ò´ö≠≠@Ö6þø´öþÖ |
|||
00000080 FE D0 D4 FE F6 76 80 F2 B4 F6 16 16 40 D6 36 FE þÐÔþöv€ò´ö≠≠@Ö6þ |
|||
00000090 F8 B4 F6 F3 7E 86 FE F0 80 90 FE 46 96 F2 FE F3 ø´öó~†þð€ĀþF–òþó |
|||
000000A0 FE 44 84 FE 76 16 FE F8 16 F3 FF 53 14 F6 16 FE þD„þv≠þø≠óÿSΣö≠þ |
|||
000000B0 D0 D4 FE F6 76 80 F2 E4 16 16 40 D6 36 FE F8 E4 ÐÔþöv€òä≠≠@Ö6þøä |
|||
000000C0 F3 7E 86 FE F0 80 90 F2 FE F3 FE 44 84 FE 76 16 ó~†þð€ĀòþóþD„þv≠ |
|||
000000D0 FE F8 16 F3 FF 53 14 F6 16 FE D0 D4 FE F6 76 80 þø≠óÿSΣö≠þÐÔþöv€ |
|||
000000E0 F2 B4 F6 16 16 40 D6 36 FE F8 B4 F6 F3 7E 86 FE ò´ö≠≠@Ö6þø´öó~†þ |
|||
000000F0 F0 46 96 F2 FE F3 FE 44 84 FE 76 16 FE F8 16 F3 ðF–òþóþD„þv≠þø≠ó |
|||
00000100 FF 53 14 F6 16 FE 53 14 F6 F3 7E 86 FE F6 76 80 ÿSΣö≠þSΣöó~†þöv€ |
|||
00000110 F2 40 D6 36 FF D0 46 A6 FF 16 FE 7E B0 FE F6 76 ò@Ö6ÿÐF¦ÿ≠þ~°þöv |
|||
00000120 80 F2 40 D6 36 FE F8 98 3E 94 4E F3 46 B3 13 FE €ò@Ö6þø˜>”NóF³ιþ |
|||
00000130 D4 F6 16 FF 42 D6 36 FF Ôö≠ÿBÖ6ÿ |
|||
= This Minecraft / MCFunction proglang = |
|||
''Made in 5 January 2024.'' |
|||
I wouldn't call this language esoteric, but it's an idea I had when I was toying around Minecraft's very low-level commands, and thinking "there must be a better way to develop using commands" |
|||
I'm interested to see something like this getting implemented, until I saw SethBling and his [https://github.com/SethBling/cbscript CBScript] achieving essentially the same thing. Oh well. |
|||
dummy $time $time_min $time_hour [* objectives *] |
|||
bossbar !progress^100 |
|||
on: get-five do: { |
|||
repeat ( |
|||
-- ...or with double brackets. |
|||
:time.ticks = /time query daytime [* stores into minecraft:time *] |
|||
{{ |
|||
NumberOP < random from: 0.0 to: 1.0. |
|||
$time = :time.ticks * 0.06 [* ticks to Minecraft minutes *] |
|||
NumberOP < random from: 0.0 to: 1.0. |
|||
$time_min = $time % 60 |
|||
NumberOP < random from: 0.0 to: 1.0. |
|||
$time_hour = ($time / 60) + 6 % 24 |
|||
NumberOP < random from: 0.0 to: 1.0. |
|||
if @s.Inventory[{Slot: -106b, id: "minecraft:clock"}] ( [* Only show digits when a clock is put offhand *] |
|||
NumberOP < random from: 0.0 to: 1.0. |
|||
/title @s actionbar c"$($time_hour):$($time_min)" |
|||
}} > answer with: [(0) (1) (2) (3) (4)]. |
|||
if $time_min < 10 /title @s actionbar c"$($time_hour):0$($time_min)" |
|||
} |
|||
) |
|||
) |
|||
) |
|||
function test ( |
|||
say "This is a function." |
|||
say "The value is $(value)." [* Macro lines don't need to be prefixed with $ *] |
|||
@s!progress = value |
|||
) |
|||
function setMaximum ( |
|||
@s!progress^ = value |
|||
) |
|||
As this agent doesn't have the trait <code>runnable</code>, we would have to use another way to interact with this agent. |
|||
== A descriptive example == |
|||
[* this is a comment *] |
|||
[* |
|||
These are the available variable types of this language. |
|||
$objective is a scoreboard objective |
|||
:tag is the value of minecraft:tag on world storage (from /data ... storage) |
|||
:tag.foo is the value of key foo in minecraft:tag |
|||
(in general it uses minecraft:nbt_path) |
|||
(you can also change the default "minecraft" namespace to something else |
|||
using the "namespace" command) |
|||
mod:tag is the value of mod:tag on world storage |
|||
!boss^10 is a bossbar with maximum value of 10 |
|||
!boss is a bossbar value |
|||
!boss^ is a bossbar's maximum value |
|||
. is the entity's data |
|||
.NoAI is the value of key NoAI of the entity's data |
|||
.Pos[0] is the first value of the list of key Pos of the entity's data |
|||
(in general it uses minecraft:nbt_path) |
|||
These may be prefixed with these object types: |
|||
@a are all the players in the world |
|||
@e are all the entities in the world |
|||
... you get the drill. It's just minecraft:entity. |
|||
Alice is a player named Alice (default for names without a sigil) |
|||
#(0 1 2) is a block in x: 0 y: 1 z: 2 |
|||
#(~ ~ ~) is a block at the entity's coordinates |
|||
*] |
|||
[* namespace example *] [* would set a namespace if it's not commented *] |
|||
[* use path/to/other/file *] [* would effectively append the contents of the file here *] |
|||
dummy $foo [* creates an objective of type dummy *] |
|||
health $bar [* creates an objective of type health *] |
|||
repeat ( |
|||
[* these commands are run every tick *] |
|||
$foo += 1 [* by default this is applied to the current entity *] |
|||
@s$foo += 1 [* this line functions identically to the line above *] |
|||
[* Supported operations are +, -, *, / (integer division), // (float division if possible), and % *] |
|||
) |
|||
function roll_call ( |
|||
[* all subcommands on /execute (except "store" and "summon") are put as their own command *] |
|||
as @a ( |
|||
say I'm present |
|||
) |
|||
[* |
|||
These lines function identically: |
|||
as @a run say I'm present |
|||
as @a /say I'm present |
|||
*] |
|||
) |
|||
function tell_time ( |
|||
dummy $time $time_min $time_hour |
|||
:time.ticks = /time query daytime [* stores into minecraft:time *] |
|||
$time = :time.ticks * 0.06 [* ticks to Minecraft minutes *] |
|||
$time_min = $time % 60 |
|||
$time_hour = ($time / 60) + 6 % 24 |
|||
if ($time_min >= 10) /tellraw @s c"It's $($time_hour):$($time_min)" |
|||
if ($time_min < 10) /tellraw @s c"It's $($time_hour):0$($time_min)" |
|||
) |
|||
function tell_time_compiled ( |
|||
[* This might be what the function tell_time will be compiled to. *] |
|||
scoreboard objectives add time dummy |
|||
scoreboard objectives add time_min dummy |
|||
scoreboard objectives add time_hour dummy |
|||
scoreboard objectives add const_24 dummy |
|||
scoreboard objectives add const_60 dummy |
|||
scoreboard objectives add const_6 dummy |
|||
scoreboard players set @s const_24 24 |
|||
scoreboard players set @s const_60 60 |
|||
scoreboard players set @s const_6 6 |
|||
execute store result storage time ticks long 1 run time query daytime |
|||
execute store result score @s time run data get storage time 0.06 |
|||
execute store result score @s time_min run scoreboard players get @s time |
|||
scoreboard players operation @s time_min %= @s const_60 |
|||
execute store result score @s time_hour run scoreboard players get @s time |
|||
scoreboard players operation @s time_hour /= @s const_60 |
|||
scoreboard players operation @s time_hour += @s const_6 |
|||
scoreboard players operation @s time_hour %= @s const_24 |
|||
execute if score @s time_min matches 10.. run tellraw @s [{"text": "It's "}, {"score": {"name": "*", "objective": "time_hour"}}, {"text": ":"}, {"score": {"name": "*", "objective": "time_min"}}] |
|||
execute if score @s time_min matches ..9 run tellraw @s [{"text": "It's "}, {"score": {"name": "*", "objective": "time_hour"}}, {"text": ":0"}, {"score": {"name": "*", "objective": "time_min"}}] |
|||
) |
|||
function conditionals #example ( [* tagged under #minecraft:example *] |
|||
[* |
|||
The following are a list of syntatic sugars using the "if" command, and their equivalent commands. |
|||
These also apply to "unless" as well. |
|||
*] |
|||
if #(^ ^ ^1) = #planks /say pointing a plank |
|||
if block ^ ^ ^1 #planks run say pointing a plank |
|||
if #(^ ^ ^1) = furnace and #(^ ^ ^1).Items[{Slot: 2b}] /say there's output in the furnace |
|||
if block ^ ^ ^1 furnace if data block ^ ^ ^1 Items[{Slot: 2b}] run say there's output in the furnace |
|||
if (@a.foodLevel = 20) /say I'm not hungry [* brackets are optional *] |
|||
as @a if data entity @s {foodLevel: 20} run say I'm not hungry [* "if entity" only allows a single entity *] |
|||
if :foo.bar /say okay |
|||
if storage foo bar run say okay |
|||
if :time.ticks = 20l /say okay |
|||
if storage time {ticks: 20l} run say okay |
|||
if @e /say I'm not alone |
|||
if entity @e run say I'm not alone |
|||
[* Note the dot. *] |
|||
if @e. /say I have data |
|||
as @e if data entity @s {} run say I have data |
|||
if $foo > $bar /say wow |
|||
if score @s foo > @s bar run say wow |
|||
if $bar <= 1 /say Peril! |
|||
if score @s bar matches ..1 run say Peril! |
|||
[* Implementation note: These commands (and probably more) would need temporary objectives or functions to work. *] |
|||
[* Example 1a: Comparing inequalities between different variable types *] |
|||
if $foo > :foo.bar /say wow |
|||
execute store result score @s temp1 run data get storage foo bar |
|||
execute if score @s foo > @s temp1 run say wow |
|||
[* Example 1b: Comparing inequalities between variable types other than objectives *] |
|||
if :foo.bar > :foo.baz /say wow |
|||
execute store result score @s temp1 run data get storage foo bar |
|||
execute store result score @s temp2 run data get storage foo baz |
|||
execute if score @s temp1 > @s temp2 run say wow |
|||
[* Example 2: Comparing variables other than objectives with a constant number *] |
|||
if :foo.bar = 10 /say wow |
|||
execute store result score @s temp1 run data get storage foo bar |
|||
scoreboard players set @s temp2 10 |
|||
execute if score @s temp1 = @s temp2 run say wow |
|||
[* |
|||
Exceptions to this example are: |
|||
1. Equality of a NBT value |
|||
if @a.foodLevel = 20 /say I'm not hungry |
|||
as @a if data entity @s {foodLevel: 20} run say I'm not hungry |
|||
2. |
|||
*] |
|||
[* Example 3: Executing a code block *] |
|||
if $foo = 10 ( |
|||
say Hello |
|||
say world |
|||
) |
|||
if score @s foo matches 10 run function temp1 |
|||
[* where the function minecraft:temp1 contains the code inside the block *] |
|||
) |
|||
function arguments #example ( |
|||
[* Unlike .mcfunction, you can add $(...) without prefixing your function with $ *] |
|||
say Argument is $(arg1) |
|||
[* To output the placeholders instead of interpolating them, you can escape them: *] |
|||
say Argument is \$(arg1) |
|||
) |
|||
function json_quotes #example ( |
|||
[* JSON quotes are prefixed with c and provides basic formatting for commands using raw JSON text format. *] |
|||
[* The following are examples of them and their equivalent commands. *] |
|||
tellraw @s c"This is plain text." |
|||
tellraw @s {"text": "This is plain text."} |
|||
tellraw @s c"It's not *that* obvious..." |
|||
tellraw @s [{"text": "It's not "}, {"text": "that", "italic": true}, {"text": " obvious..."}] |
|||
tellraw @s c"It's not \*that* obvious..." |
|||
tellraw @s {"text": "It's not \*that* obvious..."} |
|||
tellraw @s c"It's not **that** obvious..." |
|||
tellraw @s [{"text": "It's not "}, {"text": "that", "bold": true}, {"text": " obvious..."}] |
|||
tellraw @s c"It's not ***that*** obvious..." |
|||
tellraw @s [{"text": "It's not "}, {"text": "that", "bold": true, "italic": true}, {"text": " obvious..."}] |
|||
tellraw @s c"Fill in the blanks: _But I've already done that!_" |
|||
tellraw @s [{"text": "Fill in the blanks: "}, {"text": "But I've already done that!", "underline": true}] |
|||
tellraw @s c"Son of a ||birch||!" [* Sorry. *] |
|||
tellraw @s [{"text": "Son of a "}, {"text": "birch", "obfuscated": true}, {"text": "!"}] |
|||
tellraw @s c"#blue(I am blue.)" |
|||
tellraw @s {"text": "I am blue.", "color": "blue"} |
|||
tellraw @s c"#FE1F6F(Uh oh.)" |
|||
tellraw @s {"text": "Uh oh.", "color": "#FE1F6F"} |
|||
tellraw @s c"!https://example.com(Click me!)" |
|||
tellraw @s {"text": "Click me!", "clickAction": {"action": "open_url": "value": "https://example.com"}} |
|||
tellraw @s c"![say You clicked me!](Click me!)" [* this is the normal behaviour for values without any sigils *] |
|||
tellraw @s {"text": "Click me!", "clickAction": {"action": "run_command": "value": "say You clicked me!"}} |
|||
tellraw @s c"![?say You clicked me!](Click me!)" |
|||
tellraw @s {"text": "Click me!", "clickAction": {"action": "suggest_command": "value": "say You clicked me!"}} |
|||
tellraw @s c"![@You clicked me!](Click me)" |
|||
tellraw @s {"text": "Click me!", "clickAction": {"action": "copy_to_clipboard": "value": "You clicked me!"}} |
|||
tellraw @s c'Press "%(key.inventory)" to check your inventory!' |
|||
tellraw @s [{"text": "Press \""}, {"keybind": "key.inventory"}, {"text": "\" to check your inventory!"}] |
|||
tellraw @s c'Your score is $($foo)' |
|||
tellraw @s [{"text": "Your score is "}, {"score": {"name": "*", "objective": "foo"}}] |
|||
tellraw @s c'Alice\'s score is $(Alice$foo)' |
|||
tellraw @s [{"text": "Your score is "}, {"score": {"name": "Alice", "objective": "foo"}}] |
|||
tellraw @s c'minecraft:foo.bar = $(:foo.bar)' |
|||
tellraw @s [{"text": "minecraft:foo.bar = "}, {"source": "storage, "nbt": "bar"}] |
|||
) |
|||
function extended_syntax #appendix ( |
|||
[* |
|||
These are some officially unofficial extended syntax for this language. |
|||
If these were implemented, it should be as a dialect and not as the main language. |
|||
These extended syntax might be official if I feel like it. |
|||
*] |
|||
[* Statements in JSON quotes *] |
|||
tellraw @s c'Your score + 1 is $($score + 1)' |
|||
[* One of these for content matching *] |
|||
if foo.Inventory[] # {Slot: -106b} /say foo is holding something in the offhand |
|||
if foo.Inventory[] contains {Slot: -106b} /say foo is holding something in the offhand |
|||
if foo.Inventory[Slot] = -106b /say foo is holding something in the offhand |
|||
[* They're equivalent to this: *] |
|||
if foo.Inventory[{Slot: -106b}] /say foo is holding something in the offhand |
|||
[* Command repetitions *] |
|||
for i in 1 3 2 5 4 ( |
|||
if $foo > $(i) /say wow $(i) |
|||
if $foo < $(i) /say boo $(i) |
|||
) |
|||
for i from 1 to 11 step 2 ( [* forcibly inclusive *] |
|||
if $foo > $(i) /say wow $(i) |
|||
if $foo < $(i) /say boo $(i) |
|||
) |
|||
repeat 5 ( |
|||
say this line will be said 5 times |
|||
) |
|||
) |
|||
$ aasim -x random.agent |
|||
= TB²AGE = |
|||
[ERROR] Agent ForkedRandom has no trait `Runnable` |
|||
''Made in 30 August 2022.'' |
|||
$ aasim random.agent # -s implies -v |
|||
[INFO] Starting agent ForkedRandom |
|||
Again with "I'm not sure if this is esoteric enough". |
|||
[1]+ Stopped aasim -s random.agent |
|||
$ bg |
|||
-- 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
|||
[1]+ aasim -s random.agent & |
|||
-- This is an example of a Text-Based Text-Based Adventure Game Engine, or |
|||
$ aasim ForkedRandom |
|||
-- TB²AGE for short. |
|||
You are now commanding ForkedRandom. |
|||
< get-one |
|||
-- This begins the "main" room. |
|||
> 0.378571834 |
|||
-- The player will always start here. |
|||
< get-three |
|||
-- Prefixing text with $ allows the game to do engine-wide operations. |
|||
> [0.930591305 0.678678690 0.285028494] |
|||
@main |
|||
< get-five |
|||
$engine set pause on \ |
|||
> [0.498587492 0.184080535 0.469049644 0.704954824 0.901419385] |
|||
-- $engine set toggle step " |
|||
< get-seven |
|||
[@bedroom] |
|||
[ERROR] ForkedRandom doesn't implement `get-seven`. |
|||
< ^C |
|||
-- In this case, we go into the "bedroom" room. |
|||
You stopped commanding ForkedRandom. |
|||
$ aasim Blah |
|||
-- Each section is seperated by >2 newlines. |
|||
[ERROR] Agent Blah not found. |
|||
-- This section, for example, defines a placeholder. |
|||
$ |
|||
{person:a} |
|||
{*a} is in here. |
|||
-- Placeholders can also store actions, and can be styled by adding "|{style}". |
|||
{give:a:b} |
|||
$unset have_*a |
|||
You give {*a|Aa} to {*b}. |
|||
-- Any commands that's defined on the main room is global. |
|||
/quit |
|||
$engine quit |
|||
-- Prefixing commands with a symbol will make it a meta-command. This modifies |
|||
-- existing commands to decorate the outputs. This can be used to show |
|||
-- boilerplate text, like showing the current party or something. It can also |
|||
-- be used as a default text for something invalid. |
|||
-- There's a lot happening on this command. The *a wildcard matches every word |
|||
-- and stores it into the "a" variable. |
|||
-- Flags in curly brackets makes the commamd run under a condition. |
|||
/#use *a {!have_*a} |
|||
You don't have {*a|Aa}. |
|||
-- When prefixed with ?, the meta-command is called only when the command is |
|||
-- invalid. |
|||
/?use |
|||
You can't use that right now. |
|||
/?get *a |
|||
You can't get {*a|Aa} in here. |
|||
/?talk |
|||
There's nobody to talk to. |
|||
/?talk *a |
|||
There's nobody called {*a} here. |
|||
/?goto |
|||
You can't go there! |
|||
-- From the main room, you'll probably have guessed what most of this does. |
|||
@bedroom |
|||
You're in your bedroom. |
|||
/look |
|||
There's a bed and a desk on the opposite side. |
|||
There's a door on your side as well. |
|||
/look bed |
|||
The bed looks a bit worse of wear, but it's still quite comfy. |
|||
/look [desk|table] |
|||
The desk is a bit messy with papers. There's a pencil case open next to it. |
|||
/get pencil |
|||
You take Pencil. |
|||
$set have_pencil |
|||
/go [east|side|door] |
|||
[@hall] |
|||
/use pencil |
|||
You scribbled on the paper. |
|||
Doesn't seem like you can do anything with this. |
|||
@hall |
|||
You're in a hall. |
|||
-- A blank command will be executed on enter. |
|||
-- Prefixing flags with ! inverts it. |
|||
-- Prefixing text with ^ prevents text to be written in a new line. |
|||
/ {!the_pencil} |
|||
^{person:Bob} |
|||
-- The #N flag is flagged when the command is called N times. |
|||
/talk [|Bob] {!the_pencil, #1} |
|||
You talked to Bob. |
|||
Bob: "Hey, can I borrow your pencil? I kinda need it for something." |
|||
[#ask_pencil] |
|||
#ask_pencil |
|||
> Yes #accept |
|||
> No #deny |
|||
#accept |
|||
"Thanks! I'll return it later." |
|||
$set the_pencil_ip |
|||
#accept {have_pencil} |
|||
{give:pencil:Bob} |
|||
Bob: "Thanks! I'll return it later. Well, I'm leaving now. Bye!" |
|||
$set the_pencil |
|||
#accept {have_pencil, the_pencil_ip} |
|||
{give:pencil:Bob} |
|||
Bob: "Thanks! Well, I'm leaving now. Bye!" |
|||
$set the_pencil |
|||
$unset the_pencil_ip |
|||
#deny |
|||
"Oh. That sucks." |
|||
"Well, tell me if you change your mind." |
|||
/talk [|Bob] {!the_pencil, #2-} |
|||
Bob: "Can I borrow your pencil?" |
|||
[#ask_pencil] |
Revision as of 08:37, 19 July 2024
Agent-based esolangs
These are two of what I call "agent-based" languages. The main idea is there are agents (which could be anything, inorganic or not) with their certain traits that could communicate with each other.
Around this time, I like to make keywords first-class (that is, you can feed in keywords like print
into a function).
Smalltalk-like
This variant resembles Smalltalk, at least in the looks. I don't really like this variant anymore, since for something that uses <
to ask others, using parenthesis to feed outputs feels like a bad match. Oh well.
I agent: Main traits: [Runnable Stateful]. I use: "System:IO/Input" as: Input. I use: "System:IO/Output" as: Output. I use: "Toolbox:Operations/String" as: StringOP. I on: run do: { put to: name value: (I < ask about: "What's your name?"). if true: (StringOP < compare value: (get value: name) equals: "Gilbert") do: { Output < write text: "Hello, myself!". } else: { Output < write text: (StringOP < format text: "Hello, {}!" with: [(get value: name)]). }. }. I on: ask args: [about] do: { Output < write text: (get argument: about). answer with: (Input < read until: "\n"). }.
You could see this language being used in a digital thermostat that talks using MQTT:
I agent: Thermostat traits: [Periodic Stateful]. I use: "System:Environment" as Env. I use: "Toolbox:Operations/Number" as: NumOP. I use: "MQTT:example.mqtt:8883" as: MQTT config: [ username: (Env < get var: "MQTT_USER") password: (Env < get var: "MQTT_PASS") ]. I use: "GPIO:Analog/0" as: LM35 config: [ as: input output: voltage ]. I use: "GPIO:Digital/0" as: HeaterRelay config: [ as: output ]. I use: "GPIO:Digital/1" as CoolerRelay config: [ as: output ]. MQTT < subscribe to: "temperature/set/cool" do: { put to: coolTemp value: (get argument: value). }. MQTT < subscribe to: "temperature/set/heat" do: { put to: heatTemp value: (get argument: value). }. NumOP < addConversion from: 0.01V to: 1.degC context: tempConvert. I on: tick do: { put to: temp value: (NumOP < convert: (LM35 < get) to: degC context: tempConvert). MQTT < publish to: "temperature/value" value: (NumOP < { scratch to: x value: (I < get value: temp). scratch to: x value: (NumOP < raw value: (get scratch: x)). scratch to: x value: (NumOP < stringify value: (get scratch: x)). answer with: (get scratch: x). }). if true: (NumOP < compare value: (get value: temp) greater: (get value: coolTemp)) do: { CoolerRelay < set to: high. } else: { CoolerRelay < set to: low. }. if true: (NumOP < compare value: (get value: temp) less: (get value: heatTemp)) do: { HeaterRelay < set to: high. } else: { HeaterRelay < set to: low. }. }
Simplified
This is a simplified version of last language. As you can read, it uses it
as an accumulator for the next instruction.
Still need to figure out what the parenthesis and brackets differ.
agent Main traits [Runnable Stateful]. -- Runnable: this agent can be run from an outside initiator (e.g. your terminal) -- Stateful: this agent stores some states (defines the actions [(set name) (to value)] and [(get name)]) use "IO:Output" as Output. use "Number:Operations" as Number-OP. use "Text:Operations" as Text-OP. -- The syntax for the agent selector are "Protocol:Link/To/Agent" -- Each protocol has their own unique actions. -- This defines an action which can be asked by other agents. -- For this one, it also acts as the entry point for the initiator. on [(run args)] do { set i to 1. -- Repeatedly does the instructions until a reply is given. loop { set out to "". get i. ask Number-OP to {mod it with 3. reply it.}. if it is 0 do { get out. ask Text-OP to {add it with "Fizz". reply it.}. set out to it. }. get i. ask Number-OP to {mod it with 5. reply it.}. if it is 0 do { get out. ask Text-OP to {add it with "Buzz". reply it.}. set out to it. }. get out. if it is "" do { ask Number-OP to {textify it. reply it.}. ask Output to {write it. reply it.}. }. get i. ask Number-OP to {add it with 1. reply it.}. set i to it. get i. ask Number-OP to {compare it with 100. reply it.}. -- Number-OP's compare action replies the flags [equal greater less]. if it is equal do { reply 0. }. }. reply it. }.
Smalltalk-like version 2
Made in 17 July 2024.
This one follows the previous Smalltalk-like syntax, but written in the way I envisioned it to be.
agent: Example traits: [runnable] use: sys/terminal as: Terminal use: lang/text as: TextOP on: main do: { define var: name. ask about: "What is your name? " > (name). TextOP < compare value: (name) equals: "Gilbert" > if true: () do: { print text: "Hello, myself!". } else: { TextOP < format pattern: "Hello, {}." with: [(name)] > print text: (). }. } on: print args: [text] do: { Terminal < write line: (text). } on: ask args: [about] do: { Terminal < { write line: (about). read until: "\n" > answer with: (). } > answer with: (). }
Note the runnable
written in lowercase: this is an added lore to this language (more of a retcon really) where initially this language is read in a machine that's case insensitive (like COBOL!)
Here's an example of how a simulator might run the above script.
$ aasim -x example.agent What is your name? Hale Hello, Hale. $ aasim -x example.agent -vv [INFO] Starting agent Example [DEBUG] Sys/Terminal: [INFO] Starting agent Sys/Terminal as required by Example [DEBUG] Lang/Text: [INFO] Starting agent Lang/Text as required by Example [DEBUG] Sys/Terminal: [INFO] Started agent Sys/Terminal as required by Example [DEBUG] Lang/Text: [INFO] Started agent Lang/Text as required by Example [DEBUG] Started agent Example [DEBUG] Calling Example to do `main` What is your name? Gilbert189 Hello, myself! [DEBUG] `main` answered with null [INFO] Stopping agent Example [DEBUG] Sys/Terminal: [INFO] Stopping agent Sys/Terminal [DEBUG] Stopped agent Example [DEBUG] Lang/Text: [INFO] Stopping agent Lang/Text [DEBUG] Sys/Terminal: [INFO] Stopped agent Sys/Terminal [DEBUG] Lang/Text: [INFO] Stopped agent Lang/Text $
Here's an example of an agent that uses Example
for their purpose.
agent: RemoteExample traits: [runnable] use: Example as: Example use: lang/text as: TextOP on: main do: { Example < { ask about: "Input anything. " > TextOP < format "Got input {}" with [()] > print text: (). } }
And here's how it runs in the simulator:
$ aasim remote-example.agent -vv [INFO] Starting agent RemoteExample [DEBUG] Example: [INFO] Starting agent Example as required by RemoteExample [DEBUG] Sys/Terminal: [INFO] Starting agent Sys/Terminal as required by Example [DEBUG] Lang/Text: [INFO] Starting agent Lang/Text as required by Example [DEBUG] Sys/Terminal: [INFO] Started agent Sys/Terminal as required by Example [DEBUG] Lang/Text: [INFO] Started agent Lang/Text as required by Example [DEBUG] Example: [INFO] Started agent Example [DEBUG] Started agent RemoteExample [DEBUG] Calling RemoteExample to do `main` Input anything. 2763 Got input 2763 [DEBUG] `main` answered with null [INFO] Stopping agent RemoteExample [DEBUG] Example: [INFO] Stopping agent Example [DEBUG] Sys/Terminal: [INFO] Stopping agent Sys/Terminal [DEBUG] Example: [INFO] Stopped agent Example [DEBUG] Lang/Text: [INFO] Stopping agent Lang/Text [DEBUG] Sys/Terminal: [INFO] Stopped agent Sys/Terminal [DEBUG] Stopped agent RemoteExample [DEBUG] Lang/Text: [INFO] Stopped agent Lang/Text $
Here's another agent that demonstrates concurrency in this language:
agent: ForkedRandom use: lang/number as: NumberOP on: get-one do: { NumberOP < random from: 0.0 to: 1.0 > answer with: (). } on: get-three do: { -- Parallel commands can be done with vertical lines... NumberOP < random from: 0.0 to: 1.0 | NumberOP < random from: 0.0 to: 1.0 | NumberOP < random from: 0.0 to: 1.0 > answer with: [(0) (1) (2)]. } on: get-five do: { -- ...or with double brackets. {{ NumberOP < random from: 0.0 to: 1.0. NumberOP < random from: 0.0 to: 1.0. NumberOP < random from: 0.0 to: 1.0. NumberOP < random from: 0.0 to: 1.0. NumberOP < random from: 0.0 to: 1.0. }} > answer with: [(0) (1) (2) (3) (4)]. }
As this agent doesn't have the trait runnable
, we would have to use another way to interact with this agent.
$ aasim -x random.agent [ERROR] Agent ForkedRandom has no trait `Runnable` $ aasim random.agent # -s implies -v [INFO] Starting agent ForkedRandom [1]+ Stopped aasim -s random.agent $ bg [1]+ aasim -s random.agent & $ aasim ForkedRandom You are now commanding ForkedRandom. < get-one > 0.378571834 < get-three > [0.930591305 0.678678690 0.285028494] < get-five > [0.498587492 0.184080535 0.469049644 0.704954824 0.901419385] < get-seven [ERROR] ForkedRandom doesn't implement `get-seven`. < ^C You stopped commanding ForkedRandom. $ aasim Blah [ERROR] Agent Blah not found. $