From f3b78e74f28a14ce583825a6caaae0fd2808cb6a Mon Sep 17 00:00:00 2001 From: PaddiM8 Date: Thu, 18 Jun 2020 16:58:01 +0200 Subject: [PATCH] Created unit convertion expression. Syntax: to --- kalk/src/interpreter.rs | 9 +++++++++ kalk/src/inverter.rs | 4 +++- kalk/src/parser.rs | 20 ++++++++++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/kalk/src/interpreter.rs b/kalk/src/interpreter.rs index cdd53cd..51433f1 100644 --- a/kalk/src/interpreter.rs +++ b/kalk/src/interpreter.rs @@ -87,6 +87,15 @@ fn eval_binary_expr( right_expr: &Expr, unit: &str, ) -> Result<(Float, String), CalcError> { + if let TokenKind::ToKeyword = op { + // TODO: When the unit conversion function takes a Float instead of Expr, + // move this to the match statement further down. + if let Expr::Var(right_unit) = right_expr { + let (_, left_unit) = eval_expr(context, left_expr, "")?; + return convert_unit(context, left_expr, &left_unit, &right_unit); // TODO: Avoid evaluating this twice. + } + } + let (left, left_unit) = eval_expr(context, left_expr, "")?; let (right, _) = if left_unit.len() > 0 { let (_, right_unit) = eval_expr(context, right_expr, "")?; // TODO: Avoid evaluating this twice. diff --git a/kalk/src/inverter.rs b/kalk/src/inverter.rs index bfced60..e62491b 100644 --- a/kalk/src/inverter.rs +++ b/kalk/src/inverter.rs @@ -194,7 +194,9 @@ fn invert_var( symbol_table: &mut SymbolTable, identifier: &str, ) -> Result<(Expr, Expr), CalcError> { - if let Some(Stmt::VarDecl(_, var_expr)) = symbol_table.get_var(identifier).cloned() { + if identifier == DECL_UNIT { + Ok((target_expr, Expr::Var(identifier.into()))) + } else if let Some(Stmt::VarDecl(_, var_expr)) = symbol_table.get_var(identifier).cloned() { invert(target_expr, symbol_table, &var_expr) } else { Ok((target_expr, Expr::Var(identifier.into()))) diff --git a/kalk/src/parser.rs b/kalk/src/parser.rs index 84aef27..7ad16e3 100644 --- a/kalk/src/parser.rs +++ b/kalk/src/parser.rs @@ -95,6 +95,8 @@ pub fn eval( pub fn parse(context: &mut Context, input: &str) -> Result, CalcError> { context.tokens = Lexer::lex(input); context.pos = 0; + context.parsing_unit_decl = false; + context.unit_decl_base_unit = None; let mut statements: Vec = Vec::new(); while !is_at_end(context) { @@ -171,7 +173,8 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result { let identifier = advance(context).clone(); consume(context, TokenKind::Equals)?; - // Parse the definition + // Parse the mut definition + context.unit_decl_base_unit = None; context.parsing_unit_decl = true; let def = parse_expr(context)?; context.parsing_unit_decl = false; @@ -199,7 +202,20 @@ fn parse_unit_decl_stmt(context: &mut Context) -> Result { } fn parse_expr(context: &mut Context) -> Result { - Ok(parse_sum(context)?) + Ok(parse_to(context)?) +} + +fn parse_to(context: &mut Context) -> Result { + let left = parse_sum(context)?; + + if match_token(context, TokenKind::ToKeyword) { + let op = advance(context).kind.clone(); + let right = Expr::Var(advance(context).value.clone()); // Parse this as a variable for now. + + return Ok(Expr::Binary(Box::new(left), op, Box::new(right))); + } + + Ok(left) } fn parse_sum(context: &mut Context) -> Result {