~mna/snow unlisted

c459dde744d67070919fbaa2ed7c86dd8fa56f8d — Martin Angers 1 year, 4 months ago 4dbe761
codegen: example implementation of optional unwrapping
1 files changed, 50 insertions(+), 0 deletions(-)

A codegen/optional.ssa
A codegen/optional.ssa => codegen/optional.ssa +50 -0
@@ 0,0 1,50 @@
data $fmtSome = { b "%d %d\n", b 0 }
data $fmtNone = { b "none\n", b 0 }

# a random type just as example
type :type = { w, w }

# the optional wraps it in a tagged struct, can
# be optimized when :type is a pointer so that
# 0 is used as null indicator (no need to wrap).
# Other types could be optimized too (e.g. bool
# could use a value other than 0 and 1).
type :optional = { b, :type }

export function w $main() {
@start
  # first call with Optional{ .none }
  %opt =l alloc4 9
  storeb 0, %opt
  call $printOptional(:optional %opt)

  # then with Optional{ .some(...) }
  %some =l alloc4 9
  storeb 1, %some
  %f1 =l add %some, 1
  storew 36, %f1
  %f2 =l add %f1, 4
  storew 987, %f2
  call $printOptional(:optional %some)

  ret 0
}

function $printOptional(:optional %p) {
@start
  # unwrap (e.g. if optional { /* access unwrapped value */ } else { /* none */ }
  %tag =w loadub %p
  jnz %tag, @some, @none

@some
  %f1 =l add %p, 1
  %v1 =w loadw %f1
  %f2 =l add %f1, 4
  %v2 =w loadw %f2
  call $printf(l $fmtSome, w %v1, w %v2)
  ret

@none
  call $printf(l $fmtNone)
  ret
}