diff --git a/CHANGELOG.md b/CHANGELOG.md index d37c0a3..35aa9ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.0] - 2023-10-18 + +### Added + +- `while` and `until` loops +- `==`, `>` and `<` compare operators +- `+=`, `-=`, `*=` and `/=` "operate and assign" operators +- Functions now say their name on error. + ## [0.6.1] - 2023-10-14 ### Fixed @@ -77,7 +86,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.6.1...HEAD +[unreleased]: https://github.com/ArnabRollin/dwn/compare/v0.7.0...HEAD + +[0.7.0]: https://github.com/ArnabRollin/dwn/compare/v0.6.1...v0.7.0 [0.6.1]: https://github.com/ArnabRollin/dwn/compare/v0.6.0...v0.6.1 diff --git a/Cargo.lock b/Cargo.lock index cb81d64..b8c7ff6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "dwn" -version = "0.6.1" +version = "0.7.0" dependencies = [ "lazy_static", ] diff --git a/Cargo.toml b/Cargo.toml index 9d82af3..e4a824f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dwn" -version = "0.6.1" +version = "0.7.0" edition = "2021" [dependencies] diff --git a/src/dwn.rs b/src/dwn.rs index 7edbf62..dd1a952 100644 --- a/src/dwn.rs +++ b/src/dwn.rs @@ -73,6 +73,42 @@ lazy_static! { "if", if_ as for<'a> fn(Vec, &'a mut Metadata) -> Result, ); + m.insert( + "while", + while_ as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "until", + until as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "eq", + eq as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "gt", + gt as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "lt", + lt as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "add_assign", + add_assign as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "subtract_assign", + subtract_assign as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "multiply_assign", + multiply_assign as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); + m.insert( + "divide_assign", + divide_assign as for<'a> fn(Vec, &'a mut Metadata) -> Result, + ); RwLock::new(m) }; @@ -297,7 +333,7 @@ fn ask(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); if args.len() < 1 { - return Err("Not enough arguments!".to_string()); + return Err("(ask) Not enough arguments!".to_string()); } let mut input = String::new(); @@ -335,6 +371,10 @@ fn create_var(tokens: Vec, meta: &mut Metadata) -> Result let var_name = args[0].val.to_string(); let var_value = args[1].val.to_string(); + if args.len() < 1 { + return Err("(let) Not enough arguments!".to_string()); + } + match args[0].ty { TokenTypes::NONE => return Err(format!("Cannot accept none as variable name!")), _ => {} @@ -365,6 +405,11 @@ fn create_var(tokens: Vec, meta: &mut Metadata) -> Result fn sum(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(+) Not enough arguments!".to_string()); + } + let first = match args[0].ty.clone() { TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), ty => { @@ -402,6 +447,11 @@ fn sum(tokens: Vec, meta: &mut Metadata) -> Result { } fn difference(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(-) Not enough arguments!".to_string()); + } + let first = match args[0].ty.clone() { TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), ty => { @@ -439,6 +489,11 @@ fn difference(tokens: Vec, meta: &mut Metadata) -> Result } fn product(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(*) Not enough arguments!".to_string()); + } + let first = match args[0].ty.clone() { TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), ty => { @@ -476,6 +531,11 @@ fn product(tokens: Vec, meta: &mut Metadata) -> Result { } fn quotient(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(/) Not enough arguments!".to_string()); + } + let first = match args[0].ty.clone() { TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), ty => { @@ -516,7 +576,7 @@ fn forever(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); if args.len() < 1 { - return Err("Not enough arguments!".to_string()); + return Err("(forever) Not enough arguments!".to_string()); } let scope = args[0].clone(); @@ -540,7 +600,7 @@ fn scope(tokens: Vec, meta: &mut Metadata) -> Result { let args = get_args(tokens, meta); if args.len() < 1 { - return Err("Not enough arguments!".to_string()); + return Err("(scope) Not enough arguments!".to_string()); } let scope = args[0].clone(); @@ -575,7 +635,7 @@ 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()); + return Err("(if) Not enough arguments!".to_string()); } let condition = args[0].clone(); @@ -620,3 +680,481 @@ fn if_(tokens: Vec, meta: &mut Metadata) -> Result { val: "None".to_string(), }) } + +fn eq(tokens: Vec, meta: &mut Metadata) -> Result { + let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(==) Not enough arguments!".to_string()); + } + + let first = &args[0]; + let second = &args[1]; + + if first == second { + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "true".to_string(), + }); + } + + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "false".to_string(), + }); +} +fn gt(tokens: Vec, meta: &mut Metadata) -> Result { + let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(>) Not enough arguments!".to_string()); + } + + let first = match args[0].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '>' with type {ty:?}" + )) + } + }; + let second = match args[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => args[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '>' with type {ty:?}" + )) + } + }; + + if first > second { + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "true".to_string(), + }); + } + + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "false".to_string(), + }); +} +fn lt(tokens: Vec, meta: &mut Metadata) -> Result { + let args = get_args(tokens, meta); + + if args.len() < 2 { + return Err("(<) Not enough arguments!".to_string()); + } + + let first = match args[0].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => args[0].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '<' with type {ty:?}" + )) + } + }; + let second = match args[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => args[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '<' with type {ty:?}" + )) + } + }; + + if first < second { + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "true".to_string(), + }); + } + + return Ok(Token { + ty: TokenTypes::BOOL, + modifiers: vec![], + val: "false".to_string(), + }); +} + +fn while_(tokens: Vec, meta: &mut Metadata) -> Result { + loop { + let args = get_args(tokens.clone(), meta); + + if args.len() < 2 { + return Err("(while) 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); + } + } +} + +fn until(tokens: Vec, meta: &mut Metadata) -> Result { + loop { + let args = get_args(tokens.clone(), meta); + + if args.len() < 2 { + return Err("(until) 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 == "true" { + 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); + } + } +} + +fn add_assign(tokens: Vec, _meta: &mut Metadata) -> Result { + if tokens.len() < 2 { + return Err("(+=) Not enough arguments!".to_string()); + } + + let first = match tokens[0].ty.clone() { + TokenTypes::VARIABLE => &tokens[0].val, + ty => { + return Err(format!( + "Invalid type: Cannot use operation '+=' with type {ty:?}" + )) + } + }; + let second = match tokens[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => tokens[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot add thing of type {ty:?} to variable" + )) + } + }; + + let mut variables = VARIABLES.write().unwrap(); + + let variable = variables.get_mut(first); + + let variable = match variable { + Some(v) => v, + None => return Err(format!("Variable `{first}` not found")), + }; + + let value: f32 = match &variable.value.ty { + TokenTypes::INT => variable.value.val.parse().unwrap(), + TokenTypes::FLOAT => variable.value.val.parse().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '+=' with variable of type {ty:?}" + )) + } + }; + + let total = value + second; + + if total.fract() == 0.0 { + let total = total as i32; + + *variable = Variable { + value: Token { + ty: TokenTypes::INT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } else { + *variable = Variable { + value: Token { + ty: TokenTypes::FLOAT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } + + return Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }); +} +fn subtract_assign(tokens: Vec, _meta: &mut Metadata) -> Result { + if tokens.len() < 2 { + return Err("(-=) Not enough arguments!".to_string()); + } + + let first = match tokens[0].ty.clone() { + TokenTypes::VARIABLE => &tokens[0].val, + ty => { + return Err(format!( + "Invalid type: Cannot use operation '-=' with type {ty:?}" + )) + } + }; + let second = match tokens[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => tokens[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot subtract thing of type {ty:?} from variable" + )) + } + }; + + let mut variables = VARIABLES.write().unwrap(); + + let variable = variables.get_mut(first); + + let variable = match variable { + Some(v) => v, + None => return Err(format!("Variable `{first}` not found")), + }; + + let value: f32 = match &variable.value.ty { + TokenTypes::INT => variable.value.val.parse().unwrap(), + TokenTypes::FLOAT => variable.value.val.parse().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '-=' with variable of type {ty:?}" + )) + } + }; + + let total = value - second; + + if total.fract() == 0.0 { + let total = total as i32; + + *variable = Variable { + value: Token { + ty: TokenTypes::INT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } else { + *variable = Variable { + value: Token { + ty: TokenTypes::FLOAT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } + + return Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }); +} + +fn multiply_assign(tokens: Vec, _meta: &mut Metadata) -> Result { + if tokens.len() < 2 { + return Err("(*=) Not enough arguments!".to_string()); + } + + let first = match tokens[0].ty.clone() { + TokenTypes::VARIABLE => &tokens[0].val, + ty => { + return Err(format!( + "Invalid type: Cannot use operation '*=' with type {ty:?}" + )) + } + }; + let second = match tokens[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => tokens[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot multiply thing of type {ty:?} with variable" + )) + } + }; + + let mut variables = VARIABLES.write().unwrap(); + + let variable = variables.get_mut(first); + + let variable = match variable { + Some(v) => v, + None => return Err(format!("Variable `{first}` not found")), + }; + + let value: f32 = match &variable.value.ty { + TokenTypes::INT => variable.value.val.parse().unwrap(), + TokenTypes::FLOAT => variable.value.val.parse().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '*=' with variable of type {ty:?}" + )) + } + }; + + let total = value * second; + + if total.fract() == 0.0 { + let total = total as i32; + + *variable = Variable { + value: Token { + ty: TokenTypes::INT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } else { + *variable = Variable { + value: Token { + ty: TokenTypes::FLOAT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } + + return Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }); +} + +fn divide_assign(tokens: Vec, _meta: &mut Metadata) -> Result { + if tokens.len() < 2 { + return Err("(/=) Not enough arguments!".to_string()); + } + + let first = match tokens[0].ty.clone() { + TokenTypes::VARIABLE => &tokens[0].val, + ty => { + return Err(format!( + "Invalid type: Cannot use operation '/=' with type {ty:?}" + )) + } + }; + let second = match tokens[1].ty.clone() { + TokenTypes::INT | TokenTypes::FLOAT => tokens[1].val.parse::().unwrap(), + ty => { + return Err(format!( + "Invalid type: Variable cannot be divided by thing of type {ty:?}" + )) + } + }; + + let mut variables = VARIABLES.write().unwrap(); + + let variable = variables.get_mut(first); + + let variable = match variable { + Some(v) => v, + None => return Err(format!("Variable `{first}` not found")), + }; + + let value: f32 = match &variable.value.ty { + TokenTypes::INT => variable.value.val.parse().unwrap(), + TokenTypes::FLOAT => variable.value.val.parse().unwrap(), + ty => { + return Err(format!( + "Invalid type: Cannot use operation '/=' with variable of type {ty:?}" + )) + } + }; + + let total = value / second; + + if total.fract() == 0.0 { + let total = total as i32; + + *variable = Variable { + value: Token { + ty: TokenTypes::INT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } else { + *variable = Variable { + value: Token { + ty: TokenTypes::FLOAT, + modifiers: variable.value.modifiers.clone(), + val: total.to_string(), + }, + scope: variable.scope, + }; + } + + return Ok(Token { + ty: TokenTypes::NONE, + modifiers: vec![], + val: "None".to_string(), + }); +} diff --git a/src/lexer.rs b/src/lexer.rs index 9a845c9..cdf2b99 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -67,6 +67,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { let mut string_token = String::new(); let mut in_variable_set = false; let mut in_operator = false; + let mut in_compare = false; let mut literal = String::new(); let mut in_literal = false; @@ -99,7 +100,6 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { exit(1); } } - return tokens; } else { meta.scope_token.push_str(&data); @@ -135,7 +135,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { tokens.push(Token { ty: TokenTypes::LITERAL, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -156,7 +156,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::NONE, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -170,7 +170,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::BOOL, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -184,7 +184,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::BOOL, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -216,7 +216,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal && !in_string { tokens.push(Token { ty: TokenTypes::VARIABLE, - modifiers: if in_func || in_operator { + modifiers: if in_func || in_operator || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -228,6 +228,100 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { continue; } + if word == "==" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No first value for comparison operator '==' !", + meta.line_count + ); + exit(1); + } + }; + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "eq".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_compare = true; + }; + + continue; + } + if word == ">" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No first value for comparison operator '>' !", + meta.line_count + ); + exit(1); + } + }; + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "gt".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + if word == "<" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No first value for comparison operator '<' !", + meta.line_count + ); + exit(1); + } + }; + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "lt".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + if word == "+" && !in_string { if !in_literal { let first = tokens.pop(); @@ -397,11 +491,183 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { continue; } + if word == "+=" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No variable for operator '+=' !", + meta.line_count + ); + exit(1); + } + }; + + match first.ty { + TokenTypes::VARIABLE => {} + _ => { + eprintln!( + "Error on line {}: No variable for operator '+=' !", + meta.line_count + ); + exit(1); + } + } + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "add_assign".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + + if word == "-=" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No variable for operator '-=' !", + meta.line_count + ); + exit(1); + } + }; + + match first.ty { + TokenTypes::VARIABLE => {} + _ => { + eprintln!( + "Error on line {}: No variable for operator '-=' !", + meta.line_count + ); + exit(1); + } + } + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "subtract_assign".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + + if word == "*=" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No variable for operator '*=' !", + meta.line_count + ); + exit(1); + } + }; + + match first.ty { + TokenTypes::VARIABLE => {} + _ => { + eprintln!( + "Error on line {}: No variable for operator '*=' !", + meta.line_count + ); + exit(1); + } + } + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "multiply_assign".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + + if word == "/=" && !in_string { + if !in_literal { + let first = tokens.pop(); + + let first = match first { + Some(token) => token, + None => { + eprintln!( + "Error on line {}: No variable for operator '/=' !", + meta.line_count + ); + exit(1); + } + }; + + match first.ty { + TokenTypes::VARIABLE => {} + _ => { + eprintln!( + "Error on line {}: No variable for operator '/=' !", + meta.line_count + ); + exit(1); + } + } + + tokens.push(Token { + ty: TokenTypes::FUNC, + modifiers: vec![], + val: "divide_assign".to_string(), + }); + + tokens.push(Token { + modifiers: vec![TokenModifiers::ARGS], + ..first + }); + + in_operator = true; + }; + + continue; + } + if word.parse::().is_ok() && !in_string { if !in_literal { tokens.push(Token { ty: TokenTypes::INT, - modifiers: if in_func || in_operator { + modifiers: if in_func || in_operator || in_compare { if in_operator { in_operator = false; } @@ -421,7 +687,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::FLOAT, - modifiers: if in_func || in_operator { + modifiers: if in_func || in_operator || in_compare { if in_operator { in_operator = false; } @@ -452,7 +718,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::STRING, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -476,7 +742,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::STRING, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -502,7 +768,7 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { if !in_literal { tokens.push(Token { ty: TokenTypes::STRING, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] @@ -541,11 +807,11 @@ pub fn tokenize(data: String, meta: &mut Metadata) -> Vec { continue; } - if !in_string && in_func { + if !in_string { if !in_literal { tokens.push(Token { ty: TokenTypes::NAME, - modifiers: if in_func { + modifiers: if in_func || in_compare { vec![TokenModifiers::ARGS] } else { vec![] diff --git a/src/main.rs b/src/main.rs index e83edd4..e035473 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.6.1"); + println!("0.7.0"); exit(0); }