microcad_lang/parse/
literal.rs1use microcad_core::Integer;
5
6use crate::{parse::*, parser::*, syntax::*};
7
8impl Parse for Refer<Integer> {
9 fn parse(pair: Pair) -> ParseResult<Self> {
10 Ok(Refer::new(pair.as_str().parse::<i64>()?, pair.into()))
11 }
12}
13
14impl Parse for Literal {
15 fn parse(pair: Pair) -> ParseResult<Self> {
16 Parser::ensure_rule(&pair, Rule::literal);
17
18 let inner = pair.inner().next().expect(INTERNAL_PARSE_ERROR);
19
20 let s = match inner.as_rule() {
21 Rule::number_literal => Literal::Number(NumberLiteral::parse(inner)?),
22 Rule::integer_literal => Literal::Integer(Refer::<Integer>::parse(inner)?),
23 Rule::bool_literal => match inner.as_str() {
24 "true" => Literal::Bool(Refer::new(true, pair.into())),
25 "false" => Literal::Bool(Refer::new(false, pair.into())),
26 _ => unreachable!(),
27 },
28 _ => unreachable!(),
29 };
30
31 Ok(s)
32 }
33}
34
35impl std::str::FromStr for Literal {
36 type Err = ParseError;
37
38 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
39 Parser::parse_rule::<Self>(Rule::literal, s, 0)
40 }
41}
42
43impl Parse for NumberLiteral {
44 fn parse(pair: Pair) -> ParseResult<Self> {
45 Parser::ensure_rule(&pair, Rule::number_literal);
46
47 let mut inner = pair.inner();
48 let number_token = inner.next().expect("Expected number token");
49
50 assert!(
51 number_token.as_rule() == Rule::number
52 || number_token.as_rule() == Rule::integer_literal
53 );
54
55 let value = number_token.as_str().parse::<f64>()?;
56
57 let mut unit = Unit::None;
58
59 if let Some(unit_token) = inner.next() {
60 unit = Unit::parse(unit_token)?;
61 }
62 Ok(NumberLiteral(value, unit, pair.clone().into()))
63 }
64}
65
66impl std::str::FromStr for NumberLiteral {
67 type Err = ParseError;
68
69 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
70 Parser::parse_rule(Rule::number_literal, s, 0)
71 }
72}
73
74impl Parse for Unit {
75 fn parse(pair: Pair) -> ParseResult<Self> {
76 use std::str::FromStr;
77 match Unit::from_str(pair.as_str()) {
78 Ok(unit) => Ok(unit),
79 Err(_) => Err(ParseError::UnknownUnit(pair.as_str().to_string())),
80 }
81 }
82}
83
84impl std::str::FromStr for Unit {
85 type Err = ParseError;
86 fn from_str(s: &str) -> Result<Self, Self::Err> {
87 match s {
88 "" => Ok(Self::None),
90 "%" => Ok(Self::Percent),
91
92 "m" => Ok(Self::Meter),
94 "cm" => Ok(Self::Centimeter),
95 "mm" => Ok(Self::Millimeter),
96 "µm" => Ok(Self::Micrometer),
97 "in" => Ok(Self::Inch),
98 "\"" => Ok(Self::Inch),
99 "ft" => Ok(Self::Foot),
100 "\'" => Ok(Self::Foot),
101 "yd" => Ok(Self::Yard),
102
103 "deg" => Ok(Self::Deg),
105 "°" => Ok(Self::DegS),
106 "grad" => Ok(Self::Grad),
107 "turns" => Ok(Self::Turns),
108 "rad" => Ok(Self::Rad),
109
110 "g" => Ok(Self::Gram),
112 "kg" => Ok(Self::Kilogram),
113 "lb" => Ok(Self::Pound),
114 "oz" => Ok(Self::Ounce),
115
116 "m²" | "m2" => Ok(Self::Meter2),
118 "cm²" | "cm2" => Ok(Self::Centimeter2),
119 "mm²" | "mm2" => Ok(Self::Millimeter2),
120 "µm²" | "µm2" => Ok(Self::Micrometer2),
121 "in²" | "in2" => Ok(Self::Inch2),
122 "ft²" | "ft2" => Ok(Self::Foot2),
123 "yd²" | "yd2" => Ok(Self::Yard2),
124
125 "m³" | "m3" => Ok(Self::Meter3),
127 "cm³" | "cm3" => Ok(Self::Centimeter3),
128 "mm³" | "mm3" => Ok(Self::Millimeter3),
129 "µm³" | "µm3" => Ok(Self::Micrometer3),
130 "in³" | "in3" => Ok(Self::Inch3),
131 "ft³" | "ft3" => Ok(Self::Foot3),
132 "yd³" | "yd3" => Ok(Self::Yard3),
133 "ml" => Ok(Self::Milliliter),
134 "cl" => Ok(Self::Centiliter),
135 "l" => Ok(Self::Liter),
136 "µl" => Ok(Self::Microliter),
137
138 "g/mm³" => Ok(Self::GramPerMillimeter3),
139 "g/m³" => Ok(Self::GramPerMeter3),
140
141 _ => Err(ParseError::UnknownUnit(s.to_string())),
143 }
144 }
145}