Skip to content

Commit 6ed6c1c

Browse files
committed
Initial proof of concept
1 parent 15f343d commit 6ed6c1c

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/main/php/lang/ast/Result.class.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<?php namespace lang\ast;
22

3+
use lang\ast\types\{Declaration, Reflection};
4+
35
class Result {
46
public $out;
57
public $codegen;
68
public $line= 1;
79
public $meta= [];
810
public $locals= [];
911
public $stack= [];
12+
public $type= [];
1013

1114
/**
1215
* Starts a result stream, including a preamble
@@ -28,4 +31,20 @@ public function __construct($out, $preamble= '<?php ') {
2831
public function temp() {
2932
return '$'.$this->codegen->symbol();
3033
}
34+
35+
/**
36+
* Looks up a given type
37+
*
38+
* @param string $type
39+
* @return lang.ast.types.Type
40+
*/
41+
public function lookup($type) {
42+
if ('self' === $type || 'static' === $type || $type === $this->type[0]->name) {
43+
return new Declaration($this->type[0], $this);
44+
} else if ('parent' === $type) {
45+
return $this->lookup($this->type[0]->parent);
46+
} else {
47+
return new Reflection($type);
48+
}
49+
}
3150
}

src/main/php/lang/ast/emit/PHP.class.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ protected function emitLambda($result, $lambda) {
350350
}
351351

352352
protected function emitClass($result, $class) {
353+
array_unshift($result->type, $class);
353354
array_unshift($result->meta, []);
354355
$result->locals= [[], []];
355356

@@ -373,6 +374,7 @@ protected function emitClass($result, $class) {
373374
$this->emitInitializations($result, $result->locals[0]);
374375
$this->emitMeta($result, $class->name, $class->annotations, $class->comment);
375376
$result->out->write('}} '.$class->name.'::__init();');
377+
array_shift($result->type);
376378
}
377379

378380
/** Stores lowercased, unnamespaced name in annotations for BC reasons! */
@@ -909,6 +911,8 @@ protected function emitScope($result, $scope) {
909911
$result->out->write(')?'.$t.'::');
910912
$this->emitOne($result, $scope->member);
911913
$result->out->write(':null');
914+
} else if ($scope->member instanceof Literal && '$enum' === $result->lookup($scope->type)->kind()) {
915+
$result->out->write($scope->type.'::$'.$scope->member->expression);
912916
} else {
913917
$result->out->write($scope->type.'::');
914918
$this->emitOne($result, $scope->member);

src/test/php/lang/ast/unittest/emit/MembersTest.class.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,19 @@ public function run() {
171171
Assert::equals('MON', $r);
172172
}
173173

174+
#[Test]
175+
public function allow_constant_syntax_for_members() {
176+
$r= $this->run('use lang\{Enum, CommandLine}; class <T> extends Enum {
177+
public static $MON, $TUE, $WED, $THU, $FRI, $SAT, $SUN;
178+
179+
public function run() {
180+
return [self::MON->name(), <T>::TUE->name(), CommandLine::WINDOWS->name()];
181+
}
182+
}');
183+
184+
Assert::equals(['MON', 'TUE', 'WINDOWS'], $r);
185+
}
186+
174187
#[Test]
175188
public function method_with_static() {
176189
$r= $this->run('class <T> {

0 commit comments

Comments
 (0)