ASTLang

From Esolang
Jump to navigation Jump to search

ASTLang is a coding language based off of the style of an abstract syntax tree (hence AST). It uses a fully Python intepreter which is about 31kb in size (at the current release). More information is at the github page, including information about new updates, bugs, and fixed bugs.

This wiki is very long due to the number of functions and complexity of the coding language, although it is basically a copy of Python, but as an esolang.

ASTLang
200px|center
Paradigm(s) Declarative
Designed by User:NTMDev
Appeared in 2025
Memory system Stack based
Computational class Turing complete
Reference implementation Unimplemented
File extension(s) .astlang

It is a turing complete esolang that can actually be learnt and used, with very simple syntax and similar to Python. Note that this coding language was completely a "for fun" project and is not expected to be actually professionally used (I mean, who uses an esolang efficiently?)

Please note that this wiki is currently unfinished. If you are a beginner, the information already provided should be enough to give you a start.

Things you should do:

  • If you see a problem or something is not accurate, please update it.
  • Fix typos or add/remove words for clarity

Thanks!

This documentation is not intended to be read from start to end. Instead, use the table of contents (provided below) to navigate to a section of interest.

Getting Started

Obviously, from the description, the ASTLang interpreter and runtime environment needs at least Python 3 or preferably Python 3.12+ from best performance. All other packages like re or pickle will come pre-installed along with Python, so there is no need to go to other websites to find modules to run this program. As said, the main file is about 31kb large with 4100 lines of code (at the current moment, this will change).

Head to the official page of Python to download it if you do not already have Python installed.

Bugs

If you experience an unexpected bug/event that occurred while using the IDE, executing code or anything else, please add a bug under User reported issues.

The current bugs as of now. "(not critical)" means it does not hinder the performance, functionality, or effectiveness of the product.

Issues from Github:

  • While true loops crashes output box
  • Cannot focus onto autocomplete box when using arrow keys
  • Async Error: "Async handler deleted by wrong thread" when closing output box (not critical)
  • When inserting "auto correct" an extra space is inserted (not critical)
  • Signature box displays full class name when default value for argument was assigned (not critical)

Issues found when I was writing this wiki:

  • Argument Step in function Slice should be default to Integer(1), not ObjNONE().
  • DictGet returns error when using SliceVal argument.

User reported issues:

  • None

How to Troubleshoot Error Code

When an unexpected error occurs during evaluated code, regardless of user intention, the interpreter will almost always generate some error text starting with lines:

[FATAL ERROR AT Evaluate]: <error message>

After this line, you will see more lines containing where on the class hierarchy the error was found. If you see an error that you did not expect (for example, function Raise will on purposely afflict a specified error), it is probably an interpreter bug. They are very easy to diagnose since the interpreter was built off of Python.

However, sometimes you may provide an unexpected or disallowed input to an argument. Instead of producing a corrupted or not satisfactory output, it will immediately raise an error and stops all code.

Code Structure

PLEASE NOTE: In various sections of this wiki, the argument/input structure of the current function will be shown for easier understand and visualization. However, inputs do not have to go in the order shown AS LONG AS the name of the argument is mentioned (a non-positional argument)

When starting any program, you must wrap all code inside the Module function. If the program is consists of only one function, it is not necessary to wrap it.

Module(
...
)

All code must go inside the braces (yes I know they are parenthesis but I cannot spell the word "parenthesis" quickly and correctly consistently so bare with me). After that, all functions inside the Module function should be separated by commas, except for the last one which can be ignored if the programmer wishes.

Module(
  foo(),
  foobar(),
  foobarbar()
)

Inside a function, if a function does need to take arguments, they should also be seperated by commas, except for the last one which is optional. The programmer may also choose optionally to name all arguments, but they should do this consistently or it will cause confusion, and sometimes unexpected errors. This means that if a programmer names one argument, they should name all of them.

foo(
  Blah=BlahBlah,
  BlahBlah=Blah123
  Blah4321=BlahBlahBlah
)

Sometimes, an argument may need a list (an argument with brackets surrounding it) input. To define it, separate all elements inside it, except for the last one optionally (I am saying this a lot!).

Blah = [1, 2, 3, 4]

ObjNONE()

