The_Programmers_ByAble/IDLs and BlogIDL; Part Two.md

2.7 KiB

IDLs and BlogIDL; Part Two.md

Last time arround we introduced the concept of attributes. This time around we will introduce structures and data layout.

Another typical thing that logs include are path to module from project and line+column

To facilitate nicely styling and handling the module, line and column we will use a structure.

struct ModuleLineColumn{
    line: u64,
    column: u64,
    module: String,
}

In this language a String is a UTF-8 Vector of bytes with an associated length.

You can argue the name of ModuleLineColumn but it works :)

Also not all strings are valid paths so that will be a fixme left up to a future blog post.

Now that we have a solid layout for ModuleLineColumn we can add an associated function signature. Remember we are not implementing these functions this language is purely to help us reason with data and provide easy to use libraries for manipulating data.

struct ModuleLineColumn{
    line: u64,
    column: u64,
    module: String,

    display: function(Self) -> String;
}

You may notice the two different line endings , and ;, both are identical. Associated functions take a pointer to Self and operate on Self in some way to return something.

In this case the display function takes the Module line and column

module = "kernel/ipc"
line = 15
column = 10

and displays them as kernel/ipc:15:10.

We have the log level and the location of the log the only thing remaining for this post is the content of the log

To store the content of the log we will use a bog standard String. Defined below

struct String = Vector<u8>;

In most programming languages there is a stack and a heap.

This languages defines ONLY heap allocated data.

A Vector is a sized array that can be resized because of its associated length field.

It containes another type inside of it so it has angle brackets <N> to describe that type.

Ok now we tie that all together with ANOTHER structure

struct Log {
    level: LogLevel,
    location: ModuleLineColumn,
    contents: String,
}

If we have a long list of system logs all intermingled it might be nice to know where a log came from.

There are many many ways to reason about how best to handle that for now we will not use anything and keep it as an exercise for the future.

Our final IDL code looks like the following.

struct String = Vector<u8>;

enum LogLevel {
    Error = 0,
    Warn = 1,
    Info = 2,
    Debug = 3,
    Trace = 4,
}

struct ModuleLineColumn{
    line: u64,
    column: u64,
    module: String,

    display: function(Self) -> String;
}

struct Log {
    level: LogLevel,
    location: ModuleLineColumn,
    contents: String,
}