Tya v0.25 Specification

This document is the specification for Tya v0.25 after v0.24 scripting toolkit and lightweight numerics.

Theme

Tya v0.25 adds bit-level integer operations, a byte-sequence value type, and binary file I/O. Together they unblock workloads that need to read, manipulate, and write raw bytes — for example, NES emulators, simple image codecs, byte-stream protocols, and binary parsing.

Goals

Included in v0.25

v0.25 includes all v0.24 behavior and adds:

Not Included in v0.25

v0.25 does not include:

Bitwise Operators

The new operators apply to integer operands. Float operands raise an error.

Operator Form Meaning
a & b binary bitwise AND
a \| b binary bitwise OR
a ^ b binary bitwise XOR
a << n binary left shift (n ≥ 0)
a >> n binary arithmetic right shift (n ≥ 0)
~a unary bitwise NOT

Semantics

Precedence

Higher precedence to lower:

~  (unary)
* / % << >>
+ -
& 
^
|
< <= > >= == !=
and
or

This matches C’s relative ordering and resolves expressions like a & 0xFF == 0xFF as (a & 0xFF) == 0xFF. (Note that v0.25 introduces no hexadecimal integer literals — see Out of scope.)

Examples

a = 0b11110000      # not part of v0.25; use 240 or to_int("0xF0")
b = 0b00001111      # not part of v0.25; use 15

# 6502 emulator-style bit work
status = 0
status = status | 1                # set carry flag
if (status & 1) != 0
  println "carry set"

byte = 0xFF                        # not part of v0.25 (use 255)
high = (byte >> 4) & 0xF
low  = byte & 0xF

(Hexadecimal and binary literals are not added in v0.25; use decimal or to_int(string, base)-style helpers in stdlib if needed in user code.)

bytes Value Type

bytes is a new top-level value type alongside string, int, float, bool, nil, array, dict, etc.

Properties

Literal

b1 = b""
b2 = b"hello"
b3 = b"\x01\x02\xff"
b4 = b"a\nb\tc"            # \n, \t, \r, \\, \", \xHH supported

The b"..." literal accepts the same backslash escapes as a basic string, plus \xHH two-digit hexadecimal byte escapes. The literal contents are parsed byte-by-byte; non-ASCII bytes from source UTF-8 are stored verbatim.

Conversions

bytes_of("hello")            # bytes from a string (UTF-8 bytes)
bytes_text(b3)               # string from bytes (UTF-8); raises on invalid
bytes_array(b3)              # array of ints
bytes([72, 101, 108, 108])   # bytes from an array of 0..255 ints

Slicing

b = b"hello world"
bytes_slice(b, 0, 5)         # b"hello"
bytes_slice(b, 6, len(b))    # b"world"

bytes_slice(b, start, end) returns the sub-sequence [start, end) in half-open form. Out-of-range indices raise.

Concatenation

b"foo" + b"bar"              # b"foobar"
bytes_concat(b"a", b"b")     # equivalent function form

+ between string and bytes is an error in v0.25; convert explicitly.

Iteration

for byte in bytes_array(b)
  println byte

The runtime does not yet support for x in bytes_value directly; iterate via bytes_array(b) or via index in v0.25.

Binary File I/O

file.read_bytes(path) reads a file and returns a bytes value.

file.write_bytes(path, b) writes a bytes value to a file.

import file
import digest

raw = file.read_bytes("/usr/local/bin/something")
println len(raw)
println digest.sha256(raw)
file.write_bytes("/tmp/copy", raw)

The existing file.read(path) (string) and file.write(path, text) are unchanged. They remain UTF-8 text-oriented.

Updated stdlib API

Affected modules accept and return bytes where it makes sense, while preserving string compatibility.

digest

digest.md5, digest.sha1, digest.sha256, digest.sha384, digest.sha512 accept either string or bytes input. Output remains a lowercase hex string.

secure_random

secure_random.bytes(n) now returns a bytes value (was a NUL-bearing string in v0.24). secure_random.hex(n) and secure_random.base64(n) are unchanged.

hex

hex.encode(value) accepts bytes (preferred) or string (treated as UTF-8 bytes). hex.decode(text) returns bytes.

base64

base64.encode(value) accepts bytes (preferred) or string. base64.decode(text) returns bytes.

Backward compatibility

Diagnostics

v0.25 implementations should report source-oriented errors for:

Diagnostics should mention the operator, function name, expected operand type, and actual value kind when available.

Implementation Notes (non-normative)

These notes are guidance, not the spec; conforming implementations may differ as long as the user-visible behavior matches.