diff options
Diffstat (limited to 'term/term.ha')
| -rw-r--r-- | term/term.ha | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/term/term.ha b/term/term.ha new file mode 100644 index 0000000..3104e71 --- /dev/null +++ b/term/term.ha @@ -0,0 +1,116 @@ +// Defines the colors that a terminal is expected to implement. +// These are the classical VGA colors. +export type color = enum { + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + LGRAY, + DGRAY, + LBLUE, + LGREEN, + LCYAN, + LRED, + YELLOW, + LMAGENTA, + WHITE +}; + +export type vtable = struct { + setpos: *fn(_: *term, _: (size, size)) void, + getpos: *fn(_: *term) (size, size), + setcolors: *fn(_: *term, _: (color, color)) void, + getcolors: *fn(_: *term) (color, color), + putchar: *fn(_: *term, _: u8) void, + getdim: *fn(_: *term) (size, size), +}; + +export type term = *vtable; + +export fn setpos(ctrl: *term, pos: (size, size)) void = { + ctrl.setpos(ctrl, pos); +}; +export fn getpos(ctrl: *term) (size, size) = { + return ctrl.getpos(ctrl); +}; +export fn setcolors(ctrl: *term, colors: (color, color)) void = { + ctrl.setcolors(ctrl, colors); +}; +export fn getcolors(ctrl: *term) (color, color) = { + return ctrl.getcolors(ctrl); +}; +export fn putchar(ctrl: *term, c: u8) void = { + ctrl.putchar(ctrl, c); +}; +export fn getdim(ctrl: *term) (size, size) = { + return ctrl.getdim(ctrl); +}; + + +fn advancex(ctrl: *term) void = { + let dim = getdim(ctrl); + let pos = getpos(ctrl); + + pos.0 += 1; + if (pos.0 >= dim.0) { + newline(ctrl); + } else { + setpos(ctrl, pos); + }; +}; + +fn newline(ctrl: *term) void = { + let dim = getdim(ctrl); + let pos = getpos(ctrl); + + pos.0 = 0; + pos.1 += 1; + + if (pos.1 >= dim.1) { + clear(ctrl); + setpos(ctrl, (0, 0)); + } else { + setpos(ctrl, pos); + }; +}; + +fn carriage(ctrl: *term) void = { + let pos = getpos(ctrl); + + pos.0 = 0; + setpos(ctrl, pos); +}; + +export fn print(ctrl: *term, msg: str) void = { + let msg = *(&msg: *[]u8); + + for (let i = 0z; i < len(msg); i += 1) { + switch (msg[i]) { + case '\n' => newline(ctrl); + case '\r' => carriage(ctrl); + case => + putchar(ctrl, msg[i]); + advancex(ctrl); + }; + }; +}; + +export fn clear(ctrl: *term) void = { + let colors = getcolors(ctrl); + setcolors(ctrl, (colors.1, colors.1)); + let dim = getdim(ctrl); + let pos = getpos(ctrl); + + for (let j = 0z; j < dim.1; j += 1) { + for (let i = 0z; i < dim.0; i += 1) { + setpos(ctrl, (i, j)); + putchar(ctrl, ' '); + }; + }; + + setpos(ctrl, pos); + setcolors(ctrl, colors); +}; |
