smartcalc/syntax/
primative.rs

1/*
2 * smartcalc v1.0.8
3 * Copyright (c) Erhan BARIS (Ruslan Ognyanov Asenov)
4 * Licensed under the GNU General Public License v2.0.
5 */
6
7
8use alloc::rc::Rc;
9
10use crate::compiler::date::DateItem;
11use crate::compiler::date_time::DateTimeItem;
12use crate::compiler::duration::DurationItem;
13use crate::compiler::money::MoneyItem;
14use crate::compiler::dynamic_type::DynamicTypeItem;
15use crate::compiler::number::NumberItem;
16use crate::compiler::percent::PercentItem;
17use crate::compiler::time::TimeItem;
18use crate::types::*;
19use crate::syntax::util::*;
20use crate::syntax::{SyntaxParser, SyntaxParserTrait};
21use crate::syntax::binary::AddSubtractParser;
22use core::ops::Deref;
23
24pub struct PrimativeParser;
25
26impl PrimativeParser {
27    pub fn parse_basic_primatives(parser: &mut SyntaxParser) -> AstResult {
28        let index_backup = parser.get_index();
29        let token = parser.peek_token();
30
31        if token.is_err() {
32            return Err(("No more token", 0, 0));
33        }
34
35        let result = match token.unwrap().deref() {
36            TokenType::Timezone(_, _) |
37            TokenType::Text(_)   => {
38                parser.consume_token();
39                return Ok(SmartCalcAstType::None);
40            },
41            TokenType::DynamicType(number, dynamic_type)     => Ok(SmartCalcAstType::Item(Rc::new(DynamicTypeItem(*number, dynamic_type.clone())))),
42            TokenType::Money(price, currency)     => Ok(SmartCalcAstType::Item(Rc::new(MoneyItem(*price, currency.clone())))),
43            TokenType::Number(double, number_type)     => Ok(SmartCalcAstType::Item(Rc::new(NumberItem(*double, *number_type)))),
44            TokenType::Field(field_type)  => Ok(SmartCalcAstType::Field(field_type.clone())),
45            TokenType::Percent(percent)   => Ok(SmartCalcAstType::Item(Rc::new(PercentItem(*percent)))),
46            TokenType::Time(time, tz)         => Ok(SmartCalcAstType::Item(Rc::new(TimeItem(*time, tz.clone())))),
47            TokenType::Date(date, tz)         => Ok(SmartCalcAstType::Item(Rc::new(DateItem(*date, tz.clone())))),
48            TokenType::DateTime(date_time, tz)         => Ok(SmartCalcAstType::Item(Rc::new(DateTimeItem(*date_time, tz.clone())))),
49            TokenType::Duration(duration)         => Ok(SmartCalcAstType::Item(Rc::new(DurationItem(*duration)))),
50            TokenType::Variable(variable) => Ok(SmartCalcAstType::Variable(variable.clone())),
51            _ => {
52                parser.consume_token();
53                return Err(("No more token", 0, 0));
54            }
55        };
56
57        match result {
58            Ok(SmartCalcAstType::None) => {
59                parser.set_index(index_backup);
60                Ok(SmartCalcAstType::None)
61            },
62            Ok(ast) => {
63                parser.consume_token();
64                Ok(ast)
65            },
66            Err((message, line, column)) => Err((message, line, column))
67        }
68    }
69
70    pub fn parse_parenthesis(parser: &mut SyntaxParser) -> AstResult {
71        let index_backup = parser.get_index();
72        if parser.match_operator(&['(']).is_some() {
73            
74            let ast = AddSubtractParser::parse(parser);
75            if is_ast_empty(&ast) {
76                parser.set_index(index_backup);
77                return err_or_message(&ast, "Invalid expression");
78            }
79
80            if parser.match_operator(&[')']).is_none() {
81                parser.set_index(index_backup);
82                return Err(("Parentheses not closed", 0, 0));
83            }
84
85            return Ok(ast.unwrap());
86        }
87
88        parser.set_index(index_backup);
89        Ok(SmartCalcAstType::None)
90    }
91}
92
93impl SyntaxParserTrait for PrimativeParser {
94    fn parse(parser: &mut SyntaxParser) -> AstResult {
95        map_parser(parser, &[Self::parse_parenthesis, Self::parse_basic_primatives])
96    }
97}