wip cmd-type-dsl
This commit is contained in:
parent
21aa45d189
commit
63e06a2472
3 changed files with 177 additions and 0 deletions
68
src/cmd_type_dsl/annotation.rs
Normal file
68
src/cmd_type_dsl/annotation.rs
Normal file
|
@ -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<CommandType, UnificationError> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
107
src/cmd_type_dsl/mod.rs
Normal file
107
src/cmd_type_dsl/mod.rs
Normal file
|
@ -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<CommandArgPattern>),
|
||||||
|
Optional(Box<CommandArgPattern>),
|
||||||
|
Conjunction(Vec<CommandArgPattern>),
|
||||||
|
Disjunction(Vec<CommandArgPattern>)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommandPattern {
|
||||||
|
name: String,
|
||||||
|
args: Vec<CommandArgPattern>,
|
||||||
|
env: Vec<(String, CommandTypeExpr)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandArgPattern {
|
||||||
|
pub fn match_cmd(&self, cmd: &Command) -> Result<Substitution, UnificationError> {
|
||||||
|
Err(UnificationError(vec![]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MatchCandidate {
|
||||||
|
at: usize,
|
||||||
|
expected: CommandPattern,
|
||||||
|
found: CommandTypeExpr,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UnificationError( Vec<MatchCandidate> );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub enum CommandTypeExpr {
|
||||||
|
Parameter(String),
|
||||||
|
ParameterPack(String),
|
||||||
|
Char(char),
|
||||||
|
Match(Box<CommandTypeExpr>, 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<CommandTypeStatement>),
|
||||||
|
Match(Box<CommandTypeExpr>, 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![])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ mod env;
|
||||||
mod parse;
|
mod parse;
|
||||||
//mod expand;
|
//mod expand;
|
||||||
|
|
||||||
|
mod cmd_type_dsl;
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||||
|
|
||||||
pub fn get_type_str(cmd: &str, item: &str) -> Option<String> {
|
pub fn get_type_str(cmd: &str, item: &str) -> Option<String> {
|
||||||
|
|
Loading…
Reference in a new issue