Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
add hex utility function
Browse files Browse the repository at this point in the history
  • Loading branch information
ylixir committed Feb 19, 2019
1 parent afb9beb commit 9f5acc5
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
22 changes: 22 additions & 0 deletions docs/utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ assert(null === $parser("123"));
assert(null === $parser(""));
```

## `hex`

This parses a sequence of hexadecimal digits converting them to an `int`.

#### OOP and FP

```php
$parser = p::hex();

assert([0x1a] === $parser("1a")->parsed);
assert([0xf] === $parser("F")->parsed);
assert([0] === $parser("0")->parsed);

//doesn't include an end condition or prefixes
assert([0] === $parser("0xa")->parsed);
assert("xa" === $parser("0xa")->unparsed);

assert(null === $parser("")->parsed);
//doesn't handle signs
assert(null === $parser("-123")->parsed);
```

## `int`

This parses a sequence of decimal digits converting them to an `int`.
Expand Down
35 changes: 35 additions & 0 deletions src/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ final class Functions
const and = self::class . "::and";
const drop = self::class . "::drop";
const end = self::class . "::end";
const float = self::class . "::float";
const fold = self::class . "::fold";
const hex = self::class . "::hex";
const int = self::class . "::int";
const lit = self::class . "::lit";
const map = self::class . "::map";
Expand Down Expand Up @@ -170,6 +172,39 @@ function (array $a, $s) use ($f): array {
};
}

/**
* @return callable(string):?r<int>
*/
public static function hex(): callable
{
/**
* @var array<int, callable(string):?r<string>>
*/
$decLits = array_map(self::lit, range("0", "9"));
/**
* @var array<int, callable(string):?r<string>>
*/
$hexLits = array_merge(
array_map(self::lit, range("a", "f")),
array_map(self::lit, range("A", "F"))
);

$dec = self::map('intval', self::or(...$decLits));
$hex = self::map(function (string $v): int {
return 9 + (0xf & ord($v));
}, self::or(...$hexLits));

$digits = self::or($dec, $hex);

$hexSequence = self::and($digits, self::repeat($digits));

$hexVal = function (int $d, int $a): array {
return [$a * 0x10 + $d];
};

return self::fold($hexVal, [0], $hexSequence);
}

/**
* @return callable(string):?r<int>
*/
Expand Down
6 changes: 6 additions & 0 deletions src/Oop.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ final class Oop
{
//convenience constants for passing functions to functions
const float = self::class . "::float";
const hex = self::class . "::hex";
const int = self::class . "::int";
const lit = self::class . "::lit";
const pop = self::class . "::pop";
Expand Down Expand Up @@ -68,6 +69,11 @@ public function fold(callable $f, array $start = []): self
return new self(p::fold($f, $start, $this->parser));
}

public static function hex(): self
{
return new self(p::hex());
}

public static function int(): self
{
return new self(p::int());
Expand Down
21 changes: 21 additions & 0 deletions test/Unit/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,27 @@ public function test_fold(
$this->assertEquals($expected, $actual);
}

public function hex_provider(): array
{
return [
["1a", r::make("", [0x1a])],
["F", r::make("", [0xf])],
["0", r::make("", [0])],
["0xa", r::make("xa", [0])],
["", null],
["-123", null],
];
}
/**
* @dataProvider hex_provider
*/
public function test_hex(string $input, ?r $expected): void
{
$p = p::hex();

self::assertEquals($expected, $p($input));
}

public function int_provider(): array
{
return [
Expand Down
21 changes: 21 additions & 0 deletions test/Unit/OopTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,27 @@ public function testFold(
$this->assertEquals($expected, $actual);
}

public function hexProvider(): array
{
return [
["1a", r::make("", [0x1a])],
["F", r::make("", [0xf])],
["0", r::make("", [0])],
["0xa", r::make("xa", [0])],
["", null],
["-123", null],
];
}
/**
* @dataProvider hexProvider
*/
public function testHex(string $input, ?r $expected): void
{
$p = p::hex();

self::assertEquals($expected, $p($input));
}

public function intProvider(): array
{
return [
Expand Down

0 comments on commit 9f5acc5

Please sign in to comment.