浏览代码

Initial support for multiline statements, see #112

David Peter 2 年之前
父节点
当前提交
eae4c53fd9
共有 6 个文件被更改,包括 36 次插入17 次删除
  1. 2 1
      examples/barometric_formula.nbt
  2. 1 1
      examples/earth_mass.nbt
  3. 2 1
      examples/pendulum.nbt
  4. 2 1
      examples/stopping_distance.nbt
  5. 22 12
      examples/what_if_158.nbt
  6. 7 1
      numbat/src/parser.rs

+ 2 - 1
examples/barometric_formula.nbt

@@ -3,6 +3,7 @@ let t0: Temperature = 288.15 K
 
 let temperature_gradient = 0.65 K / 100 m
 
-fn air_pressure(height: Length) -> Pressure = p0 · (1 - temperature_gradient · height / t0)^5.255
+fn air_pressure(height: Length) -> Pressure =
+    p0 · (1 - temperature_gradient · height / t0)^5.255
 
 assert_eq(air_pressure(1500 m), 845.586 hPa, 0.1 hPa)

+ 1 - 1
examples/earth_mass.nbt

@@ -5,4 +5,4 @@ let volume: Volume = 4/3 · π · radius³
 let ρ: MassDensity = 5000 kg/m³
 let earth_mass: Mass = ρ · volume
 
-assert_eq(earth_mass, 4.52389 * 10^24 kg, 0.00001 * 10^24 kg)
+assert_eq(earth_mass, 4.52389e24 kg, 0.00001e24 kg)

+ 2 - 1
examples/pendulum.nbt

@@ -1,3 +1,4 @@
-fn oscillation_time(length: Length) -> Time = 2 pi × sqrt(length / gravity)
+fn oscillation_time(length: Length) -> Time =
+    2 pi × sqrt(length / gravity)
 
 assert_eq(oscillation_time(30 cm), 1.1 s, 0.1 s)

+ 2 - 1
examples/stopping_distance.nbt

@@ -1,6 +1,7 @@
 let reaction_time: Time = 500 ms
 let braking_power: Acceleration = 0.8 × gravity
 
-fn stopping_distance(v: Speed) -> Length = v × reaction_time + ½ v² / braking_power
+fn stopping_distance(v: Speed) -> Length =
+    v × reaction_time + ½ v² / braking_power
 
 assert_eq(stopping_distance(50 km/h), 19.2385 m, 0.001 m)

+ 22 - 12
examples/what_if_158.nbt

@@ -1,7 +1,7 @@
 # Hot Banana
 #
-# I heard that bananas are radioactive. If they are radioactive, then they
-# radiate energy. How many bananas would you need to power a house?
+# I heard that bananas are radioactive. If they are radioactive, then
+# they radiate energy. How many bananas would you need to power a house?
 #
 # https://what-if.xkcd.com/158/
 
@@ -17,7 +17,9 @@ let occurence_40K = 0.0117 percent
 # We can now compute the radioactivity of natural potassium
 
 let decay_rate_40K: Activity = ln(2) / halflife_40K
-let radioactivity_potassium: Activity / Mass = N_A * occurence_40K * decay_rate_40K / molar_mass_40K -> Bq / g
+
+let radioactivity_potassium: Activity / Mass =
+    N_A × occurence_40K × decay_rate_40K / molar_mass_40K -> Bq / g
 
 print(radioactivity_potassium)
 
@@ -30,26 +32,34 @@ unit banana
 
 let potassium_per_banana = 451 mg / banana
 
-let radioactivity_banana: Activity / Banana = potassium_per_banana * radioactivity_potassium -> Bq / banana
+let radioactivity_banana: Activity / Banana =
+    potassium_per_banana × radioactivity_potassium -> Bq / banana
+
 print(radioactivity_banana)
 
 # A single 40-K decay releases an energy of
 # (https://commons.wikimedia.org/wiki/File:Potassium-40-decay-scheme.svg)
 
-let energy_per_decay: Energy = 11 percent * 1.5 MeV + 89 percent * 1.3 MeV
+let energy_per_decay: Energy = 11 percent × 1.5 MeV + 89 percent × 1.3 MeV
 
 # Finally: how many bananas do we need to power a single household?
 
-let power_per_banana: Power / Banana = radioactivity_banana * energy_per_decay -> pW / banana
+let power_per_banana: Power / Banana =
+    radioactivity_banana × energy_per_decay -> pW / banana
+
 print(power_per_banana)
 
 unit household
-let power_consumption_household: Power / Household = 3000 kWh per household per year
 
-let bananas_per_household = power_consumption_household / power_per_banana -> bananas / household
+let power_consumption_household: Power / Household =
+    3000 kWh per household per year
+
+let bananas_per_household =
+    power_consumption_household / power_per_banana -> bananas / household
+
 print(bananas_per_household)
 
-# TODO: https://what-if.xkcd.com/158/ says this number should be around 300
-# quadrillion, but we only get 0.1 quadrillion. 300 quadrillion times "a couple
-# of picowatt" would be an average power consumption of at least 300 kW /
-# household, which seems … excessive.
+# TODO: https://what-if.xkcd.com/158/ says this number should be around
+# 300 quadrillion, but we only get 0.1 quadrillion. 300 quadrillion
+# times "a couple of picowatt" would be an average power consumption of
+# at least 300 kW / household, which seems … excessive.

+ 7 - 1
numbat/src/parser.rs

@@ -251,6 +251,7 @@ impl<'a> Parser<'a> {
                         span: self.peek().span,
                     })
                 } else {
+                    self.skip_empty_lines();
                     let expr = self.expression()?;
 
                     Ok(Statement::DeclareVariable {
@@ -363,6 +364,7 @@ impl<'a> Parser<'a> {
                 let body = if self.match_exact(TokenKind::Equal).is_none() {
                     None
                 } else {
+                    self.skip_empty_lines();
                     Some(self.expression()?)
                 };
 
@@ -391,9 +393,11 @@ impl<'a> Parser<'a> {
         } else if self.match_exact(TokenKind::Dimension).is_some() {
             if let Some(identifier) = self.match_exact(TokenKind::Identifier) {
                 if self.match_exact(TokenKind::Equal).is_some() {
+                    self.skip_empty_lines();
                     let mut dexprs = vec![self.dimension_expression()?];
 
                     while self.match_exact(TokenKind::Equal).is_some() {
+                        self.skip_empty_lines();
                         dexprs.push(self.dimension_expression()?);
                     }
 
@@ -455,6 +459,7 @@ impl<'a> Parser<'a> {
                 std::mem::swap(&mut decorators, &mut self.decorator_stack);
 
                 if self.match_exact(TokenKind::Equal).is_some() {
+                    self.skip_empty_lines();
                     let expr = self.expression()?;
                     Ok(Statement::DeclareDerivedUnit {
                         identifier_span,
@@ -1393,6 +1398,7 @@ mod tests {
             &[
                 "dimension Area = Length * Length",
                 "dimension Area = Length × Length",
+                "dimension Area =\n  Length × Length",
             ],
             Statement::DeclareDimension(
                 "Area".into(),
@@ -1474,7 +1480,7 @@ mod tests {
     #[test]
     fn function_declaration() {
         parse_as(
-            &["fn foo() = 1"],
+            &["fn foo() = 1", "fn foo() =\n  1"],
             Statement::DeclareFunction {
                 function_name_span: Span::dummy(),
                 function_name: "foo".into(),