ObjNONE() is a special function that returns None. None means null; it has no value. This is usually an input to an argument when it does not necessarily need an input, or the programmer deliberately chose to not give an input.

Raw String

Sometimes, you do not actually need an identifier for an argument. This usually occurs when the type of argument doesn't matter, but the text does. Example:

MyFunction(
  Mode='On', <--- This doesn't need String()
  Text=String('Hi!') <--- This does need String()
)

This is optional. You can provide a raw text/raw string with a String identifier, but this is not needed.

Empty Functions

Some functions do not require or do not need arguments to be provided to it to be able to run. However, you should still put two matching parenthesis just like any other function:

MyFunction() <--- This is still needed!

How To Save

If you wish to save a file, press Crtl+S to save the file. This will save it as a binary file, with the file extension .astlang. Unfortunately, this file can be unexpectedly large and take up storage. A general idea is to save it as a plain text file, then copy+paste it into the IDE. This can save up to 10x the storage. To open a file, press Crtl+O. A file explorer window will automatically popup, and you must select a file with .astlang. This will open all file contents inside the file.

Note: Opening large files will take some time. Also, the syntax highlighting will not appear until you make some update to your code (an example is adding a space or new line)

Commenting in Code

Commenting in your code can make it more readable and allow other programmers catch on to what you are doing. There are two options to do this.

# You can use a hashtag to comment. The interpreter will skip this line. 

Comment('You can also use the Comment function. This is only used for raw input')

Print

To print a variable or anything, use FuncCall. This is a wrapper function used to call simple functions like Min, Max, Len and Print.

FuncCall(
  Function=Print(
    Contents=Foo,
    End=Foo
  )
)

Contents is what is to be printed. End is what should be added at the end. This is default to a newline. Note that you should use an identifier, not just a plain type. For example, if you just put a string in Contents without String, it may not produce the desired output.

An example of the Print function in action is the simple Hello World! program.


FuncCall(
  Function=Print(
    Contents=String('Hello World!')
  )
)

Create A Variable

When creating a variable, there are two functions involved.

Variable Assignment

To assign any value to a variable with any valid name as a string (special characters are allowed. Note that characters should be kept as letters or numbers for readability). Use the Assignment function to do so.

Assignment(
  Name='foo',
  Val=String('foo')
)

Calling A Variable

To retrieve the contents of a variable, use Variable.

Variable(
  Name='foo',
)

Note that this will not display the value of the variable in any way. This only returns the value of the variable as an input to an argument.

Initializing a Empty Variable

When you do not want to directly provide a value to a variable but still want it to be existing in the code context, use InitVariable to create a variable assigned None. This variable cannot be used to provide input to an argument.

InitVariable(
  Name='foo'
)


Simple Data Types

Simple data types are integers, floats, booleans, and strings. They form up everything a basic programmer would need.

Integers

To return an integer as an input to an argument, use Integer.

Integer(
  Int=12345
)

NEW: Integers or floats greater than 2^32 are disallowed.

Strings

To return a string as an input to an argument, use String. Note that a string must be wrapped inside quotation marks to simulate a string. Other data types do not need this.

String(
  String='Hello, World!'
)

Floats

To return a float as an input to an argument, use Float. A common misconception is that a float CAN be an integer, but the interpreter will automatically add a .0 at the end of the value.

Float(
  Flt=1234.5
)

Boolean

To return a boolean as an input to an argument, use Boolean. Note that you can actually input a boolean as a string. What this means is you have two ways of representing a boolean inside the Boolean function.

#1:

Boolean(
  Bool='True'
)

This, in my opinion, looks better.

#2:

Boolean(
  Bool=True
)

Sometimes this can be better when comparing if the Boolean actually has a value or is true.

PrimitiveWrapper (DEPRECATED)

This is a bonus function. If you do not know directly the identifier a variable would need when inputting it into an argument, you may use PrimitiveWrapper to identify the primitive value without providing a specific identifier to that value. An example:

PrimitiveWrapper(V=Variable(Name='UnknownIdentifier'))

Lists

A list is a type of container that can hold basically hold infinite items in an array. You can retrieve elements in the list by calling the item's index, which starts at 0.

Creating a List

To create a list, use ListAssignment. This is usually used inside Variable when assigning the variable a list. Inside ListAssignment, you can give it any amount of arguments as long as they follow the rules of spacing (See Code Structure).

