Skip to content

Expression Data Types

Basm supports several data types in expressions.

Integer Types

Integers can be written in multiple formats:

  • Decimal: 42, 255
  • Hexadecimal: $FF, #ABCD, &CAFE, 0x1234, 0X5678
  • Binary: %11001100, 0b10101010, 0B11110000
  • Octal: 0o377, 0O177, @377
  • Character: 'A' (evaluates to ASCII value 65)

All numeric formats are demonstrated in the test file:

    ; Test various numeric base representations
    ; All of these should represent the same values

    org $4000

    ; === Value 255 in different bases ===
decimal_255:
    db 255              ; Decimal
    assert memory(decimal_255) == 255

hex_dollar_255:
    db $FF              ; Hexadecimal with $
    assert memory(hex_dollar_255) == 255

hex_0x_255:
    db 0xFF             ; Hexadecimal with 0x prefix
    assert memory(hex_0x_255) == 255

hex_hash_255:
    db #FF              ; Hexadecimal with # prefix
    assert memory(hex_hash_255) == 255

hex_ampersand_255:
    db &FF              ; Hexadecimal with & prefix
    assert memory(hex_ampersand_255) == 255

binary_255:
    db %11111111        ; Binary with %
    assert memory(binary_255) == 255

binary_0b_255:
    db 0b11111111       ; Binary with 0b prefix
    assert memory(binary_0b_255) == 255

octal_255:
    db 0o377            ; Octal with 0o prefix
    assert memory(octal_255) == 255

octal_at_255:
    db @377             ; Octal with @ prefix
    assert memory(octal_at_255) == 255

    ; Verify all representations are equal
    assert 255 == $FF
    assert 255 == 0xFF
    assert 255 == #FF
    assert 255 == &FF
    assert 255 == %11111111
    assert 255 == 0b11111111
    assert 255 == 0o377
    assert 255 == @377


    ; === Value 42 in different bases ===
decimal_42:
    db 42               ; Decimal
    assert memory(decimal_42) == 42

hex_dollar_42:
    db $2A              ; Hexadecimal
    assert memory(hex_dollar_42) == 42

hex_0x_42:
    db 0x2A             ; Hexadecimal with 0x
    assert memory(hex_0x_42) == 42

binary_42:
    db %00101010        ; Binary
    assert memory(binary_42) == 42

binary_0b_42:
    db 0b101010         ; Binary (without leading zeros)
    assert memory(binary_0b_42) == 42

octal_42:
    db 0o52             ; Octal
    assert memory(octal_42) == 42

    ; Verify all representations are equal
    assert 42 == $2A
    assert 42 == 0x2A
    assert 42 == #2A
    assert 42 == &2A
    assert 42 == %101010
    assert 42 == 0b101010
    assert 42 == 0o52
    assert 42 == @52


    ; === Value 4096 (16-bit) in different bases ===
decimal_4096:
    dw 4096             ; Decimal
    assert memory(decimal_4096) == 0x00  ; LSB
    assert memory(decimal_4096+1) == 0x10  ; MSB

hex_4096:
    dw $1000            ; Hexadecimal
    assert memory(hex_4096) == 0x00
    assert memory(hex_4096+1) == 0x10

binary_4096:
    dw %0001000000000000  ; Binary
    assert memory(binary_4096) == 0x00
    assert memory(binary_4096+1) == 0x10

octal_4096:
    dw 0o10000          ; Octal
    assert memory(octal_4096) == 0x00
    assert memory(octal_4096+1) == 0x10

    ; Verify all representations are equal
    assert 4096 == $1000
    assert 4096 == 0x1000
    assert 4096 == #1000
    assert 4096 == &1000
    assert 4096 == %0001000000000000
    assert 4096 == 0b1000000000000
    assert 4096 == 0o10000
    assert 4096 == @10000


    ; === Edge cases ===

    ; Zero in all bases
    db 0, $0, 0x0, #0, &0, %0, 0b0, 0o0, @0
    assert 0 == $0
    assert 0 == %0
    assert 0 == 0o0

    ; One in all bases
    db 1, $1, 0x1, #1, &1, %1, 0b1, 0o1, @1
    assert 1 == $1
    assert 1 == %1
    assert 1 == 0o1

    ; Powers of 2
    assert 128 == $80
    assert 128 == %10000000
    assert 128 == 0o200

    assert 256 == $100
    assert 256 == %100000000
    assert 256 == 0o400

    ret

