Skip to content

Commit

Permalink
Merge pull request #49 from m3m0r7/add-dir-and-file
Browse files Browse the repository at this point in the history
Add Dir and File class
  • Loading branch information
m3m0r7 authored Jan 2, 2024
2 parents 7faa77d + de6ded7 commit 3f3566e
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 3 deletions.
20 changes: 19 additions & 1 deletion src/VM/Core/Runtime/BasicObject/Kernel/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,23 @@
namespace RubyVM\VM\Core\Runtime\BasicObject\Kernel;

use RubyVM\VM\Core\Runtime\BasicObject\BasicObject;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Comparable\String_;
use RubyVM\VM\Exception\RubyVMException;

abstract class Kernel extends BasicObject {}
abstract class Kernel extends BasicObject
{
public function __dir__(): String_
{
if (!$this->context instanceof \RubyVM\VM\Core\Runtime\Executor\Context\ContextInterface) {
throw new RubyVMException('A context is not injected');
}

return String_::createBy(
$this->context
->instructionSequence()
->body()
->info()
->path(),
);
}
}
80 changes: 80 additions & 0 deletions src/VM/Core/Runtime/BasicObject/Kernel/Object_/Enumerable/Dir.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Enumerable;

use RubyVM\VM\Core\Runtime\Attribute\BindAliasAs;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Comparable\String_;
use RubyVM\VM\Core\Runtime\BasicObject\Symbolizable;
use RubyVM\VM\Core\Runtime\BasicObject\SymbolizeInterface;
use RubyVM\VM\Core\Runtime\Essential\RubyClassInterface;
use RubyVM\VM\Core\YARV\Essential\Symbol\StringSymbol;
use RubyVM\VM\Core\YARV\Essential\Symbol\SymbolInterface;
use RubyVM\VM\Exception\RuntimeException;

