From fd29ece7bfea02629407f81ec6757df087f381d6 Mon Sep 17 00:00:00 2001 From: ArnabRollin Date: Sat, 14 Oct 2023 14:27:50 +0530 Subject: [PATCH] Added boolean type and `if`, fixed bugs --- CHANGELOG.md | 15 ++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- src/dwn.rs | 57 +++++++++++++++++++++++++- src/idle.rs | 6 +-- src/interpreter.rs | 6 +-- src/lexer.rs | 100 ++++++++++++++++++++++++++++----------------- src/main.rs | 2 +- src/runner.rs | 3 +- 9 files changed, 139 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 798ed13..81a0ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.6.0] - 2023-10-14 + +### Added + +- Boolean type (`true` and `false`) +- `if` function + +### Fixed + +- Fixed bug where two arguments cannot be provided to scope-accepting function. + ## [0.5.0] - 2023-10-13 ### Changed @@ -60,7 +71,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Simple function and string parsing -[unreleased]: https://github.com/ArnabRollin/dwn/compare/v0.5.0...HEAD +[unreleased]: https://github.com/ArnabRollin/dwn/compare/v0.6.0...HEAD + +[0.6.0]: https://github.com/ArnabRollin/dwn/compare/v0.5.0...v0.6.0 [0.5.0]: https://github.com/ArnabRollin/dwn/compare/v0.4.0...v0.5.0 diff --git a/Cargo.lock b/Cargo.lock index 5c56189..bb529be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "dwn" -version = "0.4.0" +version = "0.6.0" dependencies = [ "lazy_static", ] diff --git a/Cargo.toml b/Cargo.toml index b7f1783..3e4956e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dwn" -version = "0.4.0" +version = "0.6.0" edition = "2021" [dependencies] diff --git a/src/dwn.rs b/src/dwn.rs index fbe26ae..7edbf62 100644 --- a/src/dwn.rs +++ b/src/dwn.rs @@ -23,8 +23,7 @@ pub struct Metadata<'a> { pub scope: &'a mut u32, pub in_scope: &'a mut bool, pub scope_token: &'a mut String, - pub in_func: &'a mut bool, - pub func_token: &'a mut String, + pub current_tokens: &'a mut Vec, } lazy_static! { @@ -70,6 +69,10 @@ lazy_static! { "scope", scope as for<'a> fn(Vec, &'a mut Metadata) -> Result, ); + m.insert( + "if", + if_ as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); RwLock::new(m) }; @@ -567,3 +570,53 @@ fn scope(tokens: Vec, meta: &mut Metadata) -> Result { val: "None".to_string(), }) } + +fn if_(tokens: Vec, meta: &mut Metadata) -> Result { + let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("Not enough arguments!".to_string()); + } + + let condition = args[0].clone(); + + let result = match condition.ty { + TokenTypes::BOOL => condition.val, + ty => return Err(format!("Type {ty:?} cannot be used as condition!")), + }; + + if result == "false" { + return Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }); + } + + let scope = args[1].clone(); + *meta.scope += 1; + + for line in scope.val.lines() { + run(line.to_string(), get_funcs(), meta); + } + + *meta.scope -= 1; + let mut drop_vars: Vec = vec![]; + let mut variables = VARIABLES.write().unwrap(); + + for (k, v) in variables.clone() { + if v.scope == *meta.scope + 1 { + drop_vars.push(k); + } + } + + for k in drop_vars { + variables.remove(&k); + } + + Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }) +} diff --git a/src/idle.rs b/src/idle.rs index e78d074..f9ceda6 100644 --- a/src/idle.rs +++ b/src/idle.rs @@ -16,8 +16,7 @@ pub fn idle() { let mut scope = 0; let mut in_scope = false; let mut scope_token = String::new(); - let mut in_func = false; - let mut func_token = String::new(); + let mut current_tokens = vec![]; loop { let mut code = String::new(); @@ -53,8 +52,7 @@ pub fn idle() { scope: &mut scope, in_scope: &mut in_scope, scope_token: &mut scope_token, - in_func: &mut in_func, - func_token: &mut func_token, + current_tokens: &mut current_tokens, }, ); diff --git a/src/interpreter.rs b/src/interpreter.rs index 9a565f3..a54d1f3 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -23,8 +23,7 @@ pub fn interpret_file(file: Option<&String>) { let mut scope = 0; let mut in_scope = false; let mut scope_token = String::new(); - let mut in_func = false; - let mut func_token = String::new(); + let mut current_tokens = vec![]; for (count, line) in reader.lines().enumerate() { let line = remove_all_after(line.unwrap(), ';'); @@ -37,8 +36,7 @@ pub fn interpret_file(file: Option<&String>) { scope: &mut scope, in_scope: &mut in_scope, scope_token: &mut scope_token, - in_func: &mut in_func, - func_token: &mut func_token, + current_tokens: &mut current_tokens, }, ); } diff --git a/src/lexer.rs b/src/lexer.rs index bf80176..0bed53c 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -16,6 +16,7 @@ pub enum TokenTypes { NAME, SCOPE, NONE, + BOOL, } /// The token modifiers. @@ -79,30 +80,27 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { let scope_token = meta.scope_token.to_string(); meta.scope_token.clear(); - return vec![ - Token { - ty: TokenTypes::FUNC, - modifiers: vec![], - val: if *meta.in_func { - (*meta.func_token).to_string() - } else { - eprintln!( - "Error on line {}: No function found to run scope!", - meta.line_count - ); - exit(1); - }, - }, - Token { + let mut tokens: Vec = vec![]; + for t in meta.current_tokens.clone() { + tokens.push(t); + } + + match meta.current_tokens[0].ty { + TokenTypes::FUNC => tokens.push(Token { ty: TokenTypes::SCOPE, - modifiers: if *meta.in_func { - vec![TokenModifiers::ARGS] - } else { - vec![] - }, - val: (scope_token).to_string(), - }, - ]; + modifiers: vec![TokenModifiers::ARGS], + val: scope_token, + }), + _ => { + eprintln!( + "Error on line {}: No function found to run scope!", + meta.line_count + ); + exit(1); + } + } + + return tokens; } else { meta.scope_token.push_str(&data); meta.scope_token.push('\n'); @@ -155,15 +153,45 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { } if word == "None" && !in_string { - tokens.push(Token { - ty: TokenTypes::NONE, - modifiers: if in_func { - vec![TokenModifiers::ARGS] - } else { - vec![] - }, - val: "None".to_string(), - }); + if !in_literal { + tokens.push(Token { + ty: TokenTypes::NONE, + modifiers: if in_func { + vec![TokenModifiers::ARGS] + } else { + vec![] + }, + val: "None".to_string(), + }); + } + continue; + } + if word == "true" && !in_string { + if !in_literal { + tokens.push(Token { + ty: TokenTypes::BOOL, + modifiers: if in_func { + vec![TokenModifiers::ARGS] + } else { + vec![] + }, + val: "true".to_string(), + }); + } + continue; + } + if word == "false" && !in_string { + if !in_literal { + tokens.push(Token { + ty: TokenTypes::BOOL, + modifiers: if in_func { + vec![TokenModifiers::ARGS] + } else { + vec![] + }, + val: "false".to_string(), + }); + } continue; } @@ -413,10 +441,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { *meta.scope += 1; *meta.in_scope = true; - if in_func { - *meta.in_func = true; - *meta.func_token = tokens.last().unwrap().val.to_string(); - } + *meta.current_tokens = tokens.clone(); continue; } @@ -545,8 +570,7 @@ fn tokenizer() { scope: &mut 0, in_scope: &mut false, scope_token: &mut String::new(), - in_func: &mut false, - func_token: &mut String::new(), + current_tokens: &mut vec![], }, ); diff --git a/src/main.rs b/src/main.rs index b0d930b..7c4bbf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,7 @@ fn main() { if arguments.options.contains(&"version".to_string()) || arguments.flags.contains(&"v".to_string()) { - println!("0.4.0"); + println!("0.6.0"); exit(0); } diff --git a/src/runner.rs b/src/runner.rs index ddbe844..702b5a2 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -101,8 +101,7 @@ fn line_runner() { scope: &mut 0, in_scope: &mut false, scope_token: &mut String::new(), - in_func: &mut false, - func_token: &mut String::new(), + current_tokens: &mut vec![], }, );