ListAssignment(
  Integer(1),
  String(A),
  Integer(2),
  String(B)
)

You must provide an identifier for each element in a list if it is a primitive/simple type.

Get Element From List

To get an element from a list through index, use ListCall. You must provide an index using Integer, as the interpreter must receive an integer to find the index of an element.

WARNING: Most coding languages start their index positions at 0, meaning that a element at "positon" 2 is actually at index position 1. Essentially, it is the "actual position" - 1.

Module(
 Variable(
   Name='Foo',
   Val=ListAssignment(
     Integer(1),
     Integer(2)
   )
 ),
 ListCall(
   Name='Foo',
   Index=Integer(1)
 )
)


This will return 2, as an integer

Name is the name of the variable that contains the list. This must be defined and the list must not contain any definition errors in it. Index is the index of the element the programmer wishes to examine.

Edit a List

This is a pretty complex function with a few arguments taking multiple inputs. When you wish to perform some utility functions, use ListEdit. ListEdit takes 7 arguments, which are:

Name
EditType
AppendVal (default None)
DelVal (default None)
DelIndex (default None)
PopIndex (default None)
ReversedSort (default Boolean('False'), False)

Name is the name of the variable you are currently wishing to perform actions upon. EditType is the name of the edit/action you want to perform. Edit Type takes 6 inputs:

append
del
clear
sort
pop
reverse

These names should be typed EXACTLY (including case) for the function to work.

append

Append AppendVal to the specified list (Name). AppendVal must be set so that the interpreter can add it to a list.

del

Delete DelVal from a list (name). DelVal must be set so that the interpreter can delete it to a list.

clear

Clears the list

sort

Sorts the list, from smallest to greatest if the list is entirely numerical, A-Z alphabetically if the entire list is text. If the list is not all the same type of simple data types, sort cannot be used.

reverse

Reverses the given list. This basically flips it. If the list is:

[1,2,3]

It will become:

[3,2,1]

Special List Functions

1. To insert an element anywhere into a list, use InsertElement.

InsertElement(
  Name
  Var
  IndexPos
)

Name is the name of the list. Var is what you want to insert at index IndexPos.

2. To see if a list contains an element, use ListContains.

ListContains(
  List
  Element
)

If element Element is inside List, this will return true. If not, returns false.

List Arithmetic

To use Len, Max, and Min you must wrap them inside FuncCall since they are primitive functions. They all take Var as an argument (the variable you are applying these functions to).

Len, Sum

Len returns the size of the condition. The most applicable version of this is how long a list, tuple or dictionary would be.

Len(Var=Variable(Name='MyList'))

Sum returns the sum of all the numeric numbers in a list. The list must contain only numbers, nothing else.

Max and Min

Max returns the maximum value in a list or tuple, and Min returns vice versa. However, these two functions are not limited to only numerical values.

(Note that Max and Min both follow these rules)

Caption text
Comparison (Max) Output
[1, 'a'] [FATAL ERROR AT {...}]: ...
['A', 'a'] (DEPRECATED) 'a' (or 'A')
[1, 2] 2 (or 1)

To summarize, larger numbers are larger than smaller ones (really?!), numbers cannot be compared to strings, and lowercase strings are "larger" than uppercase ones.

Container Operations

Helpful utility functions to organize or sort lists.

Slicing

To slice a list (get multiple elements from a range of indexs), use the function Slice.

Slice(
  Var
  Start (Default None)
  End (Default None)
  Step (Default Integer(1))
)

Var, Start and End are the target container (most commonly a list), start of slicing, and end of slicing, respectively. The slicing stops at EXACTLY the index of End, not before it. Step is how much you want to increase the index by (each value is spaced out by 1 LESS than the actual given value). Example:

Slice(
  Var=ListAssignment(Integer(0), Integer(1), Integer(2), Integer(3)),
  Start=Integer(0),
  End=Integer(3),
  Step=Integer(2)
) <---This outputs [0, 2]

Filtering values

WARNING! A COMMON CONFUSION IS NOT KNOWNING THE DIFFERENCE BETWEEN Filter AND FilterFunction. ALTHOUGH THEY HAVE SIMILAR NAMES, THEY ARE DIFFERENT!

