civboot / fngi

a readable language that grows from the silicon
The Unlicense
59 stars 3 forks source link

Logger #28

Open vitiral opened 1 year ago

vitiral commented 1 year ago

Logger is a role. It has different API than writer, one designed for "single drop" writes which come in chains.

The API is as follows. Note: folks will typically use the macros.

role Logger [
  absmeth level[&Self] -> U2\level
  absmeth arena[&Self] -> Arena
  absmeth start[&Self, U2\level]
  absmeth add[&Self, Slc]
  absmeth end[&Self]
]

\ Compile time macros: these will turn the stuff in the parens into a comment
\ if the compile-time logging level isn't enabled. If it is enabled, it expands to
\ use the global "logs.clog" which is the default compile-time logger. 
infoc|the name is {name}|
\ expands to:
clog.start(logs.INFO); clog.add(|the name is |); name.fmt(clog, 0); clog.end();

\ Runtime macros: these use the logging variable "log" and insert an if-statement
info:log|the name is {name}|
\ expands to:
if(log.start(logs.INFO)) do (
  log.add(|the name is |);  name.fmt(log, 0);  log.end();
)

Internal architecture

Loggers have (typically) two Arenas (BBAs, etc). They flush one to their output file while the other receives from the inputs.

The current arena to write to can be accessed with the arena() method. start() also pushes this arena onto the arena stack and end() pops it off the arena stack. The actual lifetime of the arena doesn't end at end() but will instead be until the message/s are flushed to the output.

Macro architecture

Basically it has a custom string parser. When it encounters an unescaped {token:fmtargs} it compiles the token inside. It looks at the type returned:

It then calls log.add on the resultant Slc.

There is also $textmacro which can be used to replace the text that is being parsed (like a normal text macro), which can be escaped with \$

FmtArgs

It's a U4 bitmap

Top 2 bytes

Bottom 2 bytes: