Initial commit
This commit is contained in:
commit
e2b8f1d7aa
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/.idea/
|
||||
/vendor/
|
||||
/programs/*/*
|
||||
!.gitignore
|
||||
|
||||
|
||||
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
### Philips CNC6600 NC System Interpreter
|
||||
This is an interpreter for programs written for the MAHO MH-C 700.
|
||||
It basically creates a state-machine that represents the Philips NC system.
|
||||
|
||||
Written in PHP, because why not?
|
||||
|
||||
#### Usage
|
||||
Put parts programs (plain text) in `/programs/part`, put subpart programs (plain text) in `/programs/sub`.
|
||||
|
||||
To see what's working so far; run
|
||||
```bash
|
||||
php bin/app.php
|
||||
```
|
14
bin/app.php
Normal file
14
bin/app.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Automata\Machine;
|
||||
use Automata\Tool;
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$machine = new Machine();
|
||||
$machine->toolMemory->save(new Tool(1, 5500, 2));
|
||||
$machine->toolMemory->save(new Tool(2, 3000, 61379));
|
||||
(new ProgramLoader)->loadPrograms($machine);
|
||||
|
||||
$machine->loadProgram(9002);
|
||||
$machine->start();
|
21
composer.json
Normal file
21
composer.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "joop/philips-cnc6600-interpreter",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Joop Schilder",
|
||||
"email": "jnmschilder@protonmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"": "src"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-json": "*",
|
||||
"ext-readline": "*",
|
||||
"symfony/var-dumper": "^5.0",
|
||||
"illuminate/support": "^7.10"
|
||||
}
|
||||
}
|
752
composer.lock
generated
Normal file
752
composer.lock
generated
Normal file
@ -0,0 +1,752 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1e9e0fcf3c3cc215c6ab1cd71d6bb903",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/inflector.git",
|
||||
"reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/inflector/zipball/ec3a55242203ffa6a4b27c58176da97ff0a7aec1",
|
||||
"reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"inflection",
|
||||
"pluralize",
|
||||
"singularize",
|
||||
"string"
|
||||
],
|
||||
"time": "2019-10-30T19:59:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v7.10.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
"reference": "5681c90368ffafaaa2e12c42112e344281466f23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/contracts/zipball/5681c90368ffafaaa2e12c42112e344281466f23",
|
||||
"reference": "5681c90368ffafaaa2e12c42112e344281466f23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"psr/container": "^1.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Contracts\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Contracts package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-05-06T13:37:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v7.10.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "cd11fa914c52a2249c48cde08d03a871597e8781"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/cd11fa914c52a2249c48cde08d03a871597e8781",
|
||||
"reference": "cd11fa914c52a2249c48cde08d03a871597e8781",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "^1.1",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"illuminate/contracts": "^7.0",
|
||||
"nesbot/carbon": "^2.17",
|
||||
"php": "^7.2.5",
|
||||
"voku/portable-ascii": "^1.4.8"
|
||||
},
|
||||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/filesystem": "Required to use the composer class (^7.0).",
|
||||
"moontoast/math": "Required to use ordered UUIDs (^1.1).",
|
||||
"ramsey/uuid": "Required to use Str::uuid() (^3.7|^4.0).",
|
||||
"symfony/process": "Required to use the composer class (^5.0).",
|
||||
"symfony/var-dumper": "Required to use the dd function (^5.0).",
|
||||
"vlucas/phpdotenv": "Required to use the Env class and env helper (^4.0)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Support package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"time": "2020-05-05T16:21:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "4d93cb95a80d9ffbff4018fe58ae3b7dd7f4b99b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4d93cb95a80d9ffbff4018fe58ae3b7dd7f4b99b",
|
||||
"reference": "4d93cb95a80d9ffbff4018fe58ae3b7dd7f4b99b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.1.8 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.0",
|
||||
"symfony/translation": "^3.4 || ^4.0 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/orm": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^2.14 || ^3.0",
|
||||
"kylekatarnls/multi-tester": "^1.1",
|
||||
"phpmd/phpmd": "^2.8",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpunit/phpunit": "^7.5 || ^8.0",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"bin": [
|
||||
"bin/carbon"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "http://nesbot.com"
|
||||
},
|
||||
{
|
||||
"name": "kylekatarnls",
|
||||
"homepage": "http://github.com/kylekatarnls"
|
||||
}
|
||||
],
|
||||
"description": "An API extension for DateTime that supports 281 different languages.",
|
||||
"homepage": "http://carbon.nesbot.com",
|
||||
"keywords": [
|
||||
"date",
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/Carbon",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-04-20T15:05:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/container.git",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||
"homepage": "https://github.com/php-fig/container",
|
||||
"keywords": [
|
||||
"PSR-11",
|
||||
"container",
|
||||
"container-interface",
|
||||
"container-interop",
|
||||
"psr"
|
||||
],
|
||||
"time": "2017-02-14T16:28:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
],
|
||||
"time": "2017-10-23T01:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-03-09T19:04:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v5.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "c3879db7a68fe3e12b41263b05879412c87b27fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/c3879db7a68fe3e12b41263b05879412c87b27fd",
|
||||
"reference": "c3879db7a68fe3e12b41263b05879412c87b27fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/translation-contracts": "^2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/config": "<4.4",
|
||||
"symfony/dependency-injection": "<5.0",
|
||||
"symfony/http-kernel": "<5.0",
|
||||
"symfony/twig-bundle": "<5.0",
|
||||
"symfony/yaml": "<4.4"
|
||||
},
|
||||
"provide": {
|
||||
"symfony/translation-implementation": "2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/config": "^4.4|^5.0",
|
||||
"symfony/console": "^4.4|^5.0",
|
||||
"symfony/dependency-injection": "^5.0",
|
||||
"symfony/finder": "^4.4|^5.0",
|
||||
"symfony/http-kernel": "^5.0",
|
||||
"symfony/intl": "^4.4|^5.0",
|
||||
"symfony/service-contracts": "^1.1.2|^2",
|
||||
"symfony/yaml": "^4.4|^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log-implementation": "To use logging capability in translator",
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Translation\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-04-12T16:45:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
"version": "v2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation-contracts.git",
|
||||
"reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed",
|
||||
"reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/translation-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Translation\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to translation",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"time": "2019-11-18T17:27:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v5.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "09de28632f16f81058a85fcf318397218272a07b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/09de28632f16f81058a85fcf318397218272a07b",
|
||||
"reference": "09de28632f16f81058a85fcf318397218272a07b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpunit/phpunit": "<5.4.3",
|
||||
"symfony/console": "<4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-iconv": "*",
|
||||
"symfony/console": "^4.4|^5.0",
|
||||
"symfony/process": "^4.4|^5.0",
|
||||
"twig/twig": "^2.4|^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
|
||||
"ext-intl": "To show region name in time zone dump",
|
||||
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
|
||||
},
|
||||
"bin": [
|
||||
"Resources/bin/var-dump-server"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions/dump.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\VarDumper\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony mechanism for exploring and dumping PHP variables",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-04-12T16:45:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
"version": "1.4.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/voku/portable-ascii.git",
|
||||
"reference": "240e93829a5f985fab0984a6e55ae5e26b78a334"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/voku/portable-ascii/zipball/240e93829a5f985fab0984a6e55ae5e26b78a334",
|
||||
"reference": "240e93829a5f985fab0984a6e55ae5e26b78a334",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.0 || ~7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "Use Intl for transliterator_transliterate() support"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"voku\\": "src/voku/",
|
||||
"voku\\tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Lars Moelleken",
|
||||
"homepage": "http://www.moelleken.org/"
|
||||
}
|
||||
],
|
||||
"description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
|
||||
"homepage": "https://github.com/voku/portable-ascii",
|
||||
"keywords": [
|
||||
"ascii",
|
||||
"clean",
|
||||
"php"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.me/moelleken",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/voku",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/voku",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-03-13T01:23:26+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"ext-ctype": "*",
|
||||
"ext-json": "*",
|
||||
"ext-readline": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
0
programs/part/.gitignore
vendored
Normal file
0
programs/part/.gitignore
vendored
Normal file
0
programs/sub/.gitignore
vendored
Normal file
0
programs/sub/.gitignore
vendored
Normal file
94
src/Automata/Definitions.php
Normal file
94
src/Automata/Definitions.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Automata;
|
||||
|
||||
use Program\Word;
|
||||
|
||||
class Definitions
|
||||
{
|
||||
private array $G = [
|
||||
// traverse mode
|
||||
0 => 'Rapid traverse', // Default
|
||||
1 => 'Linear interpolation',
|
||||
2 => 'Circular interpolation (CW)',
|
||||
3 => 'Circular interpolation (CCW)',
|
||||
|
||||
// quest-ce-que c'est?
|
||||
4 => 'Dwell',
|
||||
|
||||
// plane selection mode
|
||||
17 => 'Plane selection (XY-plane)', // Default
|
||||
18 => 'Plane selection (XZ-plane)',
|
||||
19 => 'Plane selection (YZ-plane)',
|
||||
|
||||
// extra functionality (one shot)
|
||||
21 => 'Parameter definition for SP (G21 E1 X1000 sets E1 to 1000)',
|
||||
22 => 'Call up of SP through X',
|
||||
23 => 'Addition of parameters in SP (G23 E030201 sets E03 = E02 + E01)',
|
||||
24 => 'Subtraction of parameters in SP (G23 E030201 sets E03 = E02 - E01)',
|
||||
25 => 'Parameter association in SP for storing',
|
||||
26 => '100% feed, no override possible',
|
||||
29 => 'Skip instruction in SP (G29 E2 X50 means jump to after 50 if E2 > 0)',
|
||||
|
||||
// radius compensation mode
|
||||
40 => 'Radius compensation not effective', // default
|
||||
41 => 'Radius compensation to left of workpiece',
|
||||
42 => 'Radius compensation to right of workpiece',
|
||||
43 => 'Radius compensation, axially parallel, positive',
|
||||
44 => 'Radius compensation, axially parallel, negative',
|
||||
|
||||
// call workcycle
|
||||
79 => 'Activation of a work cycle',
|
||||
|
||||
// work cycle selection
|
||||
81 => 'Work cycle for drilling',
|
||||
84 => 'Work cycle for tapping',
|
||||
85 => 'Work cycle for reaming',
|
||||
86 => 'Work cycle for boring',
|
||||
|
||||
// dimension modes
|
||||
90 => 'Absolute dimension programming', // Default
|
||||
91 => 'Incremental dimension programming',
|
||||
|
||||
// shift zero datum (one shot)
|
||||
92 => 'Incremental zero datum shift',
|
||||
93 => 'Absolute zero datum shift',
|
||||
|
||||
// reference to zero
|
||||
98 => 'Automatic positioning to reference datum point',
|
||||
];
|
||||
private array $M = [
|
||||
0 => 'Programmed stop (Sets M5 and M9)',
|
||||
2 => 'End of program (Sets M5 and M9)',
|
||||
3 => 'Spindle start CW (CCW in G18)',
|
||||
4 => 'Spindle start CCW (CW in G18)',
|
||||
5 => 'Spindle stop',
|
||||
6 => 'Tool change (Sets M5 and M9)',
|
||||
|
||||
// coolant control
|
||||
8 => 'Coolant on',
|
||||
9 => 'Coolant off',
|
||||
|
||||
// table clamping (unsupported)
|
||||
10 => 'Table clamping - close',
|
||||
11 => 'Table clamping - open',
|
||||
|
||||
30 => 'End of program with skip back to start (Sets M5 and M9)',
|
||||
67 => 'Enter new tool information without machine stop',
|
||||
];
|
||||
private array $S = [
|
||||
0, 40, 50, 63, 80, 100, 125, 160, 200, 250,
|
||||
315, 400, 500, 630, 800, 1000, 1250, 1600, 2000,
|
||||
];
|
||||
|
||||
public function hasPredefinedValue(Word $word): bool
|
||||
{
|
||||
return in_array($word->register, ['G', 'M']);
|
||||
}
|
||||
|
||||
|
||||
public function translatePredefinedValue(Word $word): ?string
|
||||
{
|
||||
return @$this->{$word->register}[$word->value];
|
||||
}
|
||||
}
|
74
src/Automata/Machine.php
Normal file
74
src/Automata/Machine.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Automata;
|
||||
|
||||
use Automata\Storage\ProgramMemory;
|
||||
use Automata\Storage\ToolMemory;
|
||||
use Program\Program;
|
||||
use Program\Word;
|
||||
use RuntimeException;
|
||||
use SplStack;
|
||||
|
||||
class Machine
|
||||
{
|
||||
public State $state;
|
||||
public ToolMemory $toolMemory;
|
||||
public ProgramMemory $subProgramMemory;
|
||||
public ProgramMemory $partProgramMemory;
|
||||
/** @var SplStack|Program[] */
|
||||
private SplStack $programStack;
|
||||
private ?Program $activeProgram = null;
|
||||
private Definitions $definitions;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->state = new State();
|
||||
$this->definitions = new Definitions();
|
||||
$this->toolMemory = new ToolMemory();
|
||||
$this->subProgramMemory = new ProgramMemory();
|
||||
$this->partProgramMemory = new ProgramMemory();
|
||||
$this->programStack = new SplStack();
|
||||
}
|
||||
|
||||
|
||||
public function loadProgram(int $N): void
|
||||
{
|
||||
$this->programStack = new SplStack();
|
||||
$program = $this->partProgramMemory->read($N);
|
||||
$this->programStack->push($program);
|
||||
}
|
||||
|
||||
|
||||
public function start(): void
|
||||
{
|
||||
$this->activeProgram = $this->programStack->pop();
|
||||
if (is_null($this->activeProgram)) {
|
||||
throw new RuntimeException('No program loaded');
|
||||
}
|
||||
foreach ($this->activeProgram as $block) {
|
||||
// Do we apply a block or a word?
|
||||
// Answer: depends! Some commands need
|
||||
// more information from other words.
|
||||
// TODO: Interpret commands such as preparation of a work cycle
|
||||
|
||||
$words = array_map(fn(Word $w) => $w->toString(), $block->words);
|
||||
$words = implode("\t", $words);
|
||||
$words = "N{$block->N}\t$words";
|
||||
|
||||
foreach ($block->words as $word) {
|
||||
$this->state->apply($word);
|
||||
system('clear');
|
||||
print("\n $words\n\n");
|
||||
dump($this->state);
|
||||
readline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->activeProgram = null;
|
||||
}
|
||||
}
|
11
src/Automata/Modes/G/DimensionMode.php
Normal file
11
src/Automata/Modes/G/DimensionMode.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
class DimensionMode extends G
|
||||
{
|
||||
public function supports(int $G): bool
|
||||
{
|
||||
return in_array($G, [90, 91]);
|
||||
}
|
||||
}
|
24
src/Automata/Modes/G/G.php
Normal file
24
src/Automata/Modes/G/G.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
abstract class G
|
||||
{
|
||||
public int $G;
|
||||
|
||||
public function __construct(int $G)
|
||||
{
|
||||
$this->G = $G;
|
||||
}
|
||||
|
||||
|
||||
public final function apply(int $G): void
|
||||
{
|
||||
if ($this->supports($G)) {
|
||||
$this->G = $G;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract function supports(int $G): bool;
|
||||
}
|
11
src/Automata/Modes/G/PlaneSelection.php
Normal file
11
src/Automata/Modes/G/PlaneSelection.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
class PlaneSelection extends G
|
||||
{
|
||||
public function supports(int $G): bool
|
||||
{
|
||||
return in_array($G, [17, 18, 19]);
|
||||
}
|
||||
}
|
11
src/Automata/Modes/G/RadiusCompensation.php
Normal file
11
src/Automata/Modes/G/RadiusCompensation.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
class RadiusCompensation extends G
|
||||
{
|
||||
public function supports(int $G): bool
|
||||
{
|
||||
return in_array($G, [40, 41, 42, 43, 44]);
|
||||
}
|
||||
}
|
11
src/Automata/Modes/G/TraverseMode.php
Normal file
11
src/Automata/Modes/G/TraverseMode.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
class TraverseMode extends G
|
||||
{
|
||||
public function supports(int $G): bool
|
||||
{
|
||||
return in_array($G, [0, 1, 2, 3]);
|
||||
}
|
||||
}
|
17
src/Automata/Modes/G/WorkCycle.php
Normal file
17
src/Automata/Modes/G/WorkCycle.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\G;
|
||||
|
||||
class WorkCycle extends G
|
||||
{
|
||||
public int $X = 0;
|
||||
public int $Y = 0;
|
||||
public int $Z = 0;
|
||||
public int $B = 0;
|
||||
|
||||
|
||||
public function supports(int $G): bool
|
||||
{
|
||||
return in_array($G, [81, 84, 85, 86]);
|
||||
}
|
||||
}
|
29
src/Automata/Modes/M/CoolantMode.php
Normal file
29
src/Automata/Modes/M/CoolantMode.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\M;
|
||||
|
||||
class CoolantMode extends M
|
||||
{
|
||||
|
||||
public function supports(int $M): bool
|
||||
{
|
||||
return in_array($M, [0, 2, 6, 8, 9, 30]);
|
||||
}
|
||||
|
||||
|
||||
public function apply(int $M): void
|
||||
{
|
||||
if (!$this->supports($M)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($M, [0, 2, 6, 30])) {
|
||||
$this->M = 9;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 8 or 9
|
||||
$this->M = $M;
|
||||
}
|
||||
|
||||
}
|
24
src/Automata/Modes/M/M.php
Normal file
24
src/Automata/Modes/M/M.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\M;
|
||||
|
||||
abstract class M
|
||||
{
|
||||
public int $M;
|
||||
|
||||
public function __construct(int $M)
|
||||
{
|
||||
$this->M = $M;
|
||||
}
|
||||
|
||||
|
||||
public function apply(int $M): void
|
||||
{
|
||||
if ($this->supports($M)) {
|
||||
$this->M = $M;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract function supports(int $M): bool;
|
||||
}
|
26
src/Automata/Modes/M/SpindleMode.php
Normal file
26
src/Automata/Modes/M/SpindleMode.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\M;
|
||||
|
||||
class SpindleMode extends M
|
||||
{
|
||||
public function supports(int $M): bool
|
||||
{
|
||||
return in_array($M, [0, 2, 3, 4, 5, 6, 30]);
|
||||
}
|
||||
|
||||
|
||||
public function apply(int $M): void
|
||||
{
|
||||
if (!$this->supports($M)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($M, [0, 2, 6, 30])) {
|
||||
$this->M = 5;
|
||||
|
||||
return;
|
||||
}
|
||||
// 3, 4 or 5
|
||||
$this->M = $M;
|
||||
}
|
||||
}
|
11
src/Automata/Modes/M/TableClampingMode.php
Normal file
11
src/Automata/Modes/M/TableClampingMode.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Modes\M;
|
||||
|
||||
class TableClampingMode extends M
|
||||
{
|
||||
public function supports(int $M): bool
|
||||
{
|
||||
return in_array($M, [10, 11]);
|
||||
}
|
||||
}
|
21
src/Automata/Registers.php
Normal file
21
src/Automata/Registers.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Automata;
|
||||
|
||||
class Registers
|
||||
{
|
||||
public int $B = 0; // Traverse information
|
||||
public int $X = 0; // Dimension along X-axis
|
||||
public int $Y = 0; // Dimension along Y-axis
|
||||
public int $Z = 0; // Dimension along Z-axis
|
||||
public int $N = 0; // Current line or program number
|
||||
public int $I = 0; // Circle centre, X-axis
|
||||
public int $J = 0; // Circle centre, Y-axis
|
||||
public int $K = 0; // Circle centre, Z-axis
|
||||
public int $F = 0; // Feed in 0.1 mm/min
|
||||
public int $S = 0; // Spindle speed in RPM
|
||||
public int $T = 0; // Tool number
|
||||
public int $H = 0; // Additional functions (unused)
|
||||
public int $M = 0; // Auxiliary functions
|
||||
public int $E = 0; // Number of repetitions / multiple meanins
|
||||
}
|
70
src/Automata/State.php
Normal file
70
src/Automata/State.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Automata;
|
||||
|
||||
use Automata\Modes\G\DimensionMode;
|
||||
use Automata\Modes\G\PlaneSelection;
|
||||
use Automata\Modes\G\RadiusCompensation;
|
||||
use Automata\Modes\G\TraverseMode;
|
||||
use Automata\Modes\G\WorkCycle;
|
||||
use Automata\Modes\M\CoolantMode;
|
||||
use Automata\Modes\M\SpindleMode;
|
||||
use Automata\Modes\M\TableClampingMode;
|
||||
use Program\Word;
|
||||
|
||||
class State
|
||||
{
|
||||
public Registers $registers;
|
||||
// G
|
||||
public TraverseMode $traverseMode;
|
||||
public PlaneSelection $planeSelection;
|
||||
public RadiusCompensation $radiusCompensation;
|
||||
public DimensionMode $dimensionMode;
|
||||
public WorkCycle $workCycleSelection;
|
||||
// M
|
||||
public CoolantMode $coolantMode;
|
||||
public SpindleMode $spindleMode;
|
||||
public TableClampingMode $tableClamping;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->registers = new Registers();
|
||||
$this->traverseMode = new TraverseMode(0);
|
||||
$this->planeSelection = new PlaneSelection(17);
|
||||
$this->radiusCompensation = new RadiusCompensation(40);
|
||||
$this->dimensionMode = new DimensionMode(90);
|
||||
$this->workCycleSelection = new WorkCycle(0);
|
||||
|
||||
$this->coolantMode = new CoolantMode(9);
|
||||
$this->spindleMode = new SpindleMode(5);
|
||||
$this->tableClamping = new TableClampingMode(10);
|
||||
}
|
||||
|
||||
|
||||
public function apply(Word $word): void
|
||||
{
|
||||
if ($word->register === 'G') {
|
||||
$this->traverseMode->apply($word->value);
|
||||
$this->planeSelection->apply($word->value);
|
||||
$this->radiusCompensation->apply($word->value);
|
||||
$this->dimensionMode->apply($word->value);
|
||||
$this->workCycleSelection->apply($word->value);
|
||||
|
||||
// TODO Handle other G commands
|
||||
return;
|
||||
}
|
||||
if ($word->register === 'M') {
|
||||
$this->coolantMode->apply($word->value);
|
||||
$this->spindleMode->apply($word->value);
|
||||
$this->tableClamping->apply($word->value);
|
||||
|
||||
// TODO Handle other M commands
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_exists($this->registers, $word->register)) {
|
||||
$this->registers->{$word->register} = $word->value;
|
||||
}
|
||||
}
|
||||
}
|
27
src/Automata/Storage/ProgramMemory.php
Normal file
27
src/Automata/Storage/ProgramMemory.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Storage;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Program\Program;
|
||||
|
||||
class ProgramMemory
|
||||
{
|
||||
/** @var Program[] */
|
||||
private array $memory = [];
|
||||
|
||||
|
||||
public function save(Program $program): void
|
||||
{
|
||||
if ($program->N > 9998 || $program->N < 9001) {
|
||||
throw new InvalidArgumentException('Program number must be in range 9001 - 9998');
|
||||
}
|
||||
$this->memory[$program->N] = $program;
|
||||
}
|
||||
|
||||
|
||||
public function read(int $N): ?Program
|
||||
{
|
||||
return @$this->memory[$N];
|
||||
}
|
||||
}
|
23
src/Automata/Storage/ToolMemory.php
Normal file
23
src/Automata/Storage/ToolMemory.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Automata\Storage;
|
||||
|
||||
use Automata\Tool;
|
||||
|
||||
class ToolMemory
|
||||
{
|
||||
/** @var Tool[] */
|
||||
private array $memory = [];
|
||||
|
||||
|
||||
public function save(Tool $tool): void
|
||||
{
|
||||
$this->memory[$tool->T] = $tool;
|
||||
}
|
||||
|
||||
|
||||
public function read(int $T): ?Tool
|
||||
{
|
||||
return @$this->memory[$T];
|
||||
}
|
||||
}
|
18
src/Automata/Tool.php
Normal file
18
src/Automata/Tool.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Automata;
|
||||
|
||||
class Tool
|
||||
{
|
||||
public int $T; // Tool number
|
||||
public int $X; // Radius in 0.001 mm
|
||||
public int $Z; // Length offset in 0.002 mm
|
||||
|
||||
|
||||
public function __construct(int $T, int $X, int $Z)
|
||||
{
|
||||
$this->T = $T;
|
||||
$this->X = $X;
|
||||
$this->Z = $Z;
|
||||
}
|
||||
}
|
23
src/Program/Block.php
Normal file
23
src/Program/Block.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Program;
|
||||
|
||||
class Block
|
||||
{
|
||||
public string $N;
|
||||
/** @var Word[] */
|
||||
public array $words;
|
||||
|
||||
|
||||
public function __construct(string $N)
|
||||
{
|
||||
$this->N = $N;
|
||||
$this->words = [];
|
||||
}
|
||||
|
||||
|
||||
public function addWord(Word $word): void
|
||||
{
|
||||
$this->words[] = $word;
|
||||
}
|
||||
}
|
38
src/Program/Program.php
Normal file
38
src/Program/Program.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Program;
|
||||
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
class Program implements IteratorAggregate
|
||||
{
|
||||
public int $N;
|
||||
/** @var Block[] */
|
||||
private array $blocks;
|
||||
|
||||
|
||||
public function __construct(int $N)
|
||||
{
|
||||
$this->N = $N;
|
||||
$this->blocks = [];
|
||||
}
|
||||
|
||||
|
||||
public function addBlock(Block $block): self
|
||||
{
|
||||
$this->blocks[] = $block;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ArrayIterator|Traversable|Block[]
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->blocks);
|
||||
}
|
||||
}
|
77
src/Program/ProgramParser.php
Normal file
77
src/Program/ProgramParser.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Program;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ProgramParser
|
||||
{
|
||||
public function parseFile(string $filename): Program
|
||||
{
|
||||
$lines = explode(PHP_EOL, file_get_contents($filename));
|
||||
$lines = array_filter($lines);
|
||||
|
||||
return $this->parse($lines);
|
||||
}
|
||||
|
||||
|
||||
public function parse(array $lines): Program
|
||||
{
|
||||
// In the first parsing stage, all words are parsed from the file.
|
||||
/** @var Word[] $words */
|
||||
$words = [];
|
||||
foreach ($lines as $line) {
|
||||
$characters = str_split(trim($line) . ' ');
|
||||
$state = 'NONE';
|
||||
$wordBuffer = [];
|
||||
foreach ($characters as $character) {
|
||||
if ('READING' === $state) {
|
||||
if ('-' === $character || is_numeric($character)) {
|
||||
$wordBuffer['value'] .= $character;
|
||||
continue;
|
||||
}
|
||||
// Word is finished
|
||||
$words[] = new Word($wordBuffer['register'], $wordBuffer['value']);
|
||||
$wordBuffer = [];
|
||||
$state = 'NONE';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('NONE' === $state && ctype_alpha($character)) {
|
||||
$state = 'READING';
|
||||
$wordBuffer = ['register' => $character, 'value' => ''];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stripos($line, 'EOF') !== false) {
|
||||
break 2; // End of program reached
|
||||
}
|
||||
|
||||
if (';' === $character) {
|
||||
break; // Rest of line is a comment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In the second stage, the words are ordered by N numbers
|
||||
// and shaped into a program
|
||||
$firstWord = array_shift($words);
|
||||
if (!preg_match('/^N9\d\d\d$/i', $firstWord)) {
|
||||
throw new RuntimeException('Expected program number, got ' . $firstWord);
|
||||
}
|
||||
$program = new Program($firstWord->value);
|
||||
$lineBuffer = null;
|
||||
foreach ($words as $word) {
|
||||
if ($word->register === 'N') {
|
||||
if (!is_null($lineBuffer)) {
|
||||
$program->addBlock($lineBuffer);
|
||||
}
|
||||
$lineBuffer = new Block($word->value);
|
||||
continue;
|
||||
}
|
||||
$lineBuffer->addWord($word);
|
||||
}
|
||||
|
||||
return $program;
|
||||
}
|
||||
}
|
28
src/Program/Word.php
Normal file
28
src/Program/Word.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Program;
|
||||
|
||||
class Word
|
||||
{
|
||||
public string $register;
|
||||
public int $value;
|
||||
|
||||
|
||||
public function __construct(string $register, int $value)
|
||||
{
|
||||
$this->register = $register;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return "{$this->register}{$this->value}";
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->toString();
|
||||
}
|
||||
}
|
22
src/ProgramLoader.php
Normal file
22
src/ProgramLoader.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Automata\Machine;
|
||||
use Program\ProgramParser;
|
||||
|
||||
class ProgramLoader
|
||||
{
|
||||
public function loadPrograms(Machine $machine): void
|
||||
{
|
||||
$parser = new ProgramParser();
|
||||
|
||||
foreach (glob(__DIR__ . '/../programs/part/*') as $partProgramFile) {
|
||||
$partProgram = $parser->parseFile($partProgramFile);
|
||||
$machine->partProgramMemory->save($partProgram);
|
||||
}
|
||||
|
||||
foreach (glob(__DIR__ . '/../programs/sub/*') as $subProgramFile) {
|
||||
$subProgram = $parser->parseFile($subProgramFile);
|
||||
$machine->subProgramMemory->save($subProgram);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user