Negative integers use the unary minus: -42

Floats

Floating point values support decimal notation and scientific notation:

    ; Test floating point values and operations
    org $4000

start:
    ; Basic floating point values
    pi = 3.14159
    half = 0.5
    negative = -2.5

    ; Assertions for basic floats
    assert pi == 3.14159
    assert half == 0.5
    assert negative == -2.5

    ; Scientific notation
    micro = 1.0e-6
    thousand = 1.5e3

    assert micro == 0.000001
    assert thousand == 1500.0

    ; Float arithmetic
    sum = 1.5 + 2.5
    assert sum == 4.0

    product = 2.0 * 3.5
    assert product == 7.0

    ; Comparison operators with floats
    assert 3.5 > 2.0
    assert 2.0 >= 2.0
    assert 1.5 < 2.5
    assert 2.5 <= 2.5
    assert 2.5 == 2.5

    ; Float functions (if supported)
    abs_neg = abs(-3.5)
    assert abs_neg == 3.5

    min_val = min(1.5, 2.5)
    assert min_val == 1.5

    max_val = max(1.5, 2.5)
    assert max_val == 2.5

    ; Mixed integer and float arithmetic
    mixed = 10 + 0.5
    assert mixed == 10.5

    ret

Examples:

  • 3.14159
  • 2.5
  • -0.5
  • 1.0e-6 (scientific notation)
  • 1.5e3 equals 1500.0

Strings

String literals are enclosed in double quotes and are primarily used with the DB directive:

    ; Test string literals and functions
    org $4000

start:
    ; Basic string literals (used with db directive)
data_string1:
    db "Hello, World!"

data_string2:
    db "CPC forever"

data_string3:
    db ""  ; empty string

    ; String escape sequences
data_escapes:
    db "Line 1\nLine 2"     ; newline
    db "Tab\there"          ; tab
    db "Path\\file"         ; backslash
    db "Say \"hello\""      ; quote

    ; String length function
    len1 = string_len("Hello")
    assert len1 == 5

    len2 = string_len("CPC")
    assert len2 == 3

    len3 = string_len("")
    assert len3 == 0

    ; String concatenation
    greeting = string_concat("Hello", " ", "World")
    assert string_len(greeting) == 11

    ; More complex concatenation
    full_greeting = string_concat("Hello", ", ", "dear ", "friend", "!")
    assert string_len(full_greeting) == 19

    ret

Strings can contain escape sequences:

  • \n - newline
  • \t - tab
  • \\ - backslash
  • \" - quote

String functions:

  • string_len(str) - returns the length of a string
  • string_concat(str1, str2, ...) - concatenates multiple strings (2 or more arguments)

Booleans

Boolean values for conditional expressions:

  • True: true, 1
  • False: false, 0

Booleans are demonstrated in the test file:

    ; Test boolean values and operations
    org $4000

start:
    ; Basic boolean literals
    true_val = true
    false_val = false

    ; Boolean assertions
    assert true_val == true
    assert false_val == false
    assert true == true
    assert false == false
    assert true != false

    ; Boolean in conditional expressions (ternary)
    result1 = true ? 1 : 0
    assert result1 == 1

    result2 = false ? 1 : 0
    assert result2 == 0

    ; Comparison operations return booleans
    is_greater = (10 > 5)
    assert is_greater == true

    is_less = (10 < 5)
    assert is_less == false

    is_equal = (42 == 42)
    assert is_equal == true

    is_not_equal = (42 != 43)
    assert is_not_equal == true

    ; Boolean logic with comparisons
    assert (5 > 3) == true
    assert (5 < 3) == false
    assert (5 >= 5) == true
    assert (5 <= 5) == true
    assert (5 == 5) == true
    assert (5 != 5) == false

    ; Combined logical expressions
    and_result = (true && true)
    assert and_result == true

    and_false = (true && false)
    assert and_false == false

    or_result = (true || false)
    assert or_result == true

    or_false = (false || false)
    assert or_false == false

    ; Negation - using NOT operator
    assert !(true) == false
    assert !(false) == true
    assert NOT(true) == false
    assert NOT(false) == true

    ; Boolean in data generation
