Skip to main content

rink_core/ast/
mod.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Abstract syntax tree for rink's query language.
6
7use crate::output::Digits;
8use crate::types::Numeric;
9use serde_derive::Serialize;
10use std::fmt;
11
12mod def;
13mod expr;
14mod query;
15
16pub use def::{DateMatch, DatePattern, Def, DefEntry, Defs, ExprString, Property};
17pub use expr::{Expr, Precedence};
18pub use query::{Conversion, Query};
19
20#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
21#[serde(rename_all = "camelCase")]
22pub enum Degree {
23    Celsius,
24    Fahrenheit,
25    Reaumur,
26    Romer,
27    Delisle,
28    Newton,
29}
30
31#[derive(Debug, Clone, Serialize, PartialEq)]
32pub enum DateToken {
33    Literal(String),
34    Number(String, Option<String>),
35    Colon,
36    Dash,
37    Space,
38    Plus,
39    Error(String),
40}
41
42#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
43#[serde(rename_all = "camelCase")]
44pub enum BinOpType {
45    Add,
46    Sub,
47    Frac,
48    Pow,
49    Equals,
50    ShiftL,
51    ShiftR,
52    Mod,
53    And,
54    Or,
55    Xor,
56}
57
58impl BinOpType {
59    pub fn symbol(self) -> &'static str {
60        match self {
61            BinOpType::Add => " + ",
62            BinOpType::Sub => " - ",
63            BinOpType::Frac => " / ",
64            BinOpType::Pow => "^",
65            BinOpType::Equals => " = ",
66            BinOpType::ShiftL => " << ",
67            BinOpType::ShiftR => " >> ",
68            BinOpType::Mod => " mod ",
69            BinOpType::And => " and ",
70            BinOpType::Or => " or ",
71            BinOpType::Xor => " xor ",
72        }
73    }
74}
75
76#[derive(Debug, Clone, Serialize, PartialEq)]
77pub struct BinOpExpr {
78    pub op: BinOpType,
79    pub left: Box<Expr>,
80    pub right: Box<Expr>,
81}
82
83#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
84#[serde(rename_all = "camelCase")]
85#[serde(untagged)]
86pub enum UnaryOpType {
87    Negative,
88    Positive,
89    Degree(Degree),
90}
91
92#[derive(Debug, Clone, Serialize, PartialEq)]
93pub struct UnaryOpExpr {
94    pub op: UnaryOpType,
95    pub expr: Box<Expr>,
96}
97
98#[derive(Debug, Clone, Copy, Serialize, PartialEq)]
99#[serde(rename_all = "camelCase")]
100pub enum Function {
101    Sqrt,
102    Exp,
103    Ln,
104    Log2,
105    Log10,
106    Sin,
107    Cos,
108    Tan,
109    Asin,
110    Acos,
111    Atan,
112    Sinh,
113    Cosh,
114    Tanh,
115    Asinh,
116    Acosh,
117    Atanh,
118    Log,
119    Hypot,
120    Atan2,
121    Fac,
122}
123
124impl Function {
125    pub fn name(&self) -> &str {
126        match *self {
127            Function::Sqrt => "sqrt",
128            Function::Exp => "exp",
129            Function::Ln => "ln",
130            Function::Log2 => "log2",
131            Function::Log10 => "log10",
132            Function::Sin => "sin",
133            Function::Cos => "cos",
134            Function::Tan => "tan",
135            Function::Asin => "asin",
136            Function::Acos => "acos",
137            Function::Atan => "atan",
138            Function::Sinh => "sinh",
139            Function::Cosh => "cosh",
140            Function::Tanh => "tanh",
141            Function::Asinh => "asinh",
142            Function::Acosh => "acosh",
143            Function::Atanh => "atanh",
144            Function::Log => "log",
145            Function::Hypot => "hypot",
146            Function::Atan2 => "atan2",
147            Function::Fac => "fac",
148        }
149    }
150
151    pub fn from_name(s: &str) -> Option<Self> {
152        let func = match s {
153            "sqrt" => Function::Sqrt,
154            "exp" => Function::Exp,
155            "ln" => Function::Ln,
156            "log2" => Function::Log2,
157            "log10" => Function::Log10,
158            "sin" => Function::Sin,
159            "cos" => Function::Cos,
160            "tan" => Function::Tan,
161            "asin" => Function::Asin,
162            "acos" => Function::Acos,
163            "atan" => Function::Atan,
164            "sinh" => Function::Sinh,
165            "cosh" => Function::Cosh,
166            "tanh" => Function::Tanh,
167            "asinh" => Function::Asinh,
168            "acosh" => Function::Acosh,
169            "atanh" => Function::Atanh,
170            "log" => Function::Log,
171            "hypot" => Function::Hypot,
172            "atan2" => Function::Atan2,
173            "fac" => Function::Fac,
174            _ => return None,
175        };
176        Some(func)
177    }
178}
179
180impl fmt::Display for Degree {
181    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
182        write!(fmt, "{}", self.as_str())
183    }
184}
185
186impl Degree {
187    pub fn as_str(&self) -> &'static str {
188        match *self {
189            Degree::Celsius => "°C",
190            Degree::Fahrenheit => "°F",
191            Degree::Newton => "°N",
192            Degree::Reaumur => "°Ré",
193            Degree::Romer => "°Rø",
194            Degree::Delisle => "°De",
195        }
196    }
197
198    pub fn name_base_scale(&self) -> (&str, &str, &str) {
199        match *self {
200            Degree::Celsius => ("C", "zerocelsius", "kelvin"),
201            Degree::Fahrenheit => ("F", "zerofahrenheit", "degrankine"),
202            Degree::Reaumur => ("Ré", "zerocelsius", "reaumur_absolute"),
203            Degree::Romer => ("Rø", "zeroromer", "romer_absolute"),
204            Degree::Delisle => ("De", "zerodelisle", "delisle_absolute"),
205            Degree::Newton => ("N", "zerocelsius", "newton_absolute"),
206        }
207    }
208}
209
210impl fmt::Display for DateToken {
211    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
212        match *self {
213            DateToken::Literal(ref l) => write!(fmt, "{}", l),
214            DateToken::Number(ref i, None) => write!(fmt, "{}", i),
215            DateToken::Number(ref i, Some(ref f)) => write!(fmt, "{}.{}", i, f),
216            DateToken::Colon => write!(fmt, ":"),
217            DateToken::Dash => write!(fmt, "-"),
218            DateToken::Space => write!(fmt, " "),
219            DateToken::Plus => write!(fmt, "+"),
220            DateToken::Error(ref e) => write!(fmt, "<{}>", e),
221        }
222    }
223}