Implement % as a unit

This commit is contained in:
Olivier Goffart 2020-07-16 11:23:10 +02:00
parent c3aae7648a
commit 170564ecea
5 changed files with 59 additions and 1 deletions

View file

@ -92,6 +92,16 @@ fn fill_token_vec(stream: TokenStream, vec: &mut Vec<parser::Token>) {
} }
SyntaxKind::OrOr SyntaxKind::OrOr
} }
'%' => {
// % can only exist after number literal
if let Some(last) = vec.last_mut() {
if last.kind == SyntaxKind::NumberLiteral {
last.text = format!("{}%", last.text).into();
continue;
}
}
SyntaxKind::Error
}
_ => SyntaxKind::Error, _ => SyntaxKind::Error,
}; };
prev_spacing = p.spacing(); prev_spacing = p.spacing();

View file

@ -109,6 +109,7 @@ If one change the `my_property`, the width will be updated automatically.
- FIXME: more - FIXME: more
`int32` and `float32` are the types for the numbers, they correspond to the equivalent in the target language `int32` and `float32` are the types for the numbers, they correspond to the equivalent in the target language
A number can end with '%', so for example `30%` is the same as `0.30`
`string` are implicitly shared. `string` are implicitly shared.

View file

@ -78,6 +78,8 @@ macro_rules! declare_units {
declare_units! { declare_units! {
/// No unit was given /// No unit was given
None = "" -> Float32, None = "" -> Float32,
///
Percent = "%" -> Float32 * 0.01,
// Lenghts or Coord // Lenghts or Coord

View file

@ -211,7 +211,7 @@ declare_syntax! {
Whitespace -> r"\s+", Whitespace -> r"\s+",
Comment -> r"//.*\n|(?sU)/\*.*\*/", // FIXME: comments within comments Comment -> r"//.*\n|(?sU)/\*.*\*/", // FIXME: comments within comments
StringLiteral -> r#""[^"]*""#, // FIXME: escapes StringLiteral -> r#""[^"]*""#, // FIXME: escapes
NumberLiteral -> r"[\d]+(\.[\d]*)?[\w]*", NumberLiteral -> r"[\d]+(\.[\d]*)?[\w]*%?",
ColorLiteral -> r"#[\w]+", ColorLiteral -> r"#[\w]+",
Identifier -> r"[\w]+", Identifier -> r"[\w]+",
LBrace -> r"\{", LBrace -> r"\{",

45
tests/cases/percent.60 Normal file
View file

@ -0,0 +1,45 @@
TestCase := Rectangle {
property<float32> p1: 100%;
property<float32> p2: 1%;
property<float32> p3: 5.5%;
property<float32> p4: 10 + 50%;
}
/*
```cpp
TestCase instance;
auto fuzzy_compare = [](float a, float b) { return std::abs(a - b) < 0.00000001; };
assert(fuzzy_compare(instance.get_p1(), 1.));
assert(fuzzy_compare(instance.get_p2(), 0.01));
assert(fuzzy_compare(instance.get_p3(), 0.055));
assert(fuzzy_compare(instance.get_p4(), 10.5));
// self_test
assert(!fuzzy_compare(instance.get_p1(), 1.001));
```
```rust
let instance = TestCase::new();
let instance = instance.as_ref();
assert_eq!(instance.get_p1(), 1.);
assert_eq!(instance.get_p2(), 0.01);
assert_eq!(instance.get_p3(), 0.055);
assert_eq!(instance.get_p4(), 10.5);
assert_ne!(instance.get_p3(), 0.0549);
```
```js
var instance = new sixtyfps.TestCase({});
function n(a) { return Math.round(a*1000000) }
assert.equal(n(instance.p1), n(1.));
assert.equal(n(instance.p2), n(0.01));
assert.equal(n(instance.p3), n(0.055));
assert.equal(n(instance.p4), n(10.5));
// self_test
assert.notEqual(n(instance.p1), n(1.001));
```
*/