data_start:
    db true ? 255 : 0
    assert memory(data_start) == 255

    db false ? 255 : 0
    assert memory(data_start+1) == 0

    ; Complex boolean expressions
    complex1 = (10 > 5) && (20 < 30)
    assert complex1 == true

    complex2 = (10 > 5) && (20 > 30)
    assert complex2 == false

    complex3 = (10 < 5) || (20 < 30)
    assert complex3 == true

    complex4 = (10 < 5) || (20 > 30)
    assert complex4 == false

    ; Truthiness of non-boolean values
    ; Non-zero is truthy
    assert (5 ? true : false) == true
    assert (1 ? true : false) == true
    assert (-1 ? true : false) == true

    ; Zero is falsy
    assert (0 ? true : false) == false

    ; Using booleans to control assembly
    DEBUG_MODE = false
    RELEASE_MODE = true

    assert DEBUG_MODE == false
    assert RELEASE_MODE == true

    ret

Boolean operators include:

  • Logical AND: &&
  • Logical OR: ||
  • Logical NOT: !, NOT
  • Comparison: ==, !=, <, >, <=, >=

Labels

Labels can be referenced in expressions and resolve to addresses:

    ; Labels example
    org $4000

start:
    LD A, 5
    JP start     ; Label reference

    ret

The special symbol $ represents the current program counter.

Lists

Lists are heterogeneous collections enclosed in square brackets:

    ; Lists example
    org $4000

    ; Basic list creation
    list1 = [1, 2, 3, 4, 5]
    assert list1 == [1, 2, 3, 4, 5]

    ; Empty list
    list2 = []
    assert list2 == []

    ; list_len - get the length of a list
    len1 = list_len(list1)
    assert len1 == 5

    len2 = list_len(list2)
    assert len2 == 0

    ; list_get - get element at index (0-based)
    first = list_get(list1, 0)
    assert first == 1

    second = list_get(list1, 1)
    assert second == 2

    last = list_get(list1, 4)
    assert last == 5

    ; list_new - create a new list with n elements (all initialized to given value)
    list3 = list_new(3, 0)
    assert list_len(list3) == 3
    assert list_get(list3, 0) == 0
    assert list_get(list3, 1) == 0
    assert list_get(list3, 2) == 0

    ; list_new with non-zero initial value
    list3b = list_new(2, 42)
    assert list_get(list3b, 0) == 42
    assert list_get(list3b, 1) == 42

    ; list_set - set element at index
    list4 = list_set(list3, 0, 10)
    assert list_get(list4, 0) == 10
    assert list_get(list4, 1) == 0
    assert list_get(list4, 2) == 0

    list4 = list_set(list4, 1, 20)
    list4 = list_set(list4, 2, 30)
    assert list4 == [10, 20, 30]

    ; list_push - append an element to the end
    list5 = list_push(list1, 6)
    assert list_len(list5) == 6
    assert list_get(list5, 5) == 6

    ; list_sublist - extract a sublist (start_index, end_index - not included)
    ; list1 = [1, 2, 3, 4, 5], extract from index 1 to 4 (not included) = [2, 3, 4]
    sublist = list_sublist(list1, 1, 4)
    assert list_len(sublist) == 3
    assert list_get(sublist, 0) == 2
    assert list_get(sublist, 1) == 3
    assert list_get(sublist, 2) == 4

    ; list_extend - concatenate two lists
    list6 = [10, 20]
    list7 = [30, 40]
    combined = list_extend(list6, list7)
    assert list_len(combined) == 4
    assert combined == [10, 20, 30, 40]

    ; list_sort - sort list in ascending order
    unsorted = [5, 2, 8, 1, 9]
    sorted = list_sort(unsorted)
    assert sorted == [1, 2, 5, 8, 9]

    ; list_argsort - return indices that would sort the list
    indices = list_argsort(unsorted)
    assert list_len(indices) == 5
    ; indices should point to sorted order
    assert list_get(unsorted, list_get(indices, 0)) == 1
    assert list_get(unsorted, list_get(indices, 1)) == 2
    assert list_get(unsorted, list_get(indices, 4)) == 9

    ; Mixed types list
    mixed = [1, 2.5, 3]
    assert list_len(mixed) == 3
    assert list_get(mixed, 0) == 1
    assert list_get(mixed, 1) == 2.5
    assert list_get(mixed, 2) == 3

    ret

