Types and variables - AtomCrafty/MajiroTools GitHub Wiki

Majiro types and variables (of types and mem)


[WIP]


Modifier and Invert flags are only used by ld and ldelem instructions.

Floats only support the neg invert flag.

Modifier flags are applied before Invert flags.

Modifier and Invert flags are ignored by all store operations.

Int is the default type used for all pointers (handles). Including when passing functions as arguments (which is just the hash).

Type flags should represent the type of the target variable or element being stored or loaded. This means ld and st may use any of the six type flags, while ldelem and stelem should only use the three primitive type flags that represent an array's element type.

Although it's encouraged to use the correct type flag for st and stelem instructions, it's not required since they are ignored internally. Type flags only identify the target type of the variable, not of any value being passed in, making the type flags redundant with the .i, .r, .s, .iarr, .rarr, and .sarr opcode variants already specifying this information.

Type kinds

Native/Numeric types: int, float
Primitive types: int, float, string
Array types: intarray, floatarray, stringarray
Reference types: string, intarray, floatarray, stringarray

About arrays

Arrays are 0-indexed.

Array type flags must be used when interacting with array variables as a whole (ld, st), while primitive type flags must be used when interacting with array elements (ldelem, stelem).

Internally, all arrays are three-dimensional. The extra unused dimensions are always implied to be one. Using a lower dim flag than the actual array dimensions will just use index 0 for those missing dimensions. Aka. It doesn't matter.

Array indices are wrapped around their own dimension. This means -1 notation is legal for accessing the tail end of an array. See an example of this behavior below:

var _myarray#; // [10,20,30]
_myarray# = $dim_create#(10, 20, 30); // ($96b07aee) create array (inits to all 0s)
_myarray#[9,20,-1] = 42; // assigns to _myarray#[9,0,29] aka [9%10, 20%20, (-1+30)%30]

Variable opcodes

All variable instructions have the same operands. Flags is a bitmask of different settings, hash is the CRC-32 hash of the variable name, and offs is the location of local variables on the stack (≤-2 for arguments, -1 for argcount, ≥0 for local variables).

All store opcodes contain definitions for each supported type, and then even more definitions for each compound store operation (which is based on one of the normal operator opcodes).

Opcode Description
ld <flags> <hash> <offs> load variable
ldelem <flags> <hash> <offs> load element
st. <flags> <hash> <offs> store variable
st._. <flags> <hash> <offs> compound store variable
stp. <flags> <hash> <offs> store variable (pop)
stp._. <flags> <hash> <offs> compound store variable (pop)
stelem. <flags> <hash> <offs> store element
stelem._. <flags> <hash> <offs> compound store element
stelemp. <flags> <hash> <offs> store element (pop)
stelemp._. <flags> <hash> <offs> compound store element (pop)

Although it depends on the context, all store instructions will be referred to as a whole, as st/stelem, or as st/stelem/st.*/stelem.*. Most of the time functionality overlaps, and it's easier to just list the base name.

Flags mask

000ddttt sssiimmm

unused dim type scope invert modify
000 dd ttt sss ii mmm

Variable flags

Rows multiple lines legal aliases. All names have been finalized, with exception to Invert flag aliases _.x. (Note: dim0 is valid, but not recommended)

0 1 2 3 4 5 6 7
Modify (none)
 
preinc (++x)
inc.x (++x)
predec (--x)
dec.x (--x)
postinc (x++)
x.inc (x++)
postdec (x--)
x.dec (x--)
- - -
Invert (none)
 
neg (-x)
neg.x (-x)
notl (!x)
notl.x (!x)
not (~x)
not.x (~x)
Scope persistent
persist
savefile
save
thread
 
local
loc
- - - -
Type int
i
float
r
string
s
intarray
iarr
floatarray
rarr
stringarray
sarr
- -
Dim (none)
dim0
dim1
 
dim2
 
dim3
 

Flags usage

Many flags are situational, and only used by certain instructions. Other instructions will ignore any unneeded flags. Most notably, all st* instructions have no use for the Type flag, as there's already a unique st* opcode for each type.

Legend:
✓ - used
○ - used but ignored
✗ - not used

Usage by instruction

ld ldelem st stelem st._. stelem._.
Modify
Invert
Scope
Type ✓¹ ○¹ ○¹
Dim

[1] : only primitive (int, float, string) Type flags are supported by element instructions.

Usage by type

i r s iarr rarr sarr
Modify
Invert ✓² ✓²
Scope
Dim

[2] : only the neg Invert flag is supported by float and floatarray.

Array dimensions example

ldc.i       2               ; size in dimension 1 (least significant)
ldc.i       100             ; size in dimension 2
; ldc.i     1               ; size in dimension 3 (implied, most significant)
syscall     $dim_create# (2) ; ($96b07aee) create a zero-initialized integer array with (2) dimensions
st.iarr     local intarray $00000000 0       ; save it as local 0
ldc.i       42              ; the value to store
; ldc.i     0               ; index 3 (implied)
ldc.i       2               ; index 2
ldc.i       1               ; index 1
stelem.i    dim2 local int $00000000 0  ; array[0,2,1] = 42

Loading base types

ldc.i       9001            ; push integer literal type 'i'
ldc.r       0.8             ; (0x3f4ccccd) push floating point (real) literal type 'r'
ldstr       "foobar baz"    ; push string literal type 's'

Essential syscalls

These syscalls are used to create and work with Majiro variable reftypes. Arrays must be created with a syscall, while strings only need syscalls to measure length or perform other common C-like <string.h> functions.

Hash Signature Notes
$7fcf3c82 $dim_copy#(_arr#) returns a copy
$e2413ef9 $dim_copy%#(_arr%#) returns a copy
$5bbae511 $dim_copy$#(_arr$#) returns a copy
$96b07aee $dim_create#([_dim3=1], [_dim2=1], _dim1) all zeroes (0)
$a6ac6ccc $dim_create%#([_dim3=1], [_dim2=1], _dim1) all zeroes (0.0)
$2cd009af $dim_create!#([_dim3=1], [_dim2=1], _dim1) legacy
replaced by %#
$1f57b724 $dim_create$#([_dim3=1], [_dim2=1], _dim1) all empty strings ("")
$3a49e325 $dim_release#() returns a [1,1,1]
$aab68e6d $dim_release%#() returns a [1,1,1]
$20caeb0e $dim_release!#() legacy
replaced by %#
$134d5585 $dim_release$#() returns a [1,1,1]
$b0c8f550 $strlen(_str$)

Variable name syscalls

Hash Signature Notes
$6e83677a $get_variable(_name$)
$f9a3b675 $get_variable_nowarn(_name$)
$160176be $get_variable$(_name$)
$86294bfe $get_variable_nowarn$(_name$)
$cd290aef $set_variable(_name$, _val*)
⚠️ **GitHub.com Fallback** ⚠️