Filtering (based on Condition)

To filter all the elements in a container depending on a condition, use Filter. Filter takes Iterable, Conditional, and ResultName.

Filter(
  Iterable
  Conditional
  ResultName
)

The Iterable should be some type of list or container (usually a list or tuple), and Conditional should be some condition that can evaluate to true or false. If the condition is met for a value, it is added to the result. If it is not, it is discarded. ResultName is the name of the filtered list. If you set this as the name of the given container (via Iterable), it will modify the original list instead of creating a new one with the name of ResultName. You cannot assign a new value to a tuple because it is immutable.

Filtering (based on Function)

To filter all the elements in a container based on if a given function returns truthy, use FilterFunction.

FilterFunction(
  Function
  Iterable
)

Function should be the name (as raw text or the literal function using UserFunction) of a valid function that returns a boolean of some sort. Iterable should be a container (most commonly a list or tuple). Unlike Filter', this function does not create a new variable or update the original, but returns the result like most other functions.

Tuples

Tuples are lists, but immutable. Immutable means you cannot change it any way after it is set. Examining an element (calling it) does not count as changing it.

Creating a Tuple

When you want to create a tuple (like creating a list), use TupleAssign. TupleAssign also takes a series of elements, just like ListAssignment.

TupleAssign(
 Integer(1),
 Integer(2),
 Integer(3)
)

Inspecting a Tuple

When inspecting/editing a tuple, you only have two actions you are allowed to perform since it is immutable.

TupleInspection(
  TupleVar
  Mode
  IndexVar (Default None)
  UnpackingTargets (Default None)
)

TupleVar is the name of the variable that contains the tuple. Mode is the type of action you are performing. If the selected mode is 'index', IndexVar is the index of the element you are trying to call. If the selected mode is 'unpack', UnpackingTargets should be a list of elements you want to distribute the tuple to (for more advanced programmers, this is essentially enumerating the tuple).

Conditionals (If Statements and more)

Conditionals help direct program flow. There are several conditional statements you can use.

If Statement Structure

This defines the main structure of the if-elif-else statements. When creating an if statement, a expression is always necessary.

IfCondition(
  Expression
  Body
  Elif (Default None)
  ElifBody (Default None)
  ElseBody (Default None)
)

In more actual code form (Python):

if (Expression):
  Body
elif Elif:
  ElifBody 
else:
  ElseBody

Note that ElifBody must be defined to use Elif.

Expression is the starting comparison. If this evaluates to true, Body runs. Body should be a list of functions, like this:

Body = [FuncCall(...), ListAssignment(...), Variable(...)]

(This is true for ElifBody and ElseBody)

Elif is evaluated if Expression evaluates to false. If Elif is true, ElifBody runs. If all are false, the evaluator defaults to ElseBody.

Conditions

To create a condition, you cannot simply write a string that contains the condition you want (for example, '1 + 1 == 2' is not allowed). You need the Condition function.

Condition(
  Right
  Operator
  Left
)

Right is the righthand side of the expression. In the case of 1+1=2, 1+1 would be the righthand side. Operator is the operation between the two sides of the condition. Currently, operator accepts:

Operator Definition
x == y x is equal to y
x != y x is not equal to y
x >= y x is greater than OR equal to y (numeric)
x <= y x is less than OR equal to y (numeric)
x > y x is greater than y (numeric)
x < y x is less than y (numeric)

LogicalOperation

When comparing numeric values or using '==' and '!=' is not enough, using LogicalOperation allows for boolean operations.

LogicalOperation(
  RightOp
  Op
  LeftOp
)

RightOp and LeftOp and the right and left hand sides of the condition, respectively. Op is the boolean operation you are performing.

Operation Requirement for True
x and y both true
x or y at least one true
x contains y element y is in x (containers, string)
not y inverse

A more detailed ex

and

If in form:

x and y

x and y must both be true for this to return true. If not, returns false.

or

If in form:

x or y

At least one variable must be true for this to return true. If not, returns false.

contains

If in form:

x contains y

We assume that x would be some arbitrary type of container or string. If y is in x (as an element, substring, subelement, etc.) this would return true. If not, returns false.

not

The inverse of LeftOp. RightOp is not needed here (Set it to ObjNONE()).

