Skip to content

Instantly share code, notes, and snippets.

@bryanburgers
Created November 21, 2023 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanburgers/a2837026fff8d32de5131f488336f0c1 to your computer and use it in GitHub Desktop.
Save bryanburgers/a2837026fff8d32de5131f488336f0c1 to your computer and use it in GitHub Desktop.
(module
;; Create a function that returns a single value
(func $main (result i32)
i32.const 42
)
;; Export that function so the test harness can find it
(export "main" (func $main))
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
;; Create a function that returns a single value
(func $main (result i32)
i32.const 42
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32)
i32.const 4
i32.load8_u
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32)
i32.const 4
call $load_from_memory
)
(func $load_from_memory (param $address i32) (result i32)
local.get $address ;; Push the $address parameter onto the stack
i32.load8_u ;; and use that to load from memory
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32)
i32.const 0
call $parse_digit
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; push on a value that represents ascii "0"
i32.const 0x30
;; and subtract them! [i32, i32] -> [i32]
i32.sub
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32)
i32.const 0
call $parse_digit ;; expecting 5
i32.const 3
call $parse_digit ;; expecting 0, the second digit of "10"
i32.const 15
call $parse_digit ;; expecting 7, the fourth digit of "1007..."
i32.const 4
call $parse_digit ;; what do we expect?
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; push on a value that represents ascii "0"
i32.const 0x30
;; and subtract them! [i32, i32] -> [i32]
i32.sub
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32)
i32.const 0
call $parse_digit ;; expecting 5
i32.const 3
call $parse_digit ;; expecting 0, the second digit of "10"
i32.const 15
call $parse_digit ;; expecting 7, the fourth digit of "1007..."
i32.const 4
call $parse_digit ;; what do we expect?
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32)
i32.const 0
call $parse_digit ;; expecting 5
i32.const 3
call $parse_digit ;; expecting 0, the second digit of "10"
i32.const 15
call $parse_digit ;; expecting 7, the fourth digit of "1007..."
i32.const 4
call $parse_digit ;; what do we expect?
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
(local $result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
;; if what's on the stack...
(if
;; ... is true, then ...
(then
;; set the result to what we parsed
local.get $parsed
local.set $result
)
;; ... otherwise ...
(else
;; set the result to a constant
i32.const -1
local.set $result
)
)
;; and return the result
local.get $result
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32 i32 i32 i32 i32)
i32.const 0
call $parse_digit ;; expecting 5
i32.const 3
call $parse_digit ;; expecting 0, the second digit of "10"
i32.const 15
call $parse_digit ;; expecting 7, the fourth digit of "1007..."
i32.const 4
call $parse_digit ;; what do we expect?
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result (; the value ;) i32 (; correctly parsed ;) i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
(local $success i32)
(local $result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
local.tee $success ;; store the value *and* leave it on the stack
;; if what's on the stack...
(if
;; ... is true, then ...
(then
;; set the result to what we parsed
local.get $parsed
local.set $result
)
;; ... otherwise ...
(else
;; set the result to a constant
i32.const -1
local.set $result
)
)
;; and return the results
local.get $result
local.get $success
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32 i32 i32 i32 i32)
i32.const 0
call $parse_number ;; expecting (5, 1)
i32.const 2
call $parse_number ;; expecting (10, 2)
i32.const 12
call $parse_number ;; expecting (1007000000, 10)
i32.const 4
call $parse_number ;; expecting (0, 0)
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result (; the value ;) i32 (; correctly parsed ;) i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
(local $success i32)
(local $result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
local.tee $success ;; store the value *and* leave it on the stack
;; if what's on the stack...
(if
;; ... is true, then ...
(then
;; set the result to what we parsed
local.get $parsed
local.set $result
)
;; ... otherwise ...
(else
;; set the result to a constant
i32.const -1
local.set $result
)
)
;; and return the results
local.get $result
local.get $success
)
(func $parse_number (param $address i32) (result (; number ;) i32 (; bytes parsed ;) i32)
(local $bytes_parsed i32)
(local $current_address i32)
(local $parse_digit_success i32)
(local $parse_digit_value i32)
(local $number i32)
;; initialize $number to 0
i32.const 0
local.set $number
;; initialize $bytes_parsed to 0
i32.const 0
local.set $bytes_parsed
;; initialize $current_address to the input parameter $address
local.get $address
local.set $current_address
(block $outer
(loop $inner
local.get $current_address
call $parse_digit
local.set $parse_digit_success
local.set $parse_digit_value
local.get $parse_digit_success
(if
(then
;; increment the number of bytes parsed
local.get $bytes_parsed
i32.const 1
i32.add
local.set $bytes_parsed
;; $number = $number * 10 + $parse_digit_value
local.get $number
i32.const 10
i32.mul
local.get $parse_digit_value
i32.add
local.set $number
)
(else
;; break; exit the loop
br $outer
)
)
;; increment the $current_address
local.get $current_address
i32.const 1
i32.add
local.set $current_address
;; and parse the next digit
br $inner
)
)
local.get $number
local.get $bytes_parsed
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32 i32 i32 i32)
i32.const 0
call $parse_space
i32.const 4
call $parse_space
i32.const 22
call $parse_space
i32.const 23
call $parse_space
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result (; the value ;) i32 (; correctly parsed ;) i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
(local $success i32)
(local $result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
local.tee $success ;; store the value *and* leave it on the stack
;; if what's on the stack...
(if
;; ... is true, then ...
(then
;; set the result to what we parsed
local.get $parsed
local.set $result
)
;; ... otherwise ...
(else
;; set the result to a constant
i32.const -1
local.set $result
)
)
;; and return the results
local.get $result
local.get $success
)
(func $parse_number (param $address i32) (result (; number ;) i32 (; bytes parsed ;) i32)
(local $bytes_parsed i32)
(local $current_address i32)
(local $parse_digit_success i32)
(local $parse_digit_value i32)
(local $number i32)
;; initialize $number to 0
i32.const 0
local.set $number
;; initialize $bytes_parsed to 0
i32.const 0
local.set $bytes_parsed
;; initialize $current_address to $address
local.get $address
local.set $current_address
(block $outer
(loop $inner
local.get $current_address
call $parse_digit
local.set $parse_digit_success
local.set $parse_digit_value
local.get $parse_digit_success
(if
(then
;; increment the number of bytes parsed
local.get $bytes_parsed
i32.const 1
i32.add
local.set $bytes_parsed
;; increment the current address
local.get $current_address
i32.const 1
i32.add
local.set $current_address
;; $number = $number * 10 + $parse_digit_value
local.get $number
i32.const 10
i32.mul
local.get $parse_digit_value
i32.add
local.set $number
;; continue; parse the next digit
br $inner
)
(else
;; break; exist the loop
br $outer
)
)
)
)
local.get $number
local.get $bytes_parsed
)
(func $parse_space (param $address i32) (result i32)
local.get $address
i32.load8_u
i32.const 0x20
i32.eq
)
)
(module
(export "main" (func $main))
;; Create memory with at least 1 page of 64k of memory
(memory $mem 1)
;; Initialize the first several bytes of the memory with some text
(data (i32.const 0) "5 10 42 193 1007000000 ")
(; byte offset 01234567890123456789012 ;)
(; 1 2 ;)
(func $main (result i32)
(local $address i32)
(local $sum i32)
(local $parse_number_value i32)
(local $parse_number_result i32)
i32.const 0
local.set $address
i32.const 0
local.set $sum
(block $block
(loop $loop
local.get $address
call $parse_number
local.set $parse_number_result
local.set $parse_number_value
local.get $parse_number_result
(if
(then
;; increment our next address by the number of bytes
;; we parsed
local.get $address
local.get $parse_number_result
i32.add
local.set $address
;; add to our sum
local.get $sum
local.get $parse_number_value
i32.add
local.set $sum
)
(else
;; No number parsed; stop
br $block
)
)
local.get $address
call $parse_space
(if
(then
local.get $address
i32.const 1
i32.add
local.set $address
)
(else
br $block
)
)
br $loop
)
)
local.get $sum
)
;; Load an ascii byte from memory and return its numeric value
(func $parse_digit (param $address i32) (result (; the value ;) i32 (; correctly parsed ;) i32)
(local $parsed i32)
(local $ge_zero i32)
(local $lt_ten i32)
(local $success i32)
(local $result i32)
;; get the byte at the provided address
local.get $address
i32.load8_u
;; subtract ascii "0" and store it
i32.const 0x30
i32.sub
local.set $parsed
;; is $parsed >= 0?
local.get $parsed
i32.const 0
i32.ge_s
local.set $ge_zero
;; is $parsed < 10?
local.get $parsed
i32.const 10
i32.lt_s
local.set $lt_ten
;; is $parsed >= 0 && $parsed < 10
local.get $ge_zero
local.get $lt_ten
i32.and
local.tee $success ;; store the value *and* leave it on the stack
;; if what's on the stack...
(if
;; ... is true, then ...
(then
;; set the result to what we parsed
local.get $parsed
local.set $result
)
;; ... otherwise ...
(else
;; set the result to a constant
i32.const -1
local.set $result
)
)
;; and return the results
local.get $result
local.get $success
)
(func $parse_number (param $address i32) (result (; number ;) i32 (; bytes parsed ;) i32)
(local $bytes_parsed i32)
(local $current_address i32)
(local $parse_digit_success i32)
(local $parse_digit_value i32)
(local $number i32)
;; initialize $number to 0
i32.const 0
local.set $number
;; initialize $bytes_parsed to 0
i32.const 0
local.set $bytes_parsed
;; initialize $current_address to $address
local.get $address
local.set $current_address
(block $outer
(loop $inner
local.get $current_address
call $parse_digit
local.set $parse_digit_success
local.set $parse_digit_value
local.get $parse_digit_success
(if
(then
;; increment the number of bytes parsed
local.get $bytes_parsed
i32.const 1
i32.add
local.set $bytes_parsed
;; increment the current address
local.get $current_address
i32.const 1
i32.add
local.set $current_address
;; $number = $number * 10 + $parse_digit_value
local.get $number
i32.const 10
i32.mul
local.get $parse_digit_value
i32.add
local.set $number
;; continue; parse the next digit
br $inner
)
(else
;; break; exist the loop
br $outer
)
)
)
)
local.get $number
local.get $bytes_parsed
)
(func $parse_space (param $address i32) (result i32)
local.get $address
i32.load8_u
i32.const 0x20
i32.eq
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment