Skip to content

Latest commit

 

History

History
68 lines (51 loc) · 2.1 KB

File metadata and controls

68 lines (51 loc) · 2.1 KB

Polymorphism

Besides parameterized modules, Cwerg supports a limited form of (ad-hoc) polymorphism for functions. There is no dynamic dispatch as everything is resolved at compile-time.

Example:

poly fun SysRender(v u8, out span!(u8)) uint:
    return FmtDecU8(v, out)

Note the poly atttribute indicates that a function is polymorphic.

This example has two effects:

  1. It defines a function that renders an u8 value in decimal into the buffer out and returns the number of characters written.
  2. It registers a family of functions named SysRender that must differ in their first argument.

Functions can be added to this family by re-using the name like so

poly fun SysRender(v u32, out span!(u8)) uint:
    return FmtDecU32(v, out)

Note, this function has a different first parameter type for the first argument while the other stay the same, though tthat is not a requirement. Cwerg's polymorphism applieds to the first argument only!

Printing in hex instead of decimal could be accomplished like so:

pub wrapped type u32_hex = u32

poly fun SysRender(v u32_hex, out span!(u8)) uint:
    return FmtHexU32(unwrap(v), out)

Assuming the functions above are defined in a module named fmt they can be called like so:

    ...
    ref let! buf_raw = [1024]u8{}
    let! buf span!(u8) = buf_raw
    set buf = IncSpan(buf, fmt\SysRender@(666_u32, buf))
    set buf = IncSpan(buf, fmt\SysRender@(66_u8, buf))
    set buf = IncSpan(buf, fmt\SysRender@(
        wrap_as(666,  fmt\ u32_hex), buf))
    ...

Defining SysRender for a data type in another module can be accomplished like so:

rec Point:
    x u32
    y u32

poly fun fmt\SysRender(v Point, out span!(u8)) uint:
    let! buf = out
    set buf = IncSpan(buf, fmt\SysRender@(v.x, buf))
    set buf = IncSpan(buf, fmt\SysRender@(", ", buf))
    set buf = IncSpan(buf, fmt\SysRender@(v.y, buf))
    return len(out) - len(buf)

Note, that the definition uses a qualified name referencing the family of polymorphic function we want to add to. This is the only situation where a qualified is used at a defiition of a global object.