From 63e06a247211731f3d0d83b2f0a4c16947d08f2f Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 29 Oct 2023 14:53:16 +0100 Subject: [PATCH] wip cmd-type-dsl --- src/cmd_type_dsl/annotation.rs | 68 +++++++++++++++++++++ src/cmd_type_dsl/mod.rs | 107 +++++++++++++++++++++++++++++++++ src/main.rs | 2 + 3 files changed, 177 insertions(+) create mode 100644 src/cmd_type_dsl/annotation.rs create mode 100644 src/cmd_type_dsl/mod.rs diff --git a/src/cmd_type_dsl/annotation.rs b/src/cmd_type_dsl/annotation.rs new file mode 100644 index 0000000..24c6467 --- /dev/null +++ b/src/cmd_type_dsl/annotation.rs @@ -0,0 +1,68 @@ + + + pub enum AnnotationContext { + Cached( Vec<(CommandPattern, CommandTypeStatement)> ), + Load( String ), + FindIn( String ), + } + impl AnnotationContext { + /* loads & parses any given context + */ + /* + pub fn into_cached(self) -> AnnotationContext { + match self { + AnnotationContext::Load( path ) => { + + } + } + } +*/ + pub fn get_type(&self, cmd: &Command) -> Result { + match cmd { + Command::Simple{ assignments, command_word, redirections } => { + match self { + AnnotationContext::Cached( annotations ) => { + // find matching command pattern... + for (cmd_pat, typ) in annotations.iter() { + if let Ok(unificator) = cmd_pat.match_cmd(cmd) { + return Ok( typ.substitute(unificator).eval() ); + } + } + + Err(UnificationError::NoPattern) + }, + + AnnotationContext::Load( path ) => { + /* todo: + * - open file at `path` + * - parse CommandPattern + CommandTypeStatement + * - get_type on AnnotationContext::Cached() + */ + + } + AnnotationContext::FindIn( path ) => { + // if let Some(command_name) = command_word.segments.get(0) { + /* todo: + * - use command_name to lookup file + * - forward to AnnotationContext::Load() + */ +/* + let mut err = UnificationError( vec![] ); + for file in path.direntries { + if let Ok(typ) = AnnotationContext::Load( path ).get_type() => { + + } + } +*/ + // } + } + } + } + + _ => { + Err(UnificationError::NoPattern) + } + } + } + } + diff --git a/src/cmd_type_dsl/mod.rs b/src/cmd_type_dsl/mod.rs new file mode 100644 index 0000000..4d7ec13 --- /dev/null +++ b/src/cmd_type_dsl/mod.rs @@ -0,0 +1,107 @@ +use std::{ + collections::HashMap, + boxed::Box +}; + +use crate::ast::Command; +use laddertypes::*; + + +pub struct Substitution(HashMap< String, CommandTypeExpr >); +impl Substitution { + pub fn apply(&self, expr: &mut CommandTypeExpr) { + + } +} + +pub enum CommandArgPattern { + Literal(String), + Variable(String), + VariablePack(Box), + Optional(Box), + Conjunction(Vec), + Disjunction(Vec) +} + +pub struct CommandPattern { + name: String, + args: Vec, + env: Vec<(String, CommandTypeExpr)>, +} + +impl CommandArgPattern { + pub fn match_cmd(&self, cmd: &Command) -> Result { + Err(UnificationError(vec![])) + } +} + +pub struct MatchCandidate { + at: usize, + expected: CommandPattern, + found: CommandTypeExpr, +} + +pub struct UnificationError( Vec ); + + + +pub enum CommandTypeExpr { + Parameter(String), + ParameterPack(String), + Char(char), + Match(Box, Vec<(CommandArgPattern, CommandTypeExpr)>) +} + +impl CommandTypeExpr { + pub fn eval(self) -> CommandTypeExpr { + match self { + s=>s + } + } +} + +pub struct FileDescriptor(u32); +pub enum PipeDirection { In, Out } + +pub enum Selector { + Pipe(FileDescriptor, PipeDirection), + Parameter(String), + ParameterPack(String), + File(String) +} + +pub enum CommandTypeStatement { + TypAssign(Selector, TypeTerm), + ValAssign(String, CommandTypeExpr), + Block(Vec), + Match(Box, Vec<(CommandArgPattern, CommandTypeStatement)>) +} + +pub struct CommandType(Vec<(Selector, TypeTerm)>); + +impl CommandTypeStatement { + pub fn eval(self) -> CommandType { + match self { + CommandTypeStatement::Block(stmnts) => { + CommandType( stmnts.into_iter().map(|stmnt| stmnt.eval().0.into_iter()).flatten().collect() ) + } + CommandTypeStatement::TypAssign(selector, typ) => { + CommandType( vec![ (selector, typ) ]) + } + CommandTypeStatement::ValAssign(variable, expr) => { + CommandType(vec![]) + } + CommandTypeStatement::Match(pattern, cases) => { + /* + for (case,stmnt) in cases.into_iter() { + if let Ok(unificator) = pattern + if let Ok() = case.match_expr() + CommandType( vec![] ) + } + */ + CommandType(vec![]) + } + } + } +} + diff --git a/src/main.rs b/src/main.rs index 3752690..f81dca8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,8 @@ mod env; mod parse; //mod expand; +mod cmd_type_dsl; + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ pub fn get_type_str(cmd: &str, item: &str) -> Option {