Support adding variables

This commit is contained in:
JT 2021-07-24 09:46:55 +12:00
parent 6fcdc76059
commit fca3a6b75e
5 changed files with 52 additions and 8 deletions

View file

@ -87,7 +87,20 @@ fn eval_call(state: &State, stack: &mut Stack, call: &Call) -> Result<Value, She
let block = state.parser_state.get_block(block_id);
eval_block(state, stack, block)
} else {
Ok(Value::Unknown)
if decl.signature.name == "let" {
let var_id = call.positional[0]
.as_var()
.expect("internal error: missing variable");
let rhs = eval_expression(state, stack, &call.positional[2])?;
println!("Adding: {:?} to {}", rhs, var_id);
stack.add_var(var_id, rhs);
Ok(Value::Unknown)
} else {
Ok(Value::Unknown)
}
}
}

View file

@ -131,6 +131,9 @@ fn main() -> std::io::Result<()> {
let prompt = DefaultPrompt::new(1);
let mut current_line = 1;
let mut stack = Stack {
vars: HashMap::new(),
};
loop {
let input = line_editor.read_line(&prompt)?;
@ -158,9 +161,10 @@ fn main() -> std::io::Result<()> {
s.as_bytes(),
false,
);
println!("{:?}", output);
// println!("{:?}", output);
if let Some(err) = err {
println!("Error: {:?}", err);
continue;
}
// println!("Error: {:?}", err);
(output, working_set.render())
@ -168,9 +172,6 @@ fn main() -> std::io::Result<()> {
ParserState::merge_delta(&mut *parser_state.borrow_mut(), delta);
let mut stack = Stack {
vars: HashMap::new(),
};
let state = State {
parser_state: &*parser_state.borrow(),
};

View file

@ -1,3 +1,4 @@
use crate::parser_state::Type;
pub use crate::Span;
#[derive(Debug)]
@ -18,6 +19,7 @@ pub enum ParseError {
ShortFlagBatchCantTakeArg(Span),
MissingPositional(String, Span),
MissingType(Span),
TypeMismatch(Type, Span),
MissingRequiredFlag(String, Span),
IncompleteMathExpression(Span),
UnknownState(String, Span),

View file

@ -666,12 +666,30 @@ impl<'a> ParserWorkingSet<'a> {
};
// println!("end: {}", end);
let (arg, err) =
self.parse_multispan_value(&spans[..end], &mut spans_idx, positional.shape);
let orig_idx = spans_idx;
let (arg, err) = self.parse_multispan_value(
&spans[..end],
&mut spans_idx,
positional.shape.clone(),
);
error = error.or(err);
let arg = if positional.shape.to_type() != Type::Unknown
&& arg.ty != positional.shape.to_type()
{
let span = span(&spans[orig_idx..spans_idx + 1]);
error = error.or(Some(ParseError::TypeMismatch(
positional.shape.to_type(),
span,
)));
Expression::garbage(span)
} else {
arg
};
call.positional.push(arg);
positional_idx += 1;
} else {
call.positional.push(Expression::garbage(arg_span));
error = error.or(Some(ParseError::ExtraPositional(arg_span)))
}

View file

@ -12,7 +12,7 @@ pub struct ParserState {
scope: Vec<ScopeFrame>,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Type {
Int,
Bool,
@ -118,6 +118,16 @@ impl ParserState {
}
}
pub fn find_decl(&self, name: &[u8]) -> Option<DeclId> {
for scope in self.scope.iter().rev() {
if let Some(decl_id) = scope.decls.get(name) {
return Some(*decl_id);
}
}
None
}
pub fn get_var(&self, var_id: VarId) -> &Type {
self.vars
.get(var_id)