mirror of
https://github.com/danbulant/rush
synced 2026-05-19 04:18:35 +00:00
small fixes, array definition support
This commit is contained in:
parent
b000e924e8
commit
b0a774994f
5 changed files with 193 additions and 62 deletions
|
|
@ -33,9 +33,10 @@ impl Term {
|
|||
fn format(self: &Self, stdout: &mut RawTerminal<Stdout>) -> String {
|
||||
let (_, y) = stdout.cursor_pos().unwrap();
|
||||
format!(
|
||||
"{}{}{}{}{}",
|
||||
"{}{}{}{}{}{}",
|
||||
termion::clear::CurrentLine,
|
||||
termion::cursor::Goto(1, y),
|
||||
"$: ",
|
||||
&self.input,
|
||||
termion::cursor::Left((self.input.len() - self.idx).try_into().unwrap()),
|
||||
termion::cursor::Right(if self.input.len() > 0 { 1 } else { 0 } )
|
||||
|
|
@ -141,6 +142,9 @@ impl Shell {
|
|||
print!("$: ");
|
||||
io::stdout().flush().unwrap();
|
||||
shell.collect();
|
||||
if shell.term.input == "exit" {
|
||||
break;
|
||||
}
|
||||
shell.term.input += "\n";
|
||||
let res = parser::exec(&mut shell.term.input.as_bytes(), &mut shell.ctx);
|
||||
match res {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ pub enum Value {
|
|||
Literal(String),
|
||||
Variable(String),
|
||||
ArrayVariable(String),
|
||||
ArrayDefinition(Vec<Value>),
|
||||
ArrayFunction(DefinedFunction),
|
||||
StringFunction(DefinedFunction),
|
||||
Expressions(Vec<Expression>),
|
||||
|
|
@ -137,7 +138,7 @@ impl Tree {
|
|||
let mut token = self.get_current_token();
|
||||
loop {
|
||||
if matches!(token, Tokens::Space) {
|
||||
if buf.len() > 0 {
|
||||
if !buf.is_empty() {
|
||||
values.push(CommandValue::Value(Value::Values(buf)));
|
||||
buf = Vec::new();
|
||||
}
|
||||
|
|
@ -149,12 +150,12 @@ impl Tree {
|
|||
let val = match &token {
|
||||
Tokens::Literal(str) => Value::Literal(str.clone()),
|
||||
Tokens::SubStart => {
|
||||
let val = self.get_value(end)?;
|
||||
let val = self.get_value(end, false)?;
|
||||
token = self.get_current_token();
|
||||
val
|
||||
},
|
||||
Tokens::StringVariable(str, _) => {
|
||||
if str.len() == 0 { bail!("Expected variable name"); }
|
||||
if str.is_empty() { bail!("Expected variable name"); }
|
||||
Value::Variable(str.clone())
|
||||
},
|
||||
Tokens::ArrayVariable(str, _) => Value::ArrayVariable(str.clone()),
|
||||
|
|
@ -185,7 +186,7 @@ impl Tree {
|
|||
_ => {}
|
||||
}
|
||||
// self.next();
|
||||
if buf.len() > 0 {
|
||||
if !buf.is_empty() {
|
||||
values.push(CommandValue::Value(Value::Values(buf)));
|
||||
}
|
||||
Ok(Expression::Command(values))
|
||||
|
|
@ -201,18 +202,15 @@ impl Tree {
|
|||
_ => len += 1
|
||||
}
|
||||
}
|
||||
let key = Box::new(self.get_value(self.i + len)?);
|
||||
let key = Box::new(self.get_value(self.i + len, false)?);
|
||||
self.inc(); // ????
|
||||
self.inc();
|
||||
let value = Box::new(self.get_value(end)?);
|
||||
let value = Box::new(self.get_value(end, false)?);
|
||||
Ok(Expression::LetExpression(LetExpression { key, vartype: None, value }))
|
||||
}
|
||||
|
||||
fn parse_read(&mut self, target: Option<Expression>, _end: usize) -> Result<Expression> {
|
||||
let target = match target {
|
||||
Some(source) => Some(Box::new(source)),
|
||||
None => None
|
||||
};
|
||||
let target = target.map(Box::new);
|
||||
self.i += 1;
|
||||
let mut val_end = self.i;
|
||||
let mut found_first = false;
|
||||
|
|
@ -227,16 +225,13 @@ impl Tree {
|
|||
}
|
||||
}
|
||||
val_end -= 1;
|
||||
let source = Box::new(self.get_value(val_end)?);
|
||||
let source = Box::new(self.get_value(val_end, false)?);
|
||||
self.inc();
|
||||
Ok(Expression::FileSourceExpression(FileSourceExpression { source, target }))
|
||||
}
|
||||
|
||||
fn parse_write(&mut self, source: Option<Expression>, _end: usize) -> Result<Expression> {
|
||||
let source = match source {
|
||||
Some(source) => Some(Box::new(source)),
|
||||
None => None
|
||||
};
|
||||
let source = source.map(Box::new);
|
||||
self.i += 1;
|
||||
let mut val_end = self.i;
|
||||
let mut found_first = false;
|
||||
|
|
@ -251,7 +246,7 @@ impl Tree {
|
|||
}
|
||||
}
|
||||
val_end -= 1;
|
||||
let target = Box::new(self.get_value(val_end)?);
|
||||
let target = Box::new(self.get_value(val_end, false)?);
|
||||
self.inc();
|
||||
Ok(Expression::FileTargetExpression(FileTargetExpression { source, target }))
|
||||
}
|
||||
|
|
@ -353,14 +348,27 @@ impl Tree {
|
|||
Ok(expressions)
|
||||
}
|
||||
|
||||
fn get_value(&mut self, end: usize) -> Result<Value> {
|
||||
fn parse_array_definition(&mut self, end: usize) -> Result<Vec<Value>> {
|
||||
let mut values: Vec<Value> = Vec::new();
|
||||
if matches!(self.get_current_token(), Tokens::Space) { self.inc(); }
|
||||
loop {
|
||||
if self.i >= end - 1 { break; }
|
||||
let val = self.get_value(end, true)?;
|
||||
values.push(val);
|
||||
if matches!(self.get_current_token(), Tokens::Space) { self.inc(); }
|
||||
}
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
fn get_value(&mut self, end: usize, stop_on_space: bool) -> Result<Value> {
|
||||
let mut token = self.get_current_token();
|
||||
let mut values: Vec<Value> = Vec::new();
|
||||
let mut buf: Vec<Value> = Vec::new();
|
||||
loop {
|
||||
match token {
|
||||
Tokens::Space => {
|
||||
if buf.len() == 0 { token = self.inc().get_current_token(); continue; }
|
||||
if stop_on_space { break; }
|
||||
if buf.is_empty() { token = self.inc().get_current_token(); continue; }
|
||||
values.push(Value::Values(buf));
|
||||
buf = Vec::new();
|
||||
if self.i >= end - 1 { break }
|
||||
|
|
@ -376,6 +384,31 @@ impl Tree {
|
|||
Tokens::ArrayFunction(_) => bail!("Unexpected array function"),
|
||||
Tokens::StringFunction(_) => bail!("Unexpected string function"),
|
||||
Tokens::ParenthesisStart => bail!("Parenthesis not yet implemented"),
|
||||
Tokens::ArrayStart => {
|
||||
let mut len = 0;
|
||||
let mut lvl = 1;
|
||||
self.inc();
|
||||
for token in &self.tokens[self.i..] {
|
||||
match token.token {
|
||||
Tokens::ArrayStart => lvl += 1,
|
||||
Tokens::ArrayEnd => lvl -= 1,
|
||||
_ => {}
|
||||
}
|
||||
if lvl == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
if len + self.i == end { break }
|
||||
len += 1;
|
||||
}
|
||||
if lvl != 0 {
|
||||
bail!("Parenthesis do not match");
|
||||
}
|
||||
let val = Value::ArrayDefinition(self.parse_array_definition(self.i + len)?);
|
||||
values.push(val);
|
||||
self.inc();
|
||||
},
|
||||
Tokens::ArrayEnd => bail!("Unexpected token ARRAY END (])"),
|
||||
Tokens::SubStart => {
|
||||
let mut len = 0;
|
||||
let mut lvl = 1;
|
||||
|
|
@ -411,14 +444,14 @@ impl Tree {
|
|||
Tokens::Let => buf.push(Value::Literal(token.to_str())),
|
||||
Tokens::While => buf.push(Value::Literal(token.to_str())),
|
||||
Tokens::StringVariable(str, _) => {
|
||||
if buf.len() != 0 {
|
||||
if !buf.is_empty() {
|
||||
values.push(Value::Values(buf));
|
||||
buf = Vec::new();
|
||||
}
|
||||
values.push(Value::Variable(str.clone()));
|
||||
},
|
||||
Tokens::ArrayVariable(str, _) => {
|
||||
if buf.len() != 0 {
|
||||
if !buf.is_empty() {
|
||||
values.push(Value::Values(buf));
|
||||
buf = Vec::new();
|
||||
}
|
||||
|
|
@ -432,9 +465,12 @@ impl Tree {
|
|||
if self.i >= end - 1 { break }
|
||||
token = self.inc().get_current_token();
|
||||
}
|
||||
if buf.len() > 0 {
|
||||
if !buf.is_empty() {
|
||||
values.push(Value::Values(buf));
|
||||
}
|
||||
if values.len() == 1 {
|
||||
return Ok(values.into_iter().next().unwrap());
|
||||
}
|
||||
Ok(Value::Values(values))
|
||||
}
|
||||
|
||||
|
|
@ -487,6 +523,8 @@ impl Tree {
|
|||
self.inc();
|
||||
},
|
||||
Tokens::ParenthesisEnd => bail!("Unexpected token PARENTHESIS END ())"),
|
||||
Tokens::ArrayStart => bail!("Arrays not yet implemented"),
|
||||
Tokens::ArrayEnd => bail!("Unexpected token ARRAY END (])"),
|
||||
Tokens::ArrayFunction(_) => bail!("Unexpected array function"),
|
||||
Tokens::StringFunction(_) => bail!("Unexpected string function"),
|
||||
Tokens::SubStart => match expr {
|
||||
|
|
@ -528,7 +566,7 @@ impl Tree {
|
|||
Tokens::Break => match expr {
|
||||
None => {
|
||||
self.inc();
|
||||
expr = Some(Expression::BreakExpression(BreakExpression { num: Box::new(self.get_value(end)?)}));
|
||||
expr = Some(Expression::BreakExpression(BreakExpression { num: Box::new(self.get_value(end, false)?)}));
|
||||
},
|
||||
Some(_) => bail!("Unexpected break")
|
||||
}
|
||||
|
|
@ -552,6 +590,7 @@ impl Tree {
|
|||
}
|
||||
|
||||
pub fn build_tree(tokens: Vec<Token>) -> Result<Vec<Expression>> {
|
||||
dbg!(&tokens);
|
||||
let mut expressions: Vec<Expression> = Vec::new();
|
||||
let mut tree = Tree { tokens, i: 0 };
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ impl GetValue for Value {
|
|||
ctx.pop_scope();
|
||||
Ok(Variable::String(out))
|
||||
},
|
||||
Value::Values(vec) => {
|
||||
Value::Values(vec) | Value::ArrayDefinition(vec) => {
|
||||
let mut out = Vec::new();
|
||||
for val in vec {
|
||||
out.push(val.get(ctx)?);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ pub enum Tokens {
|
|||
StringFunction(String),
|
||||
ParenthesisStart,
|
||||
ParenthesisEnd,
|
||||
ArrayStart,
|
||||
ArrayEnd,
|
||||
CommandEnd(char),
|
||||
If,
|
||||
Else,
|
||||
|
|
@ -49,10 +51,12 @@ impl Tokens {
|
|||
"$(" => Tokens::SubStart,
|
||||
"(" => Tokens::ParenthesisStart,
|
||||
")" => Tokens::ParenthesisEnd,
|
||||
"[" => Tokens::ArrayStart,
|
||||
"]" => Tokens::ArrayEnd,
|
||||
">" => Tokens::FileWrite,
|
||||
"<" => Tokens::FileRead,
|
||||
"|" => Tokens::RedirectInto,
|
||||
"\r\n" | "\n" | ";" => Tokens::CommandEnd(str.chars().nth(0).unwrap()),
|
||||
"\r\n" | "\n" | ";" => Tokens::CommandEnd(str.chars().next().unwrap()),
|
||||
"&&" => Tokens::And,
|
||||
"||" => Tokens::Or,
|
||||
"=" => Tokens::ExportSet,
|
||||
|
|
@ -81,6 +85,8 @@ impl Tokens {
|
|||
Tokens::SubStart => "$(".to_string(),
|
||||
Tokens::ParenthesisStart => "(".to_string(),
|
||||
Tokens::ParenthesisEnd => ")".to_string(),
|
||||
Tokens::ArrayStart => "[".to_string(),
|
||||
Tokens::ArrayEnd => "]".to_string(),
|
||||
Tokens::RedirectInto => "|".to_string(),
|
||||
Tokens::FileRead => "<".to_string(),
|
||||
Tokens::FileWrite => ">".to_string(),
|
||||
|
|
@ -93,7 +99,7 @@ impl Tokens {
|
|||
}
|
||||
|
||||
|
||||
fn read_var_ahead(i: usize, text: &String) -> (usize, Token) {
|
||||
fn read_var_ahead(i: usize, text: &str) -> Result<(usize, Token)> {
|
||||
let mut x = i;
|
||||
let mut buf = String::new();
|
||||
let parens_mode = text.chars().nth(x + 1).unwrap() == '{';
|
||||
|
|
@ -103,7 +109,7 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Token) {
|
|||
let letter: char = text.chars().nth(x).unwrap();
|
||||
match letter {
|
||||
'a'..='z' | 'A'..='Z' | '0'..='9' | ':' | '_' => {
|
||||
buf.push(letter.clone());
|
||||
buf.push(letter);
|
||||
}
|
||||
'}' => {
|
||||
if parens_mode {
|
||||
|
|
@ -112,19 +118,19 @@ fn read_var_ahead(i: usize, text: &String) -> (usize, Token) {
|
|||
break;
|
||||
}
|
||||
'?' => {
|
||||
buf.push(letter.clone());
|
||||
buf.push(letter);
|
||||
x += 1;
|
||||
break;
|
||||
}
|
||||
l => { if !parens_mode { break } else { panic!("Invalid variable name (starting with '{:?}{:?}')", buf, l) } }
|
||||
l => { if !parens_mode { break } else { bail!("Invalid variable name (starting with '{}{}')", buf, l) } }
|
||||
}
|
||||
}
|
||||
let token = match text.chars().nth(i).unwrap() {
|
||||
'$' => Token { token: Tokens::StringVariable(buf, parens_mode), start: i, end: i + x },
|
||||
'@' => Token { token: Tokens::ArrayVariable(buf, parens_mode), start:i , end: i+x },
|
||||
a => panic!("Invalid value {}", a)
|
||||
a => bail!("Invalid value {}", a)
|
||||
};
|
||||
(x - i - 1, token)
|
||||
Ok((x - i - 1, token))
|
||||
}
|
||||
|
||||
pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
||||
|
|
@ -133,12 +139,12 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
|||
let mut escape_active = false;
|
||||
let mut text = String::new();
|
||||
reader.read_to_string(&mut text)?;
|
||||
let mut text_length = text.len();
|
||||
let text_length = text.len();
|
||||
|
||||
let mut tokens: Vec<Token> = Vec::new();
|
||||
|
||||
fn save_buf(buf: &mut String, tokens: &mut Vec<Token>, i: usize) {
|
||||
if buf.len() > 0 { tokens.push(Token { token: Tokens::detect(std::mem::take(buf)), end: i, start: i - buf.len() }) }
|
||||
if !buf.is_empty() { tokens.push(Token { token: Tokens::detect(std::mem::take(buf)), end: i, start: i - buf.len() }) }
|
||||
}
|
||||
|
||||
let mut buf = String::new();
|
||||
|
|
@ -153,24 +159,20 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
|||
match letter {
|
||||
'"' => if !escape_active && !quote_active { double_quote_active = !double_quote_active; buf_add = false },
|
||||
'\'' => if !escape_active && !double_quote_active { quote_active = !quote_active; buf_add = false },
|
||||
'$' => if !escape_active && !quote_active {
|
||||
'$' | '@' => if !escape_active && !quote_active {
|
||||
save_buf(&mut buf, &mut tokens, i);
|
||||
if text_length > i && text.chars().nth(i + 1).unwrap() == '(' {
|
||||
if *letter == '$' && text_length > i && text.chars().nth(i + 1).unwrap() == '(' {
|
||||
tokens.push(Token { token: Tokens::SubStart, start: i, end: i+1 });
|
||||
skipper = 1;
|
||||
buf_add = false;
|
||||
} else {
|
||||
let (skippers, mut token) = read_var_ahead(i, &text);
|
||||
let (skippers, mut token) = read_var_ahead(i, &text)?;
|
||||
match token.token {
|
||||
Tokens::StringVariable(ref str, bool) => if !bool && !double_quote_active {
|
||||
if text.len() > i + skippers && text.chars().nth(i + skippers).unwrap() == '(' {
|
||||
token = Token { token: Tokens::StringFunction(str.clone()), end: i + skippers, start: i };
|
||||
}
|
||||
Tokens::StringVariable(ref str, bool) => if !bool && !double_quote_active && text.len() > i + skippers && text.chars().nth(i + skippers).unwrap() == '(' {
|
||||
token = Token { token: Tokens::StringFunction(str.clone()), end: i + skippers, start: i };
|
||||
},
|
||||
Tokens::ArrayVariable(ref str, bool) => if !bool && !double_quote_active {
|
||||
if text.len() > i + skippers && text.chars().nth(i + skippers).unwrap() == '(' {
|
||||
token = Token { token: Tokens::ArrayFunction(str.clone()), end: i+skippers, start: i };
|
||||
}
|
||||
Tokens::ArrayVariable(ref str, bool) => if !bool && !double_quote_active && text.len() > i + skippers && text.chars().nth(i + skippers).unwrap() == '(' {
|
||||
token = Token { token: Tokens::ArrayFunction(str.clone()), end: i+skippers, start: i };
|
||||
}
|
||||
_ => bail!("Cannot happen")
|
||||
}
|
||||
|
|
@ -181,7 +183,7 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
|||
},
|
||||
';' | '\r' | '\n' => if !escape_active && !quote_active && !double_quote_active {
|
||||
save_buf(&mut buf, &mut tokens, i);
|
||||
tokens.push(Token { token: Tokens::CommandEnd(letter.clone()), start: i, end: i });
|
||||
tokens.push(Token { token: Tokens::CommandEnd(*letter), start: i, end: i });
|
||||
let mut x = 0;
|
||||
while x < text.len() - 1 && matches!(text.chars().nth(x).unwrap(), '\n' | '\r' | ';' | ' ') {
|
||||
x += 1;
|
||||
|
|
@ -231,6 +233,16 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
|||
tokens.push(Token { token: Tokens::ParenthesisEnd, start: i, end: i });
|
||||
buf_add = false;
|
||||
},
|
||||
'[' => if !quote_active && !double_quote_active && !escape_active {
|
||||
save_buf(&mut buf, &mut tokens, i);
|
||||
tokens.push(Token { token: Tokens::ArrayStart, start: i, end: i });
|
||||
buf_add = false;
|
||||
},
|
||||
']' => if !quote_active && !double_quote_active && !escape_active {
|
||||
save_buf(&mut buf, &mut tokens, i);
|
||||
tokens.push(Token { token: Tokens::ArrayEnd, start: i, end: i });
|
||||
buf_add = false;
|
||||
},
|
||||
'\\' => if !escape_active {
|
||||
escape_active = true;
|
||||
buf_add = false;
|
||||
|
|
@ -253,7 +265,7 @@ pub fn tokenize(reader: &mut dyn std::io::BufRead) -> Result<Vec<Token>> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
if letter.clone() != '\\' { escape_active = false; }
|
||||
if *letter != '\\' { escape_active = false; }
|
||||
if buf_add {
|
||||
buf.push(*letter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use anyhow::{bail, Result};
|
||||
use crate::parser::ast::FunctionDefinitionExpression;
|
||||
|
||||
|
|
@ -17,9 +18,9 @@ pub enum Variable {
|
|||
Array(Vec<Variable>)
|
||||
}
|
||||
|
||||
impl Variable {
|
||||
pub fn to_string(self: &Self) -> String {
|
||||
match self {
|
||||
impl Display for Variable {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", match self {
|
||||
Variable::String(var) => {
|
||||
var.clone()
|
||||
},
|
||||
|
|
@ -36,23 +37,98 @@ impl Variable {
|
|||
},
|
||||
Variable::Array(vars) => {
|
||||
let len = vars.len();
|
||||
if len == 1 { return vars.get(0).unwrap().to_string(); }
|
||||
if len == 1 {
|
||||
return match vars.get(0) {
|
||||
Some(var) => write!(f, "{}", var),
|
||||
None => write!(f, "[]")
|
||||
}
|
||||
}
|
||||
let mut str = String::new();
|
||||
let mut i = 0;
|
||||
for var in vars {
|
||||
for (i, var) in vars.iter().enumerate() {
|
||||
str += &*var.clone().to_string();
|
||||
if i < len - 1 {
|
||||
str += " ";
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
str
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index(self: &Self, index: &Variable) -> Result<&Variable> {
|
||||
impl Variable {
|
||||
pub fn index(&self, index: &Variable) -> Result<&Variable> {
|
||||
match self {
|
||||
Variable::HMap(map) => {
|
||||
match index {
|
||||
Variable::String(key) => {
|
||||
match map.get(key) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Key not found")
|
||||
}
|
||||
}
|
||||
_ => bail!("Cannot index with non-string")
|
||||
}
|
||||
},
|
||||
Variable::Array(arr) => {
|
||||
match index {
|
||||
Variable::I32(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::I64(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::I128(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::F32(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::F64(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::U32(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::U64(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::U128(idx) => {
|
||||
match arr.get(*idx as usize) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
Variable::String(idx) => {
|
||||
match arr.get(idx.parse::<usize>()?) {
|
||||
Some(val) => Ok(val),
|
||||
None => bail!("Index out of bounds")
|
||||
}
|
||||
}
|
||||
_ => bail!("Cannot index with non-integer")
|
||||
}
|
||||
},
|
||||
_ => bail!("Cannot index unsupported types")
|
||||
}
|
||||
}
|
||||
|
|
@ -100,11 +176,11 @@ impl Context {
|
|||
}
|
||||
|
||||
pub fn get_var(self: &mut Self, var: &str) -> Option<&mut Variable> {
|
||||
for mut scope in self.scopes.iter_mut().rev() {
|
||||
let mut vars = &mut scope.vars;
|
||||
for scope in self.scopes.iter_mut().rev() {
|
||||
let vars = &mut scope.vars;
|
||||
let val = vars.get_mut(var);
|
||||
match val {
|
||||
None => {},
|
||||
None => {}
|
||||
Some(val) => {
|
||||
return Some(val);
|
||||
}
|
||||
|
|
@ -114,16 +190,16 @@ impl Context {
|
|||
}
|
||||
|
||||
pub fn set_var(&mut self, key: String, val: Variable) {
|
||||
let mut vars = &mut self.scopes.last_mut().unwrap().vars;
|
||||
let vars = &mut self.scopes.last_mut().unwrap().vars;
|
||||
vars.insert(key, val);
|
||||
}
|
||||
|
||||
pub fn get_func(self: &mut Self, key: &str) -> Option<&mut FunctionDefinitionExpression> {
|
||||
for mut scope in self.scopes.iter_mut().rev() {
|
||||
let mut funcs = &mut scope.func;
|
||||
for scope in self.scopes.iter_mut().rev() {
|
||||
let funcs = &mut scope.func;
|
||||
let val = funcs.get_mut(key);
|
||||
match val {
|
||||
None => {},
|
||||
None => {}
|
||||
Some(val) => {
|
||||
return Some(val);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue