Instructions - absoluteAquarian/CSASM GitHub Wiki

NOTE: This page is currently not complete. In the meantime, view the syntax.txt file in the repository.

This page contains the documentation for all instructions in CSASM in alphabetical order.
Instructions with an operand will have the operand's type listed beside it.
Examples: bit <u8>, ldelem <u32|^u32>

When referring to objects on the stack, A, B and C will be used to denote the objects. They are pushed to the stack in this order:

push C
push B
push A

abs

Pops A (a number) and pushes its absolute value.

add

Pops A and B, then pushes B + A.
If either B or A are of type str, then string concatenation will be executed instead: B.ToString() + A.ToString()
If both B and A are of type ~set, then the Union of the two sets is pushed to the stack
Otherwise, the types of A and B must match.

and

Pops A and B (integers) then pushes B & A (bitwise-AND).
The types of A and B must match.

asl

Pops A (an integer), then pushes A << 1.

asr

Pops A (an integer), then pushes A >> 1.

bin

Pops A (an integer), then pushes a str of its binary representation without leading zeroes.

binz

Pops A (an integer), then pushes a str of its binary representation with leading zeroes.

bit <u8>

Pops A (an integer), then pushes the bit at the zero-based position <u8>.
If the value of the argument exceeds the bit length of A, a 0 is pushed instead.

Example usage:

push 40   ; 0011 0010
push 5    ;   ^
bit
          ; Value on stack: 32

bits

Pops A (an f32 or f64), then pushes an i32 (if A was an f32) or an i64 (if A was an f64) set to the bit representation of A.

Example usage:

push 1.9   ; f64
bits
           ; Value on stack:  4611235658464650854
           ; Value in binary: 0011111111111110011001100110011001100110011001100110011001100110
           ; Value type:      i64

br <label>

Jumps execution to the label <label> unconditionally.

brfalse <label>

Pops A. If any of the following is true, then execution will jump to <label>.

  • A is a str, ~arr or obj and is null
  • A is a char and is \0
  • A is a bool and is false
  • A is a number and is equal to 0

brtrue <label>

Pops A. If any of the following is true, then execution will jump to <label>.

  • A is a str, ~arr or obj and is not null
  • A is a char and is not \0
  • A is a bool and is true
  • A is a number and is not equal to 0
  • A is a ^<u32>, ~set or ~range instance

bytes

Pops A, then pushes an approximation of how many bytes of memory it takes up.

call <func>

Jumps execution to the function <func>.

clf.c

Sets the Carry flag to false.

clf.n

Sets the Conversion flag to false.

clf.o

Sets the Comparison flag to false.

cls

Clears the console (functions similarly to the command-line command cls on Windows).

comp

Pops A and B, then sets the Comparison flag iff (if and only if) they are equal.
If A and B are ~arr instances, then this instruction will set the Comparison flag iff their element types are the same and they contain the same elements.

  • Example: array instances [ 1, 3, 5 ] and [ 1, 3, 5 ] are equal, but array instances [ 1, 3, 5 ] and [ 3, 1, 5 ] are not equal

comp.gt

Pops A and B (numbers), then sets the Comparison flag iff B is greater than A.

comp.gte

Pops A and B (numbers), then sets the Comparison flag iff B is greater than or equal to A.

comp.lt

Pops A and B (numbers), then sets the Comparison flag iff B is less than A.

comp.lte

Pops A and B (numbers), then sets the Comparison flag iff B is less than or equal to A.

conrc

Resets the colours of the text printed to the console to their default values.

conv <type>

Pops A and attempts to convert it to <type>.
Defined conversions are listed below:

  • A's type equals <type>: A is pushed to the stack
  • A is an i32 and <type> is char:
    • A is casted to char and the result is pushed to the stack
  • <type> is str
    • If A is an ~arr:char, then a new string comprised of those chars is pushed to the stack
    • If A is an ~arr, then the CSASM string representation of the array is pushed to the stack
      • E.g. if A is an array of integers 1, 2, 5, 7, then "[ 1, 2, 5, 7 ]" is pushed to the stack
    • Otherwise, the value calls ToString() and that result is pushed to the stack
  • <type> is ~arr:char and A is a str
    • A is deconstructed into an ~arr:char and that array is pushed to the stack
  • <type> is ~arr and A is either a ~set or ~range value
    • If A is a ~set, then a new ~arr:i32 comprised of A's values is pushed to the stack
    • If A is a ~range and A does not use any ^<u32> (indexer) endpoints, then an array spanning from each integer between A's endpoints, inclusive is pushed to the stack
      • E.g. if A is [4..7], then [ 4, 5, 6, 7 ] is pushed to the stack
    • If A is a ~range and A uses at least one ^<u32> (indexer) endpoint, then B is popped from the stack and used as the reference for the indexer(s).
      • E.g. if A is [1..^1] and B is "Hello!", then [ 1, 2, 3, 4, 5 ] is pushed to the stack (since ^1 represents "length - 1")
  • <type> starts with ~arr: and none of the previous conditions were satisfied
    • An exception is thrown, indicating that other array type instances cannot be created using the conv instruction
  • A is a number
    • If A is a u32 and <type> is ^<u32>, then a new indexer initialized with A is pushed to the stack
    • Otherwise, A is attempted to be casted to the target <type>. If the conversion fails, an exception is thrown
  • A is a str and <type> is one of the number types
    • A is attempted to be parsed as that type. If the parse was successful, the result is pushed to the stack and the Conversion flag is set. Otherwise, the default value for that type (0) is pushed to the stack instead
  • A is a char and <type> is i32
    • A is cast to an i32 and the result is pushed to the stack

