about summary refs log tree commit diff stats
path: root/src/lmem.c
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-12-23 12:30:21 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-12-23 12:30:28 -0800
commit916857dae08c499a9016082185a83b6139f2e4b6 (patch)
tree3cd9b5e347b2d6599466df490ce84c37d27663d7 /src/lmem.c
parent984d3450891d00de9769af446401acd028bf1c1d (diff)
downloadteliva-916857dae08c499a9016082185a83b6139f2e4b6.tar.gz
cleaner test message
Was printing over passing tests for some reason.
Diffstat (limited to 'src/lmem.c')
0 files changed, 0 insertions, 0 deletions
href='#n86'>86 87 88 89
# The 'same fringe' problem: http://wiki.c2.com/?SameFringeProblem
# Example program demonstrating coroutines using Mu's delimited continuations.
#
# Expected output:
#   1
# (i.e. that the two given trees x and y have the same leaves, in the same
# order from left to right)

container tree:_elem [
  val:_elem
  left:&:tree:_elem
  right:&:tree:_elem
]

def main [
  local-scope
  # x: ((a b) c)
  # y: (a (b c))
  a:&:tree:num <- new-tree 3
  b:&:tree:num <- new-tree 4
  c:&:tree:num <- new-tree 5
  x1:&:tree:num <- new-tree a, b
  x:&:tree:num <- new-tree x1, c
  y1:&:tree:num <- new-tree b, c
  y:&:tree:num <- new-tree a, y1
  result:bool <- same-fringe x, y
  $print result 10/newline
]

def same-fringe a:&:tree:_elem, b:&:tree:_elem -> result:bool [
  local-scope
  load-inputs
  k1:continuation <- call-with-continuation-mark 100/mark, process, a
  k2:continuation <- call-with-continuation-mark 100/mark, process, b
  {
    k1, x:_elem, a-done?:bool <- call k1
    k2, y:_elem, b-done?:bool <- call k2
    break-if a-done?
    break-if b-done?
    match?:bool <- equal x, y
    return-unless match?, false
    loop
  }
  result <- and a-done?, b-done?
]

# harness around traversal
def process t:&:tree:_elem [
  local-scope
  load-inputs
  return-continuation-until-mark 100/mark  # initial
  traverse t
  zero-val:&:_elem <- new _elem:type
  return-continuation-until-mark 100/mark, *zero-val, true/done  # final
  assert false, [continuation called past done]
]

# core traversal
def traverse t:&:tree:_elem [
  local-scope
  load-inputs
  return-unless t
  l:&:tree:_elem <- get *t, left:offset
  traverse l
  r:&:tree:_elem <- get *t, right:offset
  traverse r
  return-if l
  return-if r
  # leaf
  v:_elem <- get *t, val:offset
  return-continuation-until-mark 100/mark, v, false/not-done
]

# details

def new-tree x:_elem -> result:&:tree:_elem [
  local-scope
  load-inputs
  result <- new {(tree _elem): type}
  put *result, val:offset, x
]

def new-tree l:&:tree:_elem, r:&:tree:_elem -> result:&:tree:_elem [
  local-scope
  load-inputs
  result <- new {(tree _elem): type}
  put *result, left:offset, l
  put *result, right:offset, r
]