Skip to content

Commit

Permalink
minor fix/reword on README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
marcioAlmada committed Jun 2, 2018
1 parent 3364f2c commit ef3362c
Showing 1 changed file with 19 additions and 22 deletions.
41 changes: 19 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
This means that language features could be distributed as composer packages (as long as the macro based implementations
can be expressed in pure PHP code, and the implementation is fast enough).

> Not ready for real world usage yet :bomb:
[Roadmap](https://github.com/marcioAlmada/yay/issues/3).

## Set Up
Expand Down Expand Up @@ -45,7 +43,7 @@ Every macro consist of a matcher and an expander that when executed allows you t
Consider the simplest example possible:

```php
(macro :unsafe) { $ } >> { $this } // this shorthand
$(macro :unsafe) { $ } >> { $this } // this shorthand
```

The macro is basically expanding a literal `$` token to `$this`. The following code would expand to:
Expand All @@ -61,7 +59,7 @@ class Foo { | class Foo {
} | }
```

Notice that the `:unsafe` tag is necessary to avoid macro hygiene on `$this` expansion.
> Notice that the `:unsafe` tag is necessary to avoid macro hygiene on `$this` expansion.
This macro is actually very naive, a more producion ready version would be:

Expand Down Expand Up @@ -105,7 +103,7 @@ To implement `unless` we need to match the literal `unless` keyword followed by

```php
$(macro) {
unless $! ($(layer() as expression)) { $(layer() as body) }
unless ($(layer() as expression)) { $(layer() as body) }
} >> {
if (! ($(expression))) {
$(body)
Expand Down Expand Up @@ -137,16 +135,18 @@ enum Fruits {
var_dump(\Fruits::Orange <=> \Fruits::Apple);
```
So, syntactically, enums are declared with the literal `enum` word followed by a `T_STRING` and a comma
separated list of identifiers withing braces `{A, B, C}`.
separated list of identifiers withing braces such as `{A, B, C}`.

YAY uses parser combinators internally for everything and these more high level parsers are fully
exposed on macro declarations. Our enum macro will need high level matchers like `ls()` and `word()`
exposed on macro declarations. Our enum macro will need high level matchers like `ls()` and `label()`
combined to match the desired syntax, like so:

```php
macro {
$(macro) {
enum $(T_STRING as name) {
$(
// ls() matches a delimited list
// in this case a list of label() delimited by ',' such as `foo, bar, baz`
ls
(
label() as field
Expand All @@ -161,7 +161,7 @@ macro {
}
```

The macro is already capable to match the enums:
The macro is already capable to match the enum syntax:

```php
// source // expansion
Expand Down Expand Up @@ -198,21 +198,21 @@ $(macro :unsafe) {
}
} >> {
class $(name) implements Enum {
private static $store;
private static $registry;

private function __construct() {}

static function __callStatic(string $field, array $args) : self {
if(! self::$store) {
self::$store = new \stdclass;
static function __callStatic(string $type, array $args) : self {
if(! self::$registry) {
self::$registry = new \stdclass;
$(fields ... {
self::$store->$(field) = new class extends $(name) {};
self::$registry->$(field) = new class extends $(name) {};
})
}

if (isset(self::$store->$field)) return self::$store->$field;
if (isset(self::$registry->$type)) return self::$registry->$type;

throw new \Exception('Undefined enum field ' . __CLASS__ . "->{$field}.");
throw new \Exception(sprintf('Undefined enum type %s->%s', __CLASS__, $type));
}
}
}
Expand All @@ -223,19 +223,16 @@ $(macro) {
chain(
ns() as class, // matches a namespace
token(T_DOUBLE_COLON), // matches T_DOUBLE_COLON used for static access
not(class), // avoids matching ::class resolution syntax
not(class), // avoids matching `Foo::class`, class resolution syntax
label() as field, // matches the enum field name
not(token('(')) // avoids matching static method calls
not(token('(')) // avoids matching static method calls such as `Foo::bar()`
)
)
} >> {
\enum_field_or_class_constant($(class)::class, $$(stringify($(field))))
}
```

You can use https://github.com/marcioAlmada/yay-enums to run the example above
on your own environment, as a playground.

> More examples within the phpt tests folder https://github.com/marcioAlmada/yay/tree/master/tests/phpt
# FAQ
Expand All @@ -248,7 +245,7 @@ on your own environment, as a playground.
A cookbook is on the making

> Why TF are you working on this?
> Why are you working on this?
Because it's being fun. It may become useful. [Because we can™](https://github.com/haskellcamargo/because-we-can).

Expand Down

0 comments on commit ef3362c

Please sign in to comment.