1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
// SPEC.rs
// by Lut99
//
// Created:
// 20 Oct 2022, 14:17:30
// Last edited:
// 07 Nov 2023, 17:15:25
// Auto updated?
// Yes
//
// Description:
//! Defines (public) interfaces and structs for the `brane-ast` crate.
//
use brane_dsl::data_type::FunctionSignature;
use brane_dsl::{DataType, TextRange};
use strum::{EnumIter, IntoEnumIterator as _};
use crate::state::{ClassState, FunctionState, VarState};
/***** LIBRARY *****/
/// Defines the builtin functions that exist in BraneScript.
#[derive(Clone, Copy, Debug, EnumIter)]
pub enum BuiltinFunctions {
/// The print-function, which prints some text to stdout.
Print,
/// The println-function, which does the same as `Print` but now with a newline appended to the text.
PrintLn,
/// The len-function, which returns the length of an array.
Len,
/// The commit_builtin-function, which turns an IntermediateResult into a Data.
CommitResult,
}
impl BuiltinFunctions {
/// Returns the identifier of this builtin function.
#[inline]
pub fn name(&self) -> &'static str {
use BuiltinFunctions::*;
match self {
Print => "print",
PrintLn => "println",
Len => "len",
CommitResult => "commit_result",
}
}
/// Returns the signature of this specific builtin.
#[inline]
pub fn signature(&self) -> FunctionSignature {
use BuiltinFunctions::*;
match self {
Print => FunctionSignature::new(vec![DataType::String], DataType::Void),
PrintLn => FunctionSignature::new(vec![DataType::String], DataType::Void),
Len => FunctionSignature::new(vec![DataType::Array(Box::new(DataType::Any))], DataType::Integer),
CommitResult => FunctionSignature::new(
vec![DataType::String, DataType::Class(BuiltinClasses::IntermediateResult.name().into())],
DataType::Class(BuiltinClasses::Data.name().into()),
),
}
}
/// Returns an array with all the builtin functions in it.
#[inline]
pub fn all() -> [Self; 4] { [Self::Print, Self::PrintLn, Self::Len, Self::CommitResult] }
/// Returns an Array with all of the builtin functions but already casted to FunctionStates.
#[inline]
pub fn all_into_state() -> [FunctionState; 4] { [Self::Print.into(), Self::PrintLn.into(), Self::Len.into(), Self::CommitResult.into()] }
/// Checks if the given string is a builtin.
#[inline]
pub fn is_builtin(name: impl AsRef<str>) -> bool {
// Note that the order in which we match (i.e., on self instead of name) is a little awkward but guarantees Rust will warns us if we change the set.
let name: &str = name.as_ref();
for builtin in Self::iter() {
if name == builtin.name() {
return true;
}
}
false
}
}
impl From<BuiltinFunctions> for FunctionState {
#[inline]
fn from(value: BuiltinFunctions) -> Self {
Self {
name: value.name().into(),
signature: value.signature(),
class_name: None,
range: TextRange::none(),
}
}
}
/// Defines the builtin classes that exist in BraneScript.
#[derive(Clone, Copy, Debug)]
pub enum BuiltinClasses {
/// The data-class.
Data,
/// The intermediate-result-class.
IntermediateResult,
}
impl BuiltinClasses {
/// Returns the identifier of this builtin class.
#[inline]
pub fn name(&self) -> &'static str {
use BuiltinClasses::*;
match self {
Data => "Data",
IntermediateResult => "IntermediateResult",
}
}
/// Returns a list of all properties (as `VarState`s) in this builtin class.
#[inline]
pub fn props(&self) -> Vec<VarState> {
use BuiltinClasses::*;
match self {
Data => vec![VarState {
name: "name".into(),
data_type: DataType::String,
function_name: None,
class_name: Some(self.name().into()),
range: TextRange::none(),
}],
IntermediateResult => vec![VarState {
name: "path".into(),
data_type: DataType::String,
function_name: None,
class_name: Some(self.name().into()),
range: TextRange::none(),
}],
}
}
/// Returns a list of all methods (as `FunctioNState`s) in this builtin class.
#[inline]
pub fn methods(&self) -> Vec<FunctionState> {
use BuiltinClasses::*;
match self {
Data => vec![],
IntermediateResult => vec![],
}
}
/// Returns an array with all the builtin classes in it.
#[inline]
pub fn all() -> [Self; 2] { [Self::Data, Self::IntermediateResult] }
/// Returns an Array with all of the builtin functions but already casted to FunctionStates.
///
/// # Arguments
/// - `funcs`: The list of function states to use for declaring new methods, if any.
#[inline]
pub fn all_into_state(funcs: &mut Vec<FunctionState>) -> [ClassState; 2] {
[Self::Data.into_state(funcs), Self::IntermediateResult.into_state(funcs)]
}
/// Creates a new ClassState for this BuiltinClasses, where we define the functions in the given TableList of functions.
///
/// # Arguments
/// - `funcs`: The TableList of functions where to declare the new ones.
///
/// # Returns
/// A new ClassState instance.
#[inline]
pub fn into_state(&self, funcs: &mut Vec<FunctionState>) -> ClassState {
ClassState {
name: self.name().into(),
props: self.props(),
methods: self
.methods()
.into_iter()
.enumerate()
.map(|(i, state)| {
funcs.push(state);
i
})
.collect(),
package_name: None,
package_version: None,
range: TextRange::none(),
}
}
}