aver-lang 0.15.0

VM and transpiler for Aver, a statically-typed language designed for AI-assisted development
Documentation
;; Trim ASCII whitespace (space, tab, LF, CR) from both ends of an
;; OBJ_STRING. If nothing is trimmed (whole string is non-whitespace
;; or empty), returns the original pointer unchanged. Otherwise
;; allocates a fresh OBJ_STRING and memory.copy's the inner slice.

(func $rt_str_trim (param $str i32) (result i32)
  (local $byte_len i32)
  (local $start i32)
  (local $end i32)
  (local $ch i32)
  (local $new_len i32)
  (local $ptr i32)

  ;; byte_len = header.byte_len
  local.get $str
  i64.load
  i64.const 0xFFFFFFFF
  i64.and
  i32.wrap_i64
  local.set $byte_len

  ;; Walk forward over leading whitespace.
  i32.const 0
  local.set $start
  block
    loop
      local.get $start
      local.get $byte_len
      i32.ge_u
      br_if 1

      local.get $str
      local.get $start
      i32.add
      i32.load8_u offset=8
      local.set $ch

      ;; if not whitespace → break
      local.get $ch
      i32.const 0x20   ;; ' '
      i32.eq
      local.get $ch
      i32.const 0x09   ;; '\t'
      i32.eq
      i32.or
      local.get $ch
      i32.const 0x0A   ;; '\n'
      i32.eq
      i32.or
      local.get $ch
      i32.const 0x0D   ;; '\r'
      i32.eq
      i32.or
      i32.eqz
      br_if 1

      local.get $start
      i32.const 1
      i32.add
      local.set $start
      br 0
    end
  end

  ;; Walk backward over trailing whitespace.
  local.get $byte_len
  local.set $end
  block
    loop
      local.get $end
      local.get $start
      i32.le_u
      br_if 1

      local.get $str
      local.get $end
      i32.const 1
      i32.sub
      i32.add
      i32.load8_u offset=8
      local.set $ch

      local.get $ch
      i32.const 0x20
      i32.eq
      local.get $ch
      i32.const 0x09
      i32.eq
      i32.or
      local.get $ch
      i32.const 0x0A
      i32.eq
      i32.or
      local.get $ch
      i32.const 0x0D
      i32.eq
      i32.or
      i32.eqz
      br_if 1

      local.get $end
      i32.const 1
      i32.sub
      local.set $end
      br 0
    end
  end

  ;; new_len = end - start
  local.get $end
  local.get $start
  i32.sub
  local.set $new_len

  ;; If nothing was trimmed, return the original pointer.
  local.get $new_len
  local.get $byte_len
  i32.eq
  if (result i32)
    local.get $str
  else
    ;; alloc + memory.copy slice
    i32.const 8
    local.get $new_len
    i32.const 7
    i32.add
    i32.const -8
    i32.and
    i32.add
    call $rt_alloc
    local.set $ptr

    local.get $ptr
    i64.const 0
    local.get $new_len
    i64.extend_i32_u
    i64.or
    i64.store

    local.get $ptr
    i32.const 8
    i32.add
    local.get $str
    i32.const 8
    i32.add
    local.get $start
    i32.add
    local.get $new_len
    memory.copy

    local.get $ptr
  end
)
(export "rt_str_trim" (func $rt_str_trim))