Sfoglia il codice sorgente

Remove modulo operator, add '%' unit

David Peter 2 anni fa
parent
commit
5a041505d5

+ 0 - 1
book/numbat.js

@@ -35,7 +35,6 @@ hljs.registerLanguage('numbat', function(hljs) {
           { begin: '\\^' },
           { begin: '\\^' },
           { begin: '÷' },
           { begin: '÷' },
           { begin: '×' },
           { begin: '×' },
-          { begin: '%' },
           { begin: '=' },
           { begin: '=' },
           { begin: '->' },
           { begin: '->' },
           { begin: '→' },
           { begin: '→' },

+ 1 - 1
book/src/example-numbat_syntax.md

@@ -43,7 +43,7 @@ meter per second  # 'per' keyword can be used for division
 2**3              # Python-style
 2**3              # Python-style
 2³                # Unicode exponents
 2³                # Unicode exponents
 
 
-17 % 4            # Modulo
+mod(17, 4)        # Modulo
 
 
 3 in -> cm        # Unit conversion, can also be → or ➞
 3 in -> cm        # Unit conversion, can also be → or ➞
 3 in to cm        # Unit conversion with the 'to' keyword
 3 in to cm        # Unit conversion with the 'to' keyword

+ 1 - 1
book/src/list-units.md

@@ -70,7 +70,7 @@ All SI-accepted units support [metric prefixes](https://en.wikipedia.org/wiki/Me
 | [Parts-per-trillion](https://en.wikipedia.org/wiki/Parts-per_notation) | `ppt` |
 | [Parts-per-trillion](https://en.wikipedia.org/wiki/Parts-per_notation) | `ppt` |
 | [Parts-per-quadrillion](https://en.wikipedia.org/wiki/Parts-per_notation) | `ppq` |
 | [Parts-per-quadrillion](https://en.wikipedia.org/wiki/Parts-per_notation) | `ppq` |
 | [Pascal](https://en.wikipedia.org/wiki/Pascal_(unit)) | `pascals`, `pascal`, `Pa` |
 | [Pascal](https://en.wikipedia.org/wiki/Pascal_(unit)) | `pascals`, `pascal`, `Pa` |
-| [Percent](https://en.wikipedia.org/wiki/Parts-per_notation) | `percent`, `pct` |
+| [Percent](https://en.wikipedia.org/wiki/Parts-per_notation) | `percent`, `%`, `pct` |
 | [Person](https://en.wiktionary.org/wiki/person) | `persons`, `person`, `people` |
 | [Person](https://en.wiktionary.org/wiki/person) | `persons`, `person`, `people` |
 | [Piece](https://en.wiktionary.org/wiki/piece) | `pieces`, `piece` |
 | [Piece](https://en.wiktionary.org/wiki/piece) | `pieces`, `piece` |
 | [Pint](https://en.wikipedia.org/wiki/Pint) | `pints`, `pint` |
 | [Pint](https://en.wikipedia.org/wiki/Pint) | `pints`, `pint` |

+ 0 - 1
book/src/operators.md

@@ -8,7 +8,6 @@
 | factorial                 | `!`                  |
 | factorial                 | `!`                  |
 | exponentiation            | `^`, `**`            |
 | exponentiation            | `^`, `**`            |
 | multiplication (implicit) | *whitespace*         |
 | multiplication (implicit) | *whitespace*         |
-| modulo                    | `%`                  |
 | division                  | `per`                |
 | division                  | `per`                |
 | division                  | `/`, `÷`             |
 | division                  | `/`, `÷`             |
 | multiplication (explicit) | `*`, `·`, `×`        |
 | multiplication (explicit) | `*`, `·`, `×`        |

+ 1 - 1
book/src/tutorial.md

@@ -14,7 +14,7 @@ potassium-40](https://en.wikipedia.org/wiki/Potassium-40):
 
 
 ``` numbat
 ``` numbat
 let halflife = 1.25 billion years
 let halflife = 1.25 billion years
-let occurence = 0.0117 percent
+let occurence = 0.0117%
 let molar_mass = 40 g / mol
 let molar_mass = 40 g / mol
 ```
 ```
 
 

+ 2 - 2
examples/format_time.nbt

@@ -1,8 +1,8 @@
 let time = 17.47 hours
 let time = 17.47 hours
 
 
 let time_seconds = time -> seconds
 let time_seconds = time -> seconds
-let num_seconds = time_seconds % 60 seconds
-let num_minutes = (time - num_seconds) % (60 minutes) -> minutes
+let num_seconds = mod(time_seconds, 60 seconds)
+let num_minutes = mod(time - num_seconds, 60 minutes) -> minutes
 let num_hours = floor((time - num_minutes - num_seconds) / 1 hour) × hour -> hours
 let num_hours = floor((time - num_minutes - num_seconds) / 1 hour) × hour -> hours
 
 
 print(num_hours)
 print(num_hours)

+ 1 - 1
examples/numbat_syntax.nbt

@@ -38,7 +38,7 @@ meter per second  # 'per' keyword can be used for division
 2**3              # Python-style
 2**3              # Python-style
 2³                # Unicode exponents
 2³                # Unicode exponents
 
 
-17 % 4            # Modulo
+mod(17, 4)        # Modulo
 
 
 3 in -> cm        # Unit conversion, can also be → or ➞
 3 in -> cm        # Unit conversion, can also be → or ➞
 3 in to cm        # Unit conversion with the 'to' keyword
 3 in to cm        # Unit conversion with the 'to' keyword

+ 1 - 1
examples/typecheck_error/incompatible_types_in_modulo.nbt

@@ -1 +1 @@
-130 cm % 1
+mod(130 cm, 1)

+ 1 - 1
modules/units/partsperx.nbt

@@ -1,4 +1,4 @@
-@aliases(pct)
+@aliases(%: short, pct)
 unit percent = 1e-02
 unit percent = 1e-02
 
 
 @aliases(ppm)
 @aliases(ppm)

+ 3 - 20
numbat/src/parser.rs

@@ -14,8 +14,7 @@
 //! conversion      →   term ( "→" term ) *
 //! conversion      →   term ( "→" term ) *
 //! term            →   factor ( ( "+" | "-") factor ) *
 //! term            →   factor ( ( "+" | "-") factor ) *
 //! factor          →   negate ( ( "*" | "/") per_factor ) *
 //! factor          →   negate ( ( "*" | "/") per_factor ) *
-//! per_factor      →   modulo ( "per" modulo ) *
-//! modulo          →   negate ( "%" negate ) *
+//! per_factor      →   negate ( "per" negate ) *
 //! negate          →   "-" negate | ifactor
 //! negate          →   "-" negate | ifactor
 //! ifactor         →   power ( " " power ) *
 //! ifactor         →   power ( " " power ) *
 //! power           →   factorial ( "^" power )
 //! power           →   factorial ( "^" power )
@@ -696,11 +695,11 @@ impl<'a> Parser<'a> {
     }
     }
 
 
     fn per_factor(&mut self) -> Result<Expression> {
     fn per_factor(&mut self) -> Result<Expression> {
-        let mut expr = self.modulo()?;
+        let mut expr = self.negate()?;
 
 
         while self.match_exact(TokenKind::Per).is_some() {
         while self.match_exact(TokenKind::Per).is_some() {
             let span_op = Some(self.last().unwrap().span);
             let span_op = Some(self.last().unwrap().span);
-            let rhs = self.modulo()?;
+            let rhs = self.negate()?;
 
 
             expr = Expression::BinaryOperator {
             expr = Expression::BinaryOperator {
                 op: BinaryOperator::Div,
                 op: BinaryOperator::Div,
@@ -713,22 +712,6 @@ impl<'a> Parser<'a> {
         Ok(expr)
         Ok(expr)
     }
     }
 
 
-    fn modulo(&mut self) -> Result<Expression> {
-        let mut expr = self.negate()?;
-        let mut full_span = expr.full_span();
-
-        while self.match_exact(TokenKind::Modulo).is_some() {
-            let op_span = self.last().unwrap().span;
-            let rhs = self.modulo()?;
-
-            full_span = full_span.extend(&rhs.full_span());
-
-            expr = Expression::FunctionCall(op_span, full_span, "mod".into(), vec![expr, rhs]);
-        }
-
-        Ok(expr)
-    }
-
     fn negate(&mut self) -> Result<Expression> {
     fn negate(&mut self) -> Result<Expression> {
         if self.match_exact(TokenKind::Minus).is_some() {
         if self.match_exact(TokenKind::Minus).is_some() {
             let span = self.last().unwrap().span;
             let span = self.last().unwrap().span;

+ 1 - 2
numbat/src/tokenizer.rs

@@ -55,7 +55,6 @@ pub enum TokenKind {
     Power,
     Power,
     Divide,
     Divide,
     Per,
     Per,
-    Modulo,
     Comma,
     Comma,
     Arrow,
     Arrow,
     Equal,
     Equal,
@@ -149,6 +148,7 @@ fn is_identifier_start(c: char) -> bool {
     unicode_ident::is_xid_start(c)
     unicode_ident::is_xid_start(c)
         || is_numerical_fraction_char(c)
         || is_numerical_fraction_char(c)
         || is_currency_char(c)
         || is_currency_char(c)
+        || c == '%'
         || c == '_'
         || c == '_'
 }
 }
 
 
@@ -367,7 +367,6 @@ impl Tokenizer {
             '/' if self.match_char('/') => TokenKind::PostfixApply,
             '/' if self.match_char('/') => TokenKind::PostfixApply,
             '/' => TokenKind::Divide,
             '/' => TokenKind::Divide,
             '÷' => TokenKind::Divide,
             '÷' => TokenKind::Divide,
-            '%' => TokenKind::Modulo,
             '^' => TokenKind::Power,
             '^' => TokenKind::Power,
             ',' => TokenKind::Comma,
             ',' => TokenKind::Comma,
             '=' => TokenKind::Equal,
             '=' => TokenKind::Equal,

+ 9 - 6
numbat/tests/interpreter.rs

@@ -148,12 +148,15 @@ fn test_math() {
         "parameter type: Length\n argument type: Length²",
         "parameter type: Length\n argument type: Length²",
     );
     );
 
 
-    expect_output("5 % 3", "2");
-    expect_output("-1 % 4", "3");
-    expect_output("8 cm % 5 cm", "3 cm");
-    expect_output("235 cm % 1 m", "35 cm");
-    expect_output("2 m % 7 cm", "0.04 m");
-    expect_failure("8 m % 5 s", "parameter type: Length\n argument type: Time")
+    expect_output("mod(5, 3)", "2");
+    expect_output("mod(-1, 4)", "3");
+    expect_output("mod(8 cm, 5 cm)", "3 cm");
+    expect_output("mod(235 cm, 1 m)", "35 cm");
+    expect_output("mod(2 m, 7 cm)", "0.04 m");
+    expect_failure(
+        "mod(8 m, 5 s)",
+        "parameter type: Length\n argument type: Time",
+    )
 }
 }
 
 
 #[test]
 #[test]