44require_once __DIR__ . '/../vendor/autoload.php ' ;
55
66use Nette \PhpGenerator \ClassType ;
7+ use Nette \PhpGenerator \InterfaceType ;
78use Nette \PhpGenerator \PhpFile ;
89use Nette \PhpGenerator \PsrPrinter ;
910
@@ -22,7 +23,7 @@ defineAst(EXPR_DIR, 'Expr', [
2223defineAst (STMT_DIR , 'Stmt ' , [
2324 'ExpressionStmt : Lox\Expr\Expr expression ' ,
2425 'PrintStmt : Lox\Expr\Expr expression ' ,
25- 'VarStmt : Lox\Token name, Lox\Expr\Expr initializer ' ,
26+ 'VarStmt : Lox\Token name, ? Lox\Expr\Expr initializer ' ,
2627]);
2728
2829function defineAst (string $ outputDir , string $ baseName , array $ types ): void
@@ -62,10 +63,9 @@ function generateBaseClass(string $baseName): ClassType
6263 return $ class ;
6364}
6465
65- function generateVisitor (string $ baseName , array $ types ): ClassType
66+ function generateVisitor (string $ baseName , array $ types ): InterfaceType
6667{
67- $ class = new ClassType ('Visitor ' );
68- $ class ->setType ('interface ' );
68+ $ class = new InterfaceType ('Visitor ' );
6969
7070 foreach ($ types as $ type ) {
7171 $ parts = explode (': ' , $ type );
@@ -88,7 +88,7 @@ function generateVisitor(string $baseName, array $types): ClassType
8888function generateType (string $ baseName , string $ className , array $ properties = []): ClassType
8989{
9090 $ class = new ClassType ($ className );
91- $ class ->addExtend (sprintf ('\Lox\%s\%1$s ' , $ baseName ));
91+ $ class ->setExtends (sprintf ('\Lox\%s\%1$s ' , $ baseName ));
9292 $ class ->setFinal ();
9393
9494 $ constructor = $ class ->addMethod ('__construct ' );
@@ -122,23 +122,23 @@ function generateType(string $baseName, string $className, array $properties = [
122122 $ getter ->setReturnType ($ type );
123123 }
124124 $ getter ->addBody ('return $this->?; ' , [$ propertyName ]);
125+ }
125126
126- // implements accept method
127- $ method = $ class ->addMethod ('accept ' );
128- $ param = $ method ->addParameter ('visitor ' );
129- $ param ->setType (sprintf ('\Lox\%s\Visitor ' , $ baseName ));
127+ // implements accept method
128+ $ method = $ class ->addMethod ('accept ' );
129+ $ param = $ method ->addParameter ('visitor ' );
130+ $ param ->setType (sprintf ('\Lox\%s\Visitor ' , $ baseName ));
130131
131- if (strpos ($ className , $ baseName )) {
132- $ method ->addBody (sprintf ('return $visitor->visit%s($this); ' , $ className ));
133- } else {
134- $ method ->addBody (sprintf ('return $visitor->visit%s%s($this); ' , $ className , $ baseName ));
135- }
132+ if (strpos ($ className , $ baseName )) {
133+ $ method ->addBody (sprintf ('return $visitor->visit%s($this); ' , $ className ));
134+ } else {
135+ $ method ->addBody (sprintf ('return $visitor->visit%s%s($this); ' , $ className , $ baseName ));
136136 }
137137
138138 return $ class ;
139139}
140140
141- function writeClass (string $ outputDir , string $ baseName , ClassType $ class ): void
141+ function writeClass (string $ outputDir , string $ baseName , ClassType | InterfaceType $ class ): void
142142{
143143 $ file = new PhpFile ();
144144 $ file ->addComment ('This file is auto-generated. ' );
@@ -147,17 +147,22 @@ function writeClass(string $outputDir, string $baseName, ClassType $class): void
147147 $ namespace = $ file ->addNamespace (sprintf ('Lox\%s ' , $ baseName ));
148148 $ namespace ->add ($ class );
149149
150- if ($ class ->hasMethod ('__construct ' )) {
150+ if ($ class instanceof ClassType && $ class ->hasMethod ('__construct ' )) {
151151 $ constructor = $ class ->getMethod ('__construct ' );
152152 foreach ($ constructor ->getParameters () as $ parameter ) {
153153 if (null !== $ parameter ->getType () && !in_array ($ parameter ->getType (), $ namespace ->getUses ())) {
154- $ namespace ->addUse ($ parameter ->getType ());
154+ $ namespace ->addUse (( string ) $ parameter ->getType ());
155155 }
156156 }
157157 }
158158
159+ $ className = $ class ->getName ();
160+ if (null === $ className ) {
161+ throw new \InvalidArgumentException ('Class or Interface must have a name. ' );
162+ }
163+
159164 file_put_contents (
160- sprintf ('%s/%s.php ' , $ outputDir , $ class -> getName () ),
165+ sprintf ('%s/%s.php ' , $ outputDir , $ className ),
161166 (new PsrPrinter )->printFile ($ file )
162167 );
163168}
0 commit comments