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

View file

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

View file

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

View file

@ -12,7 +12,7 @@ pub struct ParserState {
scope: Vec<ScopeFrame>, scope: Vec<ScopeFrame>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum Type { pub enum Type {
Int, Int,
Bool, 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 { pub fn get_var(&self, var_id: VarId) -> &Type {
self.vars self.vars
.get(var_id) .get(var_id)