flowsurface-indicator-engine 0.9.0

Aggr-level live scripting engine for Flowsurface indicator sources
Documentation
use super::super::ast::AstFunction;
use crate::diagnostics::Diagnostic;
use crate::hir::{FunctionId, HirFunction};
use crate::types::{Type, ValueType};
use std::collections::BTreeMap;
use std::path::Path;

pub(super) struct FunctionIndex {
    pub(super) by_name: BTreeMap<String, FunctionId>,
    pub(super) signatures: Vec<(Vec<String>, usize)>,
    pub(super) source_ids: Vec<FunctionId>,
    pub(super) stubs: Vec<HirFunction>,
    pub(super) diagnostics: Vec<Diagnostic>,
}

pub(super) fn index_functions(functions: &[AstFunction], path: &Path) -> FunctionIndex {
    let mut index = FunctionIndex {
        by_name: BTreeMap::new(),
        signatures: Vec::new(),
        source_ids: Vec::with_capacity(functions.len()),
        stubs: Vec::new(),
        diagnostics: Vec::new(),
    };
    for function in functions {
        if let Some(id) = index.by_name.get(&function.name).copied() {
            index.diagnostics.push(Diagnostic::error(
                path.to_path_buf(),
                function.span,
                format!("function {} is already declared", function.name),
            ));
            index.source_ids.push(id);
            continue;
        }
        let id = FunctionId(index.stubs.len());
        index.by_name.insert(function.name.clone(), id);
        index.signatures.push((
            function
                .parameters
                .iter()
                .map(|parameter| parameter.name.clone())
                .collect(),
            function
                .parameters
                .iter()
                .filter(|parameter| parameter.default.is_none())
                .count(),
        ));
        index.stubs.push(HirFunction {
            id,
            name: function.name.clone(),
            parameters: Vec::new(),
            parameter_names: Vec::new(),
            parameter_defaults: Vec::new(),
            local_slots: Vec::new(),
            body: Vec::new(),
            return_type: Type::series(ValueType::Float),
        });
        index.source_ids.push(id);
    }
    index
}