# echo.ludic - the state, its verbs and its facts. The slices crossing to C are made once and # reused (L7), and what C recorded is drained into the queue after each call returns. export const ECHO_CAP: int = 64 export property EchoFact { index: int = 0 # which element went over value: float = 0.0 } export state EchoState { ec_xs: []float = floats(ECHO_CAP) ec_n: int = 0 ec_kinds: []int = words(ECHO_CAP) ec_values: []float = floats(ECHO_CAP) ec_facts: Queue = ec_facts__new() } function ec_ready() -> void { } # what went over, oldest first export function echo_facts(echo_st: EchoState) -> Queue { return echo_st.ec_facts } # put a value in the next slot; false when the slice is full export function echo_put(echo_st: mut EchoState, x: float) -> bool { ec_ready() if echo_st.ec_n >= ECHO_CAP { return false } echo_st.ec_xs[echo_st.ec_n] = x echo_st.ec_n += 1 return true } export function echo_clear(echo_st: mut EchoState) -> void { echo_st.ec_n = 0 } # the sum of what was put, worked out in C export function echo_sum(echo_st: mut EchoState) -> float { ec_ready() return ne_sum(echo_st.ec_xs, echo_st.ec_n) } # C walks the values and records each one over `over`; the records come back as facts export function echo_scan(echo_st: mut EchoState, over: float) -> int { ec_ready() let hits = ne_scan(echo_st.ec_xs, echo_st.ec_n, over) ec_drain(echo_st) return hits } function ec_drain(echo_st: mut EchoState) -> void { let n = ne_drain(echo_st.ec_kinds, echo_st.ec_values, ECHO_CAP) for i in 0 .. n { let f = new EchoFact f.index = echo_st.ec_kinds[i] f.value = echo_st.ec_values[i] q_push(echo_facts(echo_st), f) } } # how many records C had to drop because nobody drained them export function echo_lost() -> int { return ne_lost_count() } # a 64-bit value there and back export function echo_twice(x: long) -> long { return ne_twice(x) } function ec_facts__new() -> Queue { return queue_new("nativeecho.facts") }