begin aliases

This commit is contained in:
JT 2021-08-09 12:19:07 +12:00
parent 38fef28c84
commit bf19918e3c
4 changed files with 79 additions and 4 deletions

View File

@ -359,6 +359,8 @@ fn eval_call(state: &State, stack: Stack, call: &Call) -> Result<Value, ShellErr
Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "def" {
Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "alias" {
Ok(Value::Nothing { span: call.head })
} else {
Err(ShellError::Unsupported(call.head))
}

View File

@ -43,7 +43,7 @@ fn main() -> std::io::Result<()> {
working_set.add_decl(sig.into());
let sig = Signature::build("alias")
.required("var_name", SyntaxShape::Variable, "variable name")
.required("name", SyntaxShape::String, "name of the alias")
.required(
"initial_value",
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),

View File

@ -782,13 +782,17 @@ impl<'a> ParserWorkingSet<'a> {
(Box::new(call), span(spans), error)
}
pub fn parse_call(&mut self, spans: &[Span]) -> (Expression, Option<ParseError>) {
pub fn parse_call(
&mut self,
spans: &[Span],
expand_aliases: bool,
) -> (Expression, Option<ParseError>) {
// assume spans.len() > 0?
let mut pos = 0;
let mut shorthand = vec![];
while pos < spans.len() {
// First, check if there is any environment shorthand
// Check if there is any environment shorthand
let name = self.get_span_contents(spans[pos]);
let split: Vec<_> = name.splitn(2, |x| *x == b'=').collect();
if split.len() == 2 {
@ -807,6 +811,21 @@ impl<'a> ParserWorkingSet<'a> {
}
let name = self.get_span_contents(spans[pos]);
if expand_aliases {
if let Some(expansion) = self.find_alias(name) {
//let mut spans = spans.to_vec();
let mut new_spans: Vec<Span> = vec![];
new_spans.extend(&spans[0..pos]);
new_spans.extend(expansion);
if spans.len() > pos {
new_spans.extend(&spans[(pos + 1)..]);
}
return self.parse_call(&new_spans, false);
}
}
pos += 1;
if let Some(mut decl_id) = self.find_decl(name) {
@ -2115,7 +2134,7 @@ impl<'a> ParserWorkingSet<'a> {
match bytes[0] {
b'0' | b'1' | b'2' | b'3' | b'4' | b'5' | b'6' | b'7' | b'8' | b'9' | b'(' | b'{'
| b'[' | b'$' | b'"' | b'\'' => self.parse_math_expression(spans),
_ => self.parse_call(spans),
_ => self.parse_call(spans, true),
}
}
@ -2234,6 +2253,30 @@ impl<'a> ParserWorkingSet<'a> {
}
}
pub fn parse_alias(&mut self, spans: &[Span]) -> (Statement, Option<ParseError>) {
let name = self.get_span_contents(spans[0]);
if name == b"alias" && spans.len() >= 4 {
let alias_name = self.get_span_contents(spans[1]).to_vec();
let _equals = self.get_span_contents(spans[2]);
let replacement = spans[3..].to_vec();
self.add_alias(alias_name, replacement);
}
(
Statement::Expression(Expression {
expr: Expr::Garbage,
span: span(spans),
ty: Type::Unknown,
}),
Some(ParseError::UnknownState(
"internal error: let statement unparseable".into(),
span(spans),
)),
)
}
pub fn parse_let(&mut self, spans: &[Span]) -> (Statement, Option<ParseError>) {
let name = self.get_span_contents(spans[0]);
@ -2271,6 +2314,8 @@ impl<'a> ParserWorkingSet<'a> {
(decl, None)
} else if let (stmt, None) = self.parse_let(spans) {
(stmt, None)
} else if let (stmt, None) = self.parse_alias(spans) {
(stmt, None)
} else {
let (expr, err) = self.parse_expression(spans);
(Statement::Expression(expr), err)

View File

@ -36,6 +36,7 @@ pub type BlockId = usize;
struct ScopeFrame {
vars: HashMap<Vec<u8>, VarId>,
decls: HashMap<Vec<u8>, DeclId>,
aliases: HashMap<Vec<u8>, Vec<Span>>,
}
impl ScopeFrame {
@ -43,6 +44,7 @@ impl ScopeFrame {
Self {
vars: HashMap::new(),
decls: HashMap::new(),
aliases: HashMap::new(),
}
}
}
@ -352,6 +354,22 @@ impl<'a> ParserWorkingSet<'a> {
None
}
pub fn find_alias(&self, name: &[u8]) -> Option<&[Span]> {
for scope in self.delta.scope.iter().rev() {
if let Some(spans) = scope.aliases.get(name) {
return Some(spans);
}
}
for scope in self.permanent_state.scope.iter().rev() {
if let Some(spans) = scope.aliases.get(name) {
return Some(spans);
}
}
None
}
pub fn add_variable(&mut self, mut name: Vec<u8>, ty: Type) -> VarId {
let next_id = self.next_var_id();
@ -373,6 +391,16 @@ impl<'a> ParserWorkingSet<'a> {
next_id
}
pub fn add_alias(&mut self, name: Vec<u8>, replacement: Vec<Span>) {
let last = self
.delta
.scope
.last_mut()
.expect("internal error: missing stack frame");
last.aliases.insert(name, replacement);
}
pub fn set_variable_type(&mut self, var_id: VarId, ty: Type) {
let num_permanent_vars = self.permanent_state.num_vars();
if var_id < num_permanent_vars {