Skip to content

Commit ccda5bb

Browse files
authored
Merge pull request #41 from ruifonseca/add_string_parse_float_core_method
Add String.parse_float() core method
2 parents 2534a4f + a9f64ed commit ccda5bb

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

docs/language.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ render_text("Hello world");
202202
- `byte_at(byte_idx)`: Get the UTF-8 byte at the given byte index.
203203
- `char_at(byte_idx)`: Get a string for the single character at the given byte index. Returns `nil` if invalid.
204204
- `parse_int(radix)`: Try to parse the entire string as an integer of the given `radix`. Returns `nil` on failure.
205+
- `parse_float()`: Try to parse the entire string as a float. Returns `nil` on failure.
205206
- `trim()`: Produce a new string without whitespace at the beginning or end.
206207
- `upper()`: Produce a new string as the uppercase version of the string.
207208
- `lower()`: Produce a new string as the lowercase version of the string.

src/runtime.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,17 @@ fn string_parse_int(actor: &mut Actor, s: Value, radix: Value) -> Result<Value,
255255
}
256256
}
257257

258+
/// Try to parse the string as a float
259+
fn string_parse_float(actor: &mut Actor, s: Value) -> Result<Value, String>
260+
{
261+
let s = unwrap_str!(s);
262+
263+
match s.parse::<f64>() {
264+
Ok(float_val) => Ok(Value::from(float_val)),
265+
Err(_) => Ok(Value::Nil),
266+
}
267+
}
268+
258269
/// Trim whitespace
259270
fn string_trim(actor: &mut Actor, s: Value) -> Result<Value, String>
260271
{
@@ -403,6 +414,7 @@ pub fn get_method(val: Value, method_name: &str) -> Value
403414
static STRING_BYTE_AT: HostFn = HostFn { name: "byte_at", f: Fn2(string_byte_at) };
404415
static STRING_CHAR_AT: HostFn = HostFn { name: "char_at", f: Fn2(string_char_at) };
405416
static STRING_PARSE_INT: HostFn = HostFn { name: "parse_int", f: Fn2(string_parse_int) };
417+
static STRING_PARSE_FLOAT: HostFn = HostFn { name: "parse_float", f: Fn1(string_parse_float) };
406418
static STRING_TRIM: HostFn = HostFn { name: "trim", f: Fn1(string_trim) };
407419
static STRING_UPPER: HostFn = HostFn { name: "upper", f: Fn1(string_upper) };
408420
static STRING_LOWER: HostFn = HostFn { name: "lower", f: Fn1(string_lower) };
@@ -466,6 +478,7 @@ pub fn get_method(val: Value, method_name: &str) -> Value
466478
(Value::String(_), "byte_at") => &STRING_BYTE_AT,
467479
(Value::String(_), "char_at") => &STRING_CHAR_AT,
468480
(Value::String(_), "parse_int") => &STRING_PARSE_INT,
481+
(Value::String(_), "parse_float") => &STRING_PARSE_FLOAT,
469482
(Value::String(_), "trim") => &STRING_TRIM,
470483
(Value::String(_), "upper") => &STRING_UPPER,
471484
(Value::String(_), "lower") => &STRING_LOWER,

tests/strings.psh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ assert("not a number".parse_int(10) == nil);
3838
assert(" 0".parse_int(2) == nil);
3939
assert("0 ".parse_int(2) == nil);
4040

41+
// Test parse_float
42+
assert("123".parse_float() == 123);
43+
assert("3.14".parse_float() == 3.14);
44+
assert("-3.14".parse_float() == -3.14);
45+
assert("2.5E10".parse_float() == 2.5E10);
46+
assert("2.5e10".parse_float() == 2.5e10);
47+
assert("2.5E-10".parse_float() == 2.5E-10);
48+
assert("1.e1".parse_float() == 10);
49+
assert("1e1".parse_float() == 10);
50+
assert("-1e-1".parse_float() == -0.1);
51+
assert("5.".parse_float() == 5);
52+
assert(".5".parse_float() == 0.5);
53+
assert("0.5".parse_float() == 0.5);
54+
assert("7".parse_float() == 7);
55+
assert("007".parse_float() == 7);
56+
assert(" 1.0".parse_float() == nil);
57+
assert("1.1 ".parse_float() == nil);
58+
assert("1..".parse_float() == nil);
59+
60+
4161
// Test trim
4262
assert(" hello ".trim() == "hello");
4363
assert("\n world \n ".trim() == "world");

0 commit comments

Comments
 (0)