diff --git a/Cargo.lock b/Cargo.lock index 9599d91..6f79618 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,6 +367,7 @@ dependencies = [ "colored", "dust-lang", "env_logger", + "log", "nu-ansi-term", "reedline", ] diff --git a/dust-lang/src/context.rs b/dust-lang/src/context.rs index 256d070..4913f6f 100644 --- a/dust-lang/src/context.rs +++ b/dust-lang/src/context.rs @@ -36,7 +36,7 @@ impl Context { for (identifier, (value_data, usage_data)) in other.variables.read()?.iter() { if let ValueData::Type(Type::Function { .. }) = value_data { - log::trace!("Inheriting type of variable {identifier}."); + log::trace!("Context inheriting type of {identifier}."); self_data.insert(identifier.clone(), (value_data.clone(), usage_data.clone())); } @@ -49,7 +49,7 @@ impl Context { let mut self_data = self.variables.write()?; for (identifier, (value_data, usage_data)) in other.variables.read()?.iter() { - log::trace!("Inheriting variable {identifier}."); + log::trace!("Context inheriting variable {identifier}."); self_data.insert(identifier.clone(), (value_data.clone(), usage_data.clone())); } @@ -65,7 +65,7 @@ impl Context { pub fn get_type(&self, identifier: &Identifier) -> Result, ValidationError> { if let Some((value_data, _)) = self.variables.read()?.get(identifier) { - log::trace!("Using {identifier}'s type."); + log::trace!("Getting {identifier}'s type."); let r#type = match value_data { ValueData::Type(r#type) => r#type.clone(), @@ -105,6 +105,19 @@ impl Context { } } + pub fn get_data( + &self, + identifier: &Identifier, + ) -> Result, RwLockPoisonError> { + if let Some(full_data) = self.variables.read()?.get(identifier) { + log::trace!("Getting {identifier}'s value."); + + Ok(Some(full_data.clone())) + } else { + Ok(None) + } + } + pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> { log::debug!("Setting {identifier} to type {}.", r#type); diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index ded5f90..befa050 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -88,6 +88,8 @@ impl Interpreter { ), ]; + log::info!("Start loading standard library..."); + let error = std_sources .into_par_iter() .find_map_any(|(source_id, source)| { @@ -139,6 +141,8 @@ impl Interpreter { .err() }); + log::info!("Finish loading standard library."); + if let Some(error) = error { Err(error) } else { diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 7d3559a..cf4a78b 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -12,6 +12,10 @@ use crate::{ pub type ParserInput<'src> = SpannedInput, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>; +pub type ParserExtra<'src> = extra::Err, SimpleSpan>>; + +pub type Comment = String; + pub fn parse<'src>(tokens: &'src [(Token<'src>, SimpleSpan)]) -> Result> { let statements = parser(false) .parse(tokens.spanned((tokens.len()..tokens.len()).into())) @@ -28,8 +32,7 @@ pub fn parse<'src>(tokens: &'src [(Token<'src>, SimpleSpan)]) -> Result( allow_built_ins: bool, -) -> impl Parser<'src, ParserInput<'src>, Vec, extra::Err, SimpleSpan>>> -{ +) -> impl Parser<'src, ParserInput<'src>, Vec, ParserExtra<'src>> { let identifiers: RefCell> = RefCell::new(HashMap::new()); let _custom_types: Rc>> = Rc::new(RefCell::new(HashMap::new())); @@ -335,8 +338,20 @@ pub fn parser<'src>( ) }); + let list_index = choice((list.clone(), identifier_expression.clone())) + .then(expression.clone().delimited_by( + just(Token::Control(Control::SquareOpen)), + just(Token::Control(Control::SquareClose)), + )) + .map_with(|(left, right), state| { + Expression::ListIndex( + Box::new(ListIndex::new(left, right)).with_position(state.span()), + ) + }); + let atom = choice(( map_index.clone(), + list_index.clone(), range.clone(), parsed_function.clone(), list.clone(), @@ -358,18 +373,6 @@ pub fn parser<'src>( Expression::Logic(Box::new(Logic::Not(expression)).with_position(span)) }, ), - postfix( - 2, - expression.clone().delimited_by( - just(Token::Control(Control::SquareOpen)), - just(Token::Control(Control::SquareClose)), - ), - |left, right, span| { - Expression::ListIndex( - Box::new(ListIndex::new(left, right)).with_position(span), - ) - }, - ), postfix( 3, turbofish.clone().or_not().then( @@ -499,6 +502,7 @@ pub fn parser<'src>( choice(( logic_math_indexes_and_function_calls, + list_index, map_index, built_in_function_call, range, diff --git a/dust-shell/Cargo.toml b/dust-shell/Cargo.toml index e452d03..a11bc29 100644 --- a/dust-shell/Cargo.toml +++ b/dust-shell/Cargo.toml @@ -14,5 +14,6 @@ clap = { version = "4.5.3", features = ["derive"] } colored = "2.1.0" dust-lang = { path = "../dust-lang" } env_logger = "0.11.3" +log = "0.4.21" nu-ansi-term = "0.50.0" reedline = { version = "0.30.0", features = ["sqlite", "system_clipboard"] } diff --git a/dust-shell/src/main.rs b/dust-shell/src/main.rs index 6ccbd47..376e1e0 100644 --- a/dust-shell/src/main.rs +++ b/dust-shell/src/main.rs @@ -5,6 +5,7 @@ use ariadne::sources; use clap::Parser; use cli::run_shell; use colored::Colorize; +use log::Level; use std::{ fs::read_to_string, @@ -33,10 +34,16 @@ fn main() { env_logger::Builder::from_env("DUST_LOG") .format(|buffer, record| { let args = record.args(); - let log_level = record.level().to_string().bold(); + let log_level = match record.level() { + Level::Trace => "TRACE".cyan().bold(), + Level::Warn => "WARN".yellow().bold(), + Level::Debug => "DEBUG".green().bold(), + Level::Error => "ERROR".red().bold(), + Level::Info => "INFO".white().bold(), + }; let timestamp = buffer.timestamp_seconds().to_string().dimmed(); - writeln!(buffer, "[{log_level} {timestamp}] {args}") + writeln!(buffer, "[{} {}] {}", log_level, timestamp, args) }) .init(); diff --git a/examples/json_length.ds b/examples/json_length.ds new file mode 100644 index 0000000..15ee421 --- /dev/null +++ b/examples/json_length.ds @@ -0,0 +1,9 @@ +/* + This is is simple program to get the length of a json array. + + Use `cargo run --package dust-shell examples/json_length.ds` +*/ +input = fs.read_file('examples/assets/data.json') +data = json.parse(input) + +list.length(data)