#[BindAliasAs('Dir')]
class Dir extends Enumerable implements RubyClassInterface, SymbolizeInterface
{
use Symbolizable;
protected ?\ArrayIterator $iterator = null;

/**
* @var \DirectoryIterator[]
*/
protected array $files = [];

protected string $directory;

public function __construct(protected SymbolInterface $symbol)
{
$this->directory = (string) $this->symbol;
$this->files = array_values(
iterator_to_array(
new \DirectoryIterator($this->symbol->valueOf()),
)
);
}

public static function pwd(): RubyClassInterface
{
return String_::createBy(getcwd());
}

public function getIterator(): \ArrayIterator
{
return $this->iterator ??= new \ArrayIterator($this->files);
}

public function offsetExists(mixed $offset): bool
{
return (bool) $this->offsetGet($offset);
}

public function offsetGet(mixed $offset): mixed
{
return $this->files[$offset] ?? throw new RuntimeException(
sprintf('File not found #%s', $offset),
);
}

public function offsetSet(mixed $offset, mixed $value): void
{
throw new RuntimeException('File cannot set');
}

public function offsetUnset(mixed $offset): void
{
throw new RuntimeException('File cannot unset');
}

public function count(): int
{
return count($this->files);
}

public static function createBy(?string $directory = null): self
{
return new self(new StringSymbol((string) ($directory ?? getcwd())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Enumerable\IO;

use RubyVM\VM\Core\Runtime\Attribute\BindAliasAs;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Comparable\String_;
use RubyVM\VM\Core\Runtime\BasicObject\SymbolizeInterface;
use RubyVM\VM\Core\Runtime\Essential\RubyClassInterface;
use RubyVM\VM\Core\YARV\Essential\Symbol\NilSymbol;
use RubyVM\VM\Core\YARV\Essential\Symbol\NumberSymbol;
use RubyVM\VM\Core\YARV\Essential\Symbol\StringSymbol;
use RubyVM\VM\Core\YARV\Essential\Symbol\SymbolInterface;
use RubyVM\VM\Exception\RuntimeException;

#[BindAliasAs('File')]
class File extends IO implements RubyClassInterface, SymbolizeInterface
{
public function __construct(protected NilSymbol|StringSymbol $path, protected StringSymbol $mode, protected NumberSymbol $permission)
{
$this->path = $path;
$this->mode = $mode;
$this->permission = $permission;
}

public function getIterator(): \Traversable
{
throw new RuntimeException('File cannot iterate');
}

public function offsetExists(mixed $offset): bool
{
throw new RuntimeException('File cannot exists');
}

public function offsetGet(mixed $offset): mixed
{
throw new RuntimeException('File cannot get');
}

public function offsetSet(mixed $offset, mixed $value): void
{
throw new RuntimeException('File cannot set');
}

public function offsetUnset(mixed $offset): void
{
throw new RuntimeException('File cannot unset');
}

public function count(): int
{
throw new RuntimeException('File cannot count');
}

public static function read(String_ $path): String_
{
return String_::createBy(
file_get_contents(
(string) $path,
),
);
}

public static function createBy(?string $path = null, ?string $mode = null, ?int $permission = null): self
{
return new self(
$path === null
? new NilSymbol()
: new StringSymbol($path),
new StringSymbol($mode ?? 'r'),
new NumberSymbol($permission ?? 0666),
);
}

public function symbol(): SymbolInterface
{
return $this->path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Enumerable\IO;

use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Enumerable\Enumerable;

abstract class IO extends Enumerable {}
14 changes: 13 additions & 1 deletion src/VM/Core/Runtime/Executor/CallBlockHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use RubyVM\VM\Core\Runtime\Attribute\WithContext;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Class_;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Comparable\Integer_;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Comparable\String_;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Object_\Enumerable\Array_;
use RubyVM\VM\Core\Runtime\Essential\RubyClassInterface;
use RubyVM\VM\Core\Runtime\Executor\Context\ContextInterface;
Expand Down Expand Up @@ -33,7 +35,17 @@ public function send(string $name, CallInfoInterface $callInfo, ?ExecutorInterfa
];
}

return $this->{$name}(...$arguments);
$result = $this->{$name}(...$arguments);

if (is_int($result)) {
return Integer_::createBy($result);
}

if (is_string($result)) {
return String_::createBy($result);
}

return $result;
}

return $this->{$name}(
Expand Down
3 changes: 2 additions & 1 deletion src/VM/Core/Runtime/Main.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
namespace RubyVM\VM\Core\Runtime;

use RubyVM\VM\Core\Helper\ClassHelper;
use RubyVM\VM\Core\Runtime\BasicObject\Kernel\Kernel;
use RubyVM\VM\Core\Runtime\BasicObject\Symbolizable;
use RubyVM\VM\Core\Runtime\Essential\MainInterface;
use RubyVM\VM\Core\YARV\Criterion\ShouldBeRubyClass;
use RubyVM\VM\Core\YARV\Essential\Symbol\StringSymbol;
use RubyVM\VM\Exception\OperationProcessorException;

class Main implements MainInterface
class Main extends Kernel implements MainInterface
{
use ShouldBeRubyClass;
use Symbolizable;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Tests\RubyVM\Version\RubyVM\Call\BasicObject\Kernel\Object_\Enumerable;

use RubyVM\VM\Core\Runtime\Executor\ExecutedStatus;
use Tests\RubyVM\Helper\TestApplication;

/**
* @internal
*
* @coversNothing
*/
class DirTest extends TestApplication
{
public function testPwd(): void
{
$rubyVMManager = $this->createRubyVMFromCode(
<<< '_'
puts Dir.pwd + "\n"
_,
);

$executor = $rubyVMManager
->rubyVM
->disassemble();

$this->assertSame(ExecutedStatus::SUCCESS, $executor->execute()->executedStatus);
$dir = getcwd();
$this->assertSame("{$dir}\n", $rubyVMManager->stdOut->readAll());
}

public function testCount(): void
{
$rubyVMManager = $this->createRubyVMFromCode(
<<< '_'
puts Dir.new(Dir.pwd).count.to_s + "\n"
_,
);

$executor = $rubyVMManager
->rubyVM
->disassemble();

$this->assertSame(ExecutedStatus::SUCCESS, $executor->execute()->executedStatus);
$count = count(iterator_to_array(new \DirectoryIterator(getcwd() ?: './')));
$this->assertSame("{$count}\n", $rubyVMManager->stdOut->readAll());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Tests\RubyVM\Version\RubyVM\Call\BasicObject\Kernel\Object_\Enumerable;

use RubyVM\VM\Core\Runtime\Executor\ExecutedStatus;
use Tests\RubyVM\Helper\TestApplication;

/**
* @internal
*
* @coversNothing
*/
class FileTest extends TestApplication
{
public function testRead(): void
{
$file = __FILE__;

$rubyVMManager = $this->createRubyVMFromCode(
<<< _
puts File.read("{$file}") + "\n"
_,
);

$executor = $rubyVMManager
->rubyVM
->disassemble();

$this->assertSame(ExecutedStatus::SUCCESS, $executor->execute()->executedStatus);
$this->assertSame(file_get_contents($file) . "\n", $rubyVMManager->stdOut->readAll());
}
}

0 comments on commit 3f3566e

Please sign in to comment.