Lists support:

  • Indexing: list[0] (0-based)
  • Nesting: [[1, 2], [3, 4]]
  • Functions: list_len(), list_get(), etc.

Matrices

Matrices are 2D arrays, created via matrix_new() or from nested lists:

list1 = [[5, 5, 5],[5, 5, 5],[5, 5, 5]]

mat1 = matrix_new(3, 3, 5)
mat2 = matrix_new([[5, 5, 5],[5, 5, 5],[5, 5, 5]])
mat3 = matrix_new(list1)

print mat1
print mat2
print mat3

assert mat1 == mat2
assert mat1 == mat3
assert mat2 == mat3

Matrices support various operations through built-in functions (see functions).

Matrices support specialized access functions documented in the functions page.

Operators

Binary Operators

Listed by precedence (highest to lowest):

  1. Multiplication/Division: *, /, % (modulo)
  2. Addition/Subtraction: +, -
  3. Bitwise Shift: <<, >>
  4. Relational: <, >, <=, >=
  5. Equality: ==, !=
  6. Bitwise AND: &
  7. Bitwise XOR: ^
  8. Bitwise OR: |
  9. Logical AND: &&
  10. Logical OR: ||

Unary Operators

  • Negation: -x (arithmetic)
  • Bitwise NOT: ~x
  • Logical NOT: !x
  • Low byte: <x (equivalent to low(x))
  • High byte: >x (equivalent to high(x))

Operator Examples

    ; Operators example
    org $4000

    value = (5 + 3) * 2       ; = 16
    mask = $FF & %00001111    ; = $0F
    shifted = 1 << 4          ; = 16
    high_byte = high($1234)   ; = $12
    low_byte = low($1234)     ; = $34

    ret

Type Conversions

Implicit conversions occur in expressions:

  • Integer to Float: automatic when mixed with floats
  • Boolean to Integer: true → 1, false → 0
  • Integer to Boolean: 0 → false, non-zero → true
  • Character to Integer: automatic (ASCII value)

Function Calls

Functions are called with parentheses:

    ; Function calls example
    org $4000

    ; Functions in expressions
    ld a, high($ABCD)
    ld b, low($ABCD)
    ld c, max(10, 20, 30)

    ret

See the functions page for a complete list of built-in functions.

Special Symbols

  • $ - Current program counter (assembly address)
  • $$ - Start of current section
  • $-$$ - Offset within current section
    ; Special symbols example
    org $4000

start:
    ld a, ($ + 5)  ; Reference current address + 5
    db $ - $$      ; Offset from section start

    ret

Conditional Expressions

The ternary operator for inline conditionals:

    ; Ternary operator example
    org $4000

start:
    ; Ternary in instruction
    ld a, (1 > 0) ? 42 : 0
    assert memory(start) == $3e     ; ld a, nn opcode
    assert memory(start+1) == 42    ; Should be 42 (true branch)

    ; Max using ternary
    ld b, (10 > 20) ? 10 : 20
    assert memory(start+2) == $06   ; ld b, nn opcode
    assert memory(start+3) == 20    ; Should be 20 (false branch, 10 < 20)

    ; Simple data bytes with ternary
data_start:
    db (1 > 0) ? 42 : 0
    assert memory(data_start) == 42

    db (0 > 1) ? 42 : 0
    assert memory(data_start+1) == 0

    ; Nested ternary
    db (1 > 0) ? ((2 > 1) ? 100 : 50) : 0
    assert memory(data_start+2) == 100

    ; With arithmetic
    db (5 * 2 > 8) ? (10 + 5) : (2 + 3)
    assert memory(data_start+3) == 15

    ; Boolean conditions
    db true ? 1 : 0
    assert memory(data_start+4) == 1

    db false ? 1 : 0
    assert memory(data_start+5) == 0

    ; Edge case: zero condition (falsy)
    db 0 ? 99 : 77
    assert memory(data_start+6) == 77

    ; Edge case: non-zero condition (truthy)
    db 5 ? 99 : 77
    assert memory(data_start+7) == 99

    ret