Any + AllCondition

When you want to find out if a set of objects follow a condition, use AllCondition. However, if you only need to know if at least one object follows the condition, use AnyCondition. They both take Condition as an argument, which should be some type of the Condition function:

Condition(Right=ListAssignment(Boolean('True'), Boolean('False'), ...))

AnyCondition returns true if ANY of the values in the given object are true, and AllCondition return if ALL values are true.

Switch / Match

Instead of using many IfStatement functions, using Switch can make code more readable and efficient. Example (psuedocode):

What day is it?

switch (day):
  case 1:
    print "monday!"
  case 2:
    print "tuesday!"
  {so on...}
  case 7:
    print "sunday!"
  default:
    print "hey, that's not in the days of the week!"

In ASTLang, Switch takes these arguments:

Switch(
  SwitchVar
  Scenarios
  Default (Default None)
)

SwitchVar is the variable you are comparing against the Scenarios. The SwitchVar in our "days of the week" example would be day, while the Scenarios would be 1, 2, 3, 4, etc. to 7. Default would be if all Scenarios evaluated false. If this is not set, the interpreter will just skip the Switch statement.

Scenario

This is the base function for Switch. It creates the individual cases for the switch statement.

Scenario(
  Var
  Body
  Fallthrough (Default False)
)

Var is the variable you are comparing against the SwitchVar. In our example, that would be our day numbers. Body is what you want to execute if the scenario is true. Fallthrough controls if the code evaluates even after finding a matching scenario.

Simple statistics and Math Operations

This section will cover the functions Mean, Median, Mode, Operation, and Calculate.

Simple Statistics

To calculate the mean of a list or tuple (must be numeric), use Mean. For mode, use Mode, and for the median use Median. All 3 of these functions take List as an argument. This is the list or tuple you want to take the mean, mode, or median of.

Simple Math operations

To calculate an expression using order of operations (simple operations like '*+-/') and other features, use Calculate. Calculate takes Expression as an argument. This argument takes raw text. To assign a primitive operation to a variable or as an input to an argument, use Operation.

Operation(
  Left
  Op
  Right
)

Left, Right, and Op are the left hand side, right hand side, and operator of the equation. You can input '*', '+', '-', or '/' (strings) as an operator. This argument takes raw text as an input.

Abs returns the absolute value of its argument, Val.

Power takes two arguments, Power and Base. It returns Base raised to the Power.

Loops

Loops are good for repeatedly performing the same task efficiently.

Loop structure Function

To create the structure of the loop, use Loop. Note that the argument Iterable should not be confused with the function of the same name, Iteerable.

Loop(
  LoopType
  Body
  Iterable (Default None)
  Expression (Default None)
  ControlVar (Default None)
)

LoopType is the type of loop you want to create (it takes 'for' or 'while'). This takes a raw text argument. Body takes a list of functions you want to run each successful iteration ran by Iterable. Iterable should be some arbitrary object that can be iterated through (this is only needed when the LoopType is 'for'). This is a somewhat complex requirement for beginners (no programming experience). If you do not know if the object you are using is iterable, use THE FUNCTION Iterable.

Iterable takes the argument Iter. If the object given to the argument (as input) is indeed iterable (can be used in a loop), the function will return something like this:

<list_iterator object at 0x...> 

This is what you get if you inputted a list. Of course, if it was a string, it would be different.

Expression is used when the LoopType is 'while'. Expression should be a condition that evaluates to a boolean. When the Expression value is true, the loop will execute until the condition is false.

ControlVar is the variable of which the iterable is being stored.

for x in i:
  x

In this case, i' is the iterable and x is the control variable. Every element of i is being stored inside x once every iteration. This is only needed if the LoopType is 'for'.

Break and Continue

To forcefully exit a loop regardless of the current circumstances, use Break. You can optionally provide an ExitMessage, which outputs when the loop is exited. To skip an iteration, use Continue.

Enumeration

The function EnumerateObjects returns both the current iteration count and also the element itself. Quote from AI: "This object can then be used in loops to access both the index and the value of each item in the iterable simultaneously."

When actually using EnumerateObjects, you need to put it in the Iterable argument as an input (since the EnumerateObjects function is an iterable).