If a conversion other than the ones explicitly mentioned above is attempted, an exception will be thrown.

conv.a <type>

Functions identically to the conv instruction, but the A is $a and the result is also put into $a.
Do note that if $a is a ~range value that has at least one ^<u32> (indexer) endpoint, an ~arr or str value needs to be on the stack.

dec <var>

Decrements a number in <var> (a .local, .global or register) by one and stores the result in <var>.

disj

Pops A and B (~set instances), then sets the Comparison flag iff they are Disjoint

div

Pops A and B.
If A and B are numbers, B / A is pushed to the stack.
If B is a str and A is a str or char, then B.Split(A) is called and the result (an ~arr:str) is pushed to the stack.
If A and B are ~set instances, then their Intersection is pushed to the stack. Otherwise, an exception is thrown.

dup

Pops A, then pushes A. If A is an ~arr or str, then a clone of A is pushed to the stack. Otherwise, A is pushed to the stack again.

exit

Calls Environment.Exit(0), essentially halting the program.

extern <func>

Calls one of a few predefined external functions:

<func> Value Stack Usage Expected Types Result
Math.Sqrt A a number (A) Pushes the result of System.Math.Sqrt(A) as an f64
Math.Sin A a number (A) Pushes the result of System.Math.Sin(A) as an f64
Math.Cos A a number (A) Pushes the result of System.Math.Cos(A) as an f64
Math.Tan A a number (A) Pushes the result of System.Math.Tan(A) as an f64
Math.Atan2 A, B numbers (A and B) Pushes the result of System.Math.Atan2(B, A) as an f64
Random.Next none none Pushes the result of System.Random.Next()1 as an i32
Random.Next(i32) A an i32 (A) Pushes the result of System.Random.Next(A)1 as an i32
Random.Next(i32,i32) A, B i32s (A and B) Pushes the result of System.Random.Next(B, A)1 as an i32

1: Random.X extern calls use a System.Random object that is initialized at the start of the program

Attempting to use extern with any other <func> argument throws an exception.

in <str>

Prints <str>, then waits for a newline-terminated string of text to be entered by the user. The inputted string is pushed to the stack.

inc <var>

Increments a number in <var> (a .local, .global or register) by one and stores the result in <var>.

index

Pops A and B.
If B is an ~arr and the element type of B matches the type of A, then the index of the first instance of A in B is pushed to the stack or -1 if A could not be found in B.
If B is a str and B is a str or char, then the result of B.IndexOf(A) is pushed to the stack.
Otherwise, an exception is thrown.

ink <str>

Prints <str>, then waits for the user to press a key.
The key pressed is printed to the console and the char value for that key is pushed to the stack.

inki <str>

Prints <str>, then waits for the user to press a key.
The key pressed is not printed to the console and the char value for that key is pushed to the stack.

interp <str>

Pops A (an ~arr:obj), then pushes the result of string.Format(<str>, A) to the stack.

io.r<u8> <type>

Reads a <type> value from the I/O instance indicated by <u8>.
If said I/O instance is in Stream mode, then any <type> other than char or str will throw an exception.
The I/O instance must be in Read-Only format.

io.w<u8> <val>

Writes <val> to the I/O instance indicated by <u8>.
If the I/O instance is in Stream mode, then the string representation of <val> is written.
If the I/O instance is in Binary mode, then <val> is written differently depending on its type.

If <val> is a number, then it is written however System.IO.BinaryWriter would handle writing it.
If <val> is an array, then the array's element type is written as a string (how System.IO.BinaryWriter.Write(string) would handle it), then the array's length is written as a 7-bit Encoded Integer. Then the array's elements are written in order as if they were passed into io.w<u32>.

is <type>

Pops A, then sets the Comparison flag iff (if and only if) A has the same type as <type>.

is.a <type>

Sets the Comparison flag iff $a (the accumulator register) has the same type as <type>.

isarr <type>

Pops A, then sets the Comparison flag iff A is an array and its element type is <type>.
If you only need to check if A is an array, pass obj as the <type>.

lda <var>

Stores the value of <var> into $a, the accumulator register.

ldelem <u32|^<u32>>

Pops A (an ~arr instance), then pushes the value at the zero-based index u32 or ^<u32> (indexer).

len

Pops A (an ~arr or str instance), then pushes the length of A.

mul

Pops A and B.
If A and B are both numbers, B * A is pushed to the stack.
Otherwise, if B is a str and A is a positive integer, A copies of B are created, then joined together. The resulting str value is pushed to the stack.

Example:

push "Hello!"
push 5
mul
print          ; "Hello!Hello!Hello!Hello!Hello!"

neg

Pops A (a number), then pushes -A.

⚠️ **GitHub.com Fallback** ⚠️