blr-lang 0.1.0

A language implementation that provides type safe dataframes
Documentation
//! Implementation of blr the language.

pub mod compiler;
mod debug;
mod exec;
mod external_type;
pub mod runtime;
pub mod snapshot_diff;

use std::path::PathBuf;

use compiler::{Database, ItemSource, TypeError};
use runtime::{binary, conv};
use snafu::{ResultExt as _, Snafu};
use tokio::fs;
use wac_graph::{EncodeError, PlugError};
use wasmtime::component::Val;

pub type Result<T, E = Error> = std::result::Result<T, E>;

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("parse error: {}", message))]
    Parse {
        // TODO: Preserve actual diagnostics
        message: String,
    },
    #[snafu(display("type error"))]
    Type { source: TypeError },
    // TODO Collapse Link errors into a single error enum
    #[snafu(display("link error"))]
    Link { source: anyhow::Error },
    #[snafu(display("link plugging error"))]
    LinkPlug { source: PlugError },
    #[snafu(display("link encode error"))]
    LinkEncode { source: EncodeError },
    #[snafu(display("io error at {path}"))]
    IO {
        source: std::io::Error,
        path: String,
    },
    #[snafu(display("execution error"))]
    Exec { source: snafu::Whatever },
}

pub async fn run(src: &str, path_root: impl Into<PathBuf>) -> Result<Val> {
    let mut item_source = ItemSource::default();
    binary::register_binary_operator_functions(&mut item_source);
    conv::register_conversion_funcs(&mut item_source);
    let mut db = Database::new(path_root, src.to_string(), item_source);
    let code = compiler::root_component(&mut db).await?;

    if let Ok(prefix) = std::env::var("BLR_SNAPSHOT") {
        // TODO sanitize the path
        let file_path = PathBuf::from(prefix).with_extension("blr.wasm");
        fs::write(&file_path, &code).await.unwrap();
        tracing::debug!(file_path = %file_path.display(), "snapshot saved");
    }

    exec::run_wasm(&code).await.context(ExecSnafu)
}

pub fn val_to_string(val: Val) -> String {
    match val {
        Val::S32(v) => v.to_string(),
        Val::S64(v) => v.to_string(),
        Val::Bool(v) => v.to_string(),
        Val::S8(v) => v.to_string(),
        Val::U8(v) => v.to_string(),
        Val::S16(v) => v.to_string(),
        Val::U16(v) => v.to_string(),
        Val::U32(v) => v.to_string(),
        Val::U64(v) => v.to_string(),
        Val::Float32(v) => v.to_string(),
        Val::Float64(v) => v.to_string(),
        Val::Char(v) => v.to_string(),
        //TODO Escape string
        Val::String(v) => v,
        Val::List(_vals) => todo!(),
        Val::Record(fields) => format!("{:?}", fields),
        Val::Tuple(_vals) => todo!(),
        Val::Variant(_, _val) => todo!(),
        Val::Enum(_) => todo!(),
        Val::Option(_val) => todo!(),
        Val::Result(_val) => todo!(),
        Val::Flags(_items) => todo!(),
        Val::Resource(_resource_any) => todo!(),
        Val::Future(_future_any) => todo!(),
        Val::Stream(_stream_any) => todo!(),
        Val::ErrorContext(_error_context_any) => todo!(),
    }
}