EnumerateObjects(
  Iterable (not to be confused with Loop's Iterable argument)
  Start (Default 0)
)

Iterable is the list you want to enumerate through. Start is what integer you want to start the iteration counter. This is usually default to 0 (since the first index for a list is also 0).

WARNING! If using iterable that outputs more than one item, you must give ControlVar a list argument, like this: ['element', 'index'] in the case of EnumerateObjects

The Range Function

When you want to create a numerical list without specifically defining it, you can use Range. This is usually used when a list containing a geometric sequence (like 1, 2, 3, 4, ...) is too long to be written by hand. Also, it is used as an input to the Iterable argument for Loop.

Range(
  BoundMin
  BoundMax
  Step (Default 1)
)

BoundMin is the starting number of the list. BoundMax is the ending number of the list, and Step is the common difference between any two consecutive elements (or the incrementor). A common usage in loops:

Loop(
  LoopType='for',
  Iterable=Range(BoundMin=Integer(0), BoundMax=Integer(10)),
  ControlVar='x',
  Body=[FuncCall(Function=Print(Contents=Variable('x')))] <--- You can actually call any control variable using Variable!
) <--- This outputs 1, 2, 3 ... 10

Advanced Math Operations

This includes trigonometry functions and other functions like Gcd, Round, or Factorial. All of the functions listed take Value as their only argument unless otherwise noted.

Round

Round argument Flt to DecPoints decimal points. Example:

Round(
 Flt=Float(1.1),
 DecPoints=Integer(0)
)

Floor, Ceiling

Floor rounds the value provided down regardless of rounding rules, while Ceil rounds it up.

Floor(Value=Float(1.1)) <--- This outputs 1
Ceil(Value=Float(1.1)) <--- This outputs 2

Square root, Logarithm, Factorial

For square roots, use Sqrt. For a logarithm, use Log. Log takes an additional argument called Base, which is the base the logarithm will be in. Factorial calculates the factorial of Value (really?!).

Trig Functions

To perform a trigonometric function, use Exp, Sin, Cos, or Tan. They calculate their corresponding trig function, according to their name.

WARNING: The source code for these functions use Python's math package, "math". This is always calculated in RADIANS, not degrees.

Gcd, Lcm

Gcd and Lcm stands for greatest common divisor (or more commonly known as greatest common factor) and least common multiple, respectively. They evaluate this between arguments A and B. Example:

Gcd(
 A=Integer(20),
 B=Integer(30)
) <--- This outputs 10

Mod, MathConstants

Mod will calculate the remainder when its Value is divided by Divisor. Example:

Mod(
 Value=Integer(5),
 Divisor=Integer(2)
) <--- This will return 1

MathConstants will return some advanced irrational values in math, like e or pi. It accepts:

pi
e
tau
inf

String Operations 1

There are many string operations you can use. In this section, it covers mostly on string checkers than modifiers. Basically, these functions do not really change the string itself.

Uppercase, Lowercase

To automatically convert the case to uppercase or lowercase, use StringUpper and StringLower, respectively. Both take Str as an argument. Make sure this is a valid string and also wrapped inside String.

More Utilities

For some more miscellaneous (but useful) utilities, use StringOperation.

StringOperation(
  Var
  OpType
  Arg (Default None)
)

Var is the current string in use. OpType is the operation the user wants to perform (in raw text):

reverse

Reverses the string.

replace

Replaces the FIRST element of Arg with the second one. Example:

StringOperation(
  Var=String('Hello World'),
  StringOp='replace',
  Arg=("world", "bob")
) <-- This outputs 'Hello bob'

split

Splits the string into parts spaced out by Arg. If the string was 'abcd' and Arg was (an empty string), you would get 'a', 'b', 'c', 'd'.

sort

Sort the string from A-Z, and for numerical values smallest to largest. If there is a mix, numerical values are placed first then the alphabetical values after.

String Checkers

To see if a string contains a substring, use StringContains.

StringContains(
  Text
  Substring
)

This will return true if Substring can be found inside Text. If not, returns false.

To see if string's suffix or prefix is a string, use IsStringAffix. IsStringAffix has 3 arguments, Var, AffixCheckMode, and AffixStr. Var is the parent string. AffixCheckMode takes startswith (prefix) and endswith (suffix), in raw text format. AffixStr is the string you want to check at the specified affix.

IsStringAffix(
  Var
  AffixCheckMode
  AffixStr
)

To see if a string is in a specific case or format, use IsStringType. IsStringType takes inputs from 2 arguments, Var and CheckMode. Var is the parent string being checked. CheckMode is the check you want to peform on the parent string (input parameters as raw text). You there are 3 modes:

upper <--- Is the string all in uppercase?
lower <--- Is the string all in lowercase?
alpha <--- Is the string all alphabetical (contains no numbers, symbols etc.)?

String Operations 2

This section covers functions that directly modify strings and their contents.

Joining elements

When you have something like a list or series of strings that you want to join into one, whole string, using Join. Join takes input from two arguments, Delimiter and Items. Join will join all of the items in Items spaced out with Delimiter. Example:

Join(
  Items=ListAssignment(String('Hello'), String('World')),
  Delimiter=String(' ')
) <--- This outputs "Hello World"

Formatting strings

To add variables inside a string without using string arithmetic, use FormattedString. Each variable is inserted at the two opening and closing curly brackets in the string. You can set any amount of curly brackets, but the variables provided must match each corresponding curly brackets.

FormattedString(
  FormatString
  Args
)

FormatString is the target string, and Args are the values to be unpacked into the seperate curly brackets. This should be in a list, like this:

Args=[Integer(1), String('A'), ...]

Example:

FormattedString(
  FormatString=String('Hello, Mr.{}, {}!'),
  Args=[String('Bob'), String('Good day')]
) <--- This outputs 'Hello Mr.Bob, Good day!'

Splitting a String

To split a string based on a delimiter (spacer), use StringSplit.

StringSplit(
  Str
  Delimiter
)

Str is the original/target string, and Delimiter is the spacer that cuts the string. This is the inverse of Join.

Replace substrings

To replace an entire substring with a new string, use StringReplace.

StringReplace(
  Text
  OldSubstring
  NewSubstring
)

Text is the parent string/original string. OldSubstring should be a substring that can be found inside Text (this can be any length). NewSubstring is the string you want to replace OldSubstring. Returns the new replaced string as an input to an argument.

Functions

Functions help perform tasks rapidly and efficiently. Also, you can give a task custom arguments to act based on input.

Defining Or Creating a Function

To create a new functions, use tne function DefineFunction.

DefineFunction(
  Name
  Body
  Param
)

Name is the name of the function. This should match FuncName when calling it. Body is what the function should do when it is called. This should be a list of functions. To call and use a parameter inside the function, use Variable. Param are the function's parameters. Any number of parameters are allowed.

Returning a Value

If you want your function to return a value back to the its original caller (source), use Return. This is similar to Python or Java's return statement. If you do not know what this would do, you can search for it online. Return has only one argument, Value. Value is what you want to return to the caller.

Calling a Function

To call a pre-existing function, use UserFunction.

UserFunction(
  FuncName
  Args
  Global (Default True)
)

FuncName is the name of the function (should already exist, as said). Args are the arguments the function needs. This should be a list of values, any values. Global is if the WHOLE function should have a global scope. This is by default set to true.

Dictionaries (Hash Maps)

A dictionary is a container type where a key is paired to a value, in form of "[key:Value]", or "key: value".

Creating a new Dictionary

To create a new dictionary, use DictionaryAssign. DictionaryAssign only takes one argument, called Pairs. This argument should be given a list of tuples. Example:

Pairs = [(String('A'), Integer(1)), (String('B'), Integer(2))...]

Basically, each key-value pair should be wrapped inside parenthesis so the interpreter knows where each pair is.

Get item in Dictionary

When you want to perform some utility function or to retrieve a key or value, use DictGet. This function has many arguments and different inputs, so there will be a separate section for each argument.

DictGet(
  Var
  Key (Default None)
  GetKey (Default False)
  GetItems (Default False)
  GetValues (Default False)
  SliceVal (Default None)
  HasKey (Default None)
)

If you don't want to read all of the sections, here is a table:

Argument Name Action
Var The dictionary
Key Get the value of this key
GetKey Get all keys
GetItems Get all items, as key-value pairs
GetValues Get all values with valid keys
SliceVal (DEPRECATED) Slices a list (more versatilee, "bonus" argument). Var must be a list container type for this to work
HasKey Does the dictionary contain the given key?

Var

The dictionary you are performing the function on. This should be some implementation of DictionaryAssign.

Key

If this is given, the intepreter will return the matching value of the given key. Example:

{'A' : 1}
DictGet(Key=String('A') <--- This returns 1, as an Integer

GetKey, GetValues

If GetKey given true or false, the function will return all valid keys in the current dictionary. Contrary, GetValues will return all valid values that were given a valid key.

GetItems

If given true or false, will return the key-value pairs of the dictionary as dict_items([...]).

Why not use FuncCall(Print)?

The reason is because you can actually enumerate through this container type since it is a iterable (in terms of Python). I will not write out the ASTLang code for this, but this is what you would expect, in Python:

for keys, values in dict.items():
  print(keys, values)

In this case, dict.items() would be our function,DictGet(GetItems=Boolean('True')).

SliceVal (DEPRECATED)

The variable given to DictGet should be a list for the function to work properly (this makes DictGet more versatile). Give SliceVal a list argument, in order start, stop, step:

SliceVal = [Integer(0) (The start), Integer(5) (The stop), Integer(1) (The step)]

HasKey

If given name, will return if that key name exists in the dictionary (as true or false).

Add or Remove Pair

To add or remove a key-value pair from a given dictionary/hash map, use DictItems.

DictItems(
  Var
  ItemEditType
  Key
  Value
)

Var would be the specified map to be edited. ItemEditType is the action/edit to be performed, it takes two raw texts inputs (add and remove). Key is the key where the action is to be conducted, and Value is only used when you want to add something (in other words, when ItemEditType is set to mode add).

Objects (aka classes)

Objects group together a vast amount of functions and help make things more organized. These are usually used for a repetitively used group of functions or for a more object-oriented scope on things.

New class

To define and create a new class with full inheritance from a super class, use DefineClass.

Argument Result
Name Name of the class to be referred to when creating a instance of it
Body All functions inside of it, with a local scope.
Base Name of its super class. Inherits all functions from it.

Note that you obviously do not need to provide a superclass for a class.

Creating An Instance

To create a global instance of a defined class, use NewInstance. A class must have an instance to be ran and used.

NewInstance(
  ClassName
  Args (Default Empty List)
)

ClassName is the name of the class being initialized (in raw text). Of course, this needs to be already defined. You cannot initialize a class to create it. Args is the initialization arguments (this can be left empty if the init is not present). If a class had the init keyword in its Body, this means the class must be created with a set of predefined values, that it references itself using self. If outside of the class scope, you can use the class name to call the variable.

Get and SetAttr

GetAttr gets the attribute Attr of class Obj (it only takes these two inputs). SetAttr sets the value of Attr to Value in class Obj. To use SetAttr, the Attr argument must already be defined, and same goes for Obj. These should be provided as raw text.

Calling a Class Method

To call a class method that is in the local scale (from perspective of the class), use MethodCall. It will call the method MethodName in class Obj with any needed arguments which are set in Args.

MethodCall(
  Obj
  MethodName
  Args (Default Empty List)
)

Args can be set if a function needs mandatory inputs. If not, you can skip this input.

Superclasses

To directly call the superclass of the current class the code is in, use Super. It will run the method MethodName using arguments Args of the superclass. Note that this can only be used when you are inside a class with a superclass already defined.

To create a superclass of a class that inherits all properties and methods of the parent class, use SuperClass (not to be confused with function Super)

SuperClass(
  ChildClassName
  ParentClassName
  Methods (Default Empty List)
  Properties (Default Empty List) (DEPRECATED)
)

ChildClassName and 'ParentClassName is the class name of the child and parent classes, respectively.

A common misconception is that this function creates a new class altogether. Instead, it takes two functions and assigns one as a parent to the other.

Methods and Properties (DEPRECATED) add new methods and properties to the child class without directly editing the class (this is called inheritance).

List Utilities

List utilities help make using lists easier and more efficient.

Unique

Function Unique will filter out all repeated items from list Items.

Sort

Sorts the list. This is the same function as EditList's sort argument.

Sort(
  List
  Reverse (Default False)
  Key
)

There is one bonus parameter: Key. This is how you want to sort your list. This must be provided.