From e2b8f1d7aa390cde18e60b6105b979c03ebc0ddb Mon Sep 17 00:00:00 2001 From: Joop Schilder Date: Fri, 8 May 2020 00:37:29 +0200 Subject: [PATCH] Initial commit --- .gitignore | 7 + README.md | 13 + bin/app.php | 14 + composer.json | 21 + composer.lock | 752 ++++++++++++++++++++ programs/part/.gitignore | 0 programs/sub/.gitignore | 0 src/Automata/Definitions.php | 94 +++ src/Automata/Machine.php | 74 ++ src/Automata/Modes/G/DimensionMode.php | 11 + src/Automata/Modes/G/G.php | 24 + src/Automata/Modes/G/PlaneSelection.php | 11 + src/Automata/Modes/G/RadiusCompensation.php | 11 + src/Automata/Modes/G/TraverseMode.php | 11 + src/Automata/Modes/G/WorkCycle.php | 17 + src/Automata/Modes/M/CoolantMode.php | 29 + src/Automata/Modes/M/M.php | 24 + src/Automata/Modes/M/SpindleMode.php | 26 + src/Automata/Modes/M/TableClampingMode.php | 11 + src/Automata/Registers.php | 21 + src/Automata/State.php | 70 ++ src/Automata/Storage/ProgramMemory.php | 27 + src/Automata/Storage/ToolMemory.php | 23 + src/Automata/Tool.php | 18 + src/Program/Block.php | 23 + src/Program/Program.php | 38 + src/Program/ProgramParser.php | 77 ++ src/Program/Word.php | 28 + src/ProgramLoader.php | 22 + 29 files changed, 1497 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 bin/app.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 programs/part/.gitignore create mode 100644 programs/sub/.gitignore create mode 100644 src/Automata/Definitions.php create mode 100644 src/Automata/Machine.php create mode 100644 src/Automata/Modes/G/DimensionMode.php create mode 100644 src/Automata/Modes/G/G.php create mode 100644 src/Automata/Modes/G/PlaneSelection.php create mode 100644 src/Automata/Modes/G/RadiusCompensation.php create mode 100644 src/Automata/Modes/G/TraverseMode.php create mode 100644 src/Automata/Modes/G/WorkCycle.php create mode 100644 src/Automata/Modes/M/CoolantMode.php create mode 100644 src/Automata/Modes/M/M.php create mode 100644 src/Automata/Modes/M/SpindleMode.php create mode 100644 src/Automata/Modes/M/TableClampingMode.php create mode 100644 src/Automata/Registers.php create mode 100644 src/Automata/State.php create mode 100644 src/Automata/Storage/ProgramMemory.php create mode 100644 src/Automata/Storage/ToolMemory.php create mode 100644 src/Automata/Tool.php create mode 100644 src/Program/Block.php create mode 100644 src/Program/Program.php create mode 100644 src/Program/ProgramParser.php create mode 100644 src/Program/Word.php create mode 100644 src/ProgramLoader.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c79e77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/.idea/ +/vendor/ +/programs/*/* +!.gitignore + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..4da6362 --- /dev/null +++ b/README.md @@ -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 +``` diff --git a/bin/app.php b/bin/app.php new file mode 100644 index 0000000..97c362a --- /dev/null +++ b/bin/app.php @@ -0,0 +1,14 @@ +toolMemory->save(new Tool(1, 5500, 2)); +$machine->toolMemory->save(new Tool(2, 3000, 61379)); +(new ProgramLoader)->loadPrograms($machine); + +$machine->loadProgram(9002); +$machine->start(); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..6be7abd --- /dev/null +++ b/composer.json @@ -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" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..107dd47 --- /dev/null +++ b/composer.lock @@ -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" +} diff --git a/programs/part/.gitignore b/programs/part/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/programs/sub/.gitignore b/programs/sub/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/Automata/Definitions.php b/src/Automata/Definitions.php new file mode 100644 index 0000000..df29ba2 --- /dev/null +++ b/src/Automata/Definitions.php @@ -0,0 +1,94 @@ + '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]; + } +} diff --git a/src/Automata/Machine.php b/src/Automata/Machine.php new file mode 100644 index 0000000..b9bf4aa --- /dev/null +++ b/src/Automata/Machine.php @@ -0,0 +1,74 @@ +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; + } +} diff --git a/src/Automata/Modes/G/DimensionMode.php b/src/Automata/Modes/G/DimensionMode.php new file mode 100644 index 0000000..3556e3c --- /dev/null +++ b/src/Automata/Modes/G/DimensionMode.php @@ -0,0 +1,11 @@ +G = $G; + } + + + public final function apply(int $G): void + { + if ($this->supports($G)) { + $this->G = $G; + } + } + + + public abstract function supports(int $G): bool; +} diff --git a/src/Automata/Modes/G/PlaneSelection.php b/src/Automata/Modes/G/PlaneSelection.php new file mode 100644 index 0000000..02cb3a2 --- /dev/null +++ b/src/Automata/Modes/G/PlaneSelection.php @@ -0,0 +1,11 @@ +supports($M)) { + return; + } + if (in_array($M, [0, 2, 6, 30])) { + $this->M = 9; + + return; + } + + // 8 or 9 + $this->M = $M; + } + +} diff --git a/src/Automata/Modes/M/M.php b/src/Automata/Modes/M/M.php new file mode 100644 index 0000000..bee8211 --- /dev/null +++ b/src/Automata/Modes/M/M.php @@ -0,0 +1,24 @@ +M = $M; + } + + + public function apply(int $M): void + { + if ($this->supports($M)) { + $this->M = $M; + } + } + + + public abstract function supports(int $M): bool; +} diff --git a/src/Automata/Modes/M/SpindleMode.php b/src/Automata/Modes/M/SpindleMode.php new file mode 100644 index 0000000..95bdb04 --- /dev/null +++ b/src/Automata/Modes/M/SpindleMode.php @@ -0,0 +1,26 @@ +supports($M)) { + return; + } + if (in_array($M, [0, 2, 6, 30])) { + $this->M = 5; + + return; + } + // 3, 4 or 5 + $this->M = $M; + } +} diff --git a/src/Automata/Modes/M/TableClampingMode.php b/src/Automata/Modes/M/TableClampingMode.php new file mode 100644 index 0000000..93e087d --- /dev/null +++ b/src/Automata/Modes/M/TableClampingMode.php @@ -0,0 +1,11 @@ +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; + } + } +} diff --git a/src/Automata/Storage/ProgramMemory.php b/src/Automata/Storage/ProgramMemory.php new file mode 100644 index 0000000..f565302 --- /dev/null +++ b/src/Automata/Storage/ProgramMemory.php @@ -0,0 +1,27 @@ +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]; + } +} diff --git a/src/Automata/Storage/ToolMemory.php b/src/Automata/Storage/ToolMemory.php new file mode 100644 index 0000000..2ad8c2c --- /dev/null +++ b/src/Automata/Storage/ToolMemory.php @@ -0,0 +1,23 @@ +memory[$tool->T] = $tool; + } + + + public function read(int $T): ?Tool + { + return @$this->memory[$T]; + } +} diff --git a/src/Automata/Tool.php b/src/Automata/Tool.php new file mode 100644 index 0000000..6004806 --- /dev/null +++ b/src/Automata/Tool.php @@ -0,0 +1,18 @@ +T = $T; + $this->X = $X; + $this->Z = $Z; + } +} diff --git a/src/Program/Block.php b/src/Program/Block.php new file mode 100644 index 0000000..9861a55 --- /dev/null +++ b/src/Program/Block.php @@ -0,0 +1,23 @@ +N = $N; + $this->words = []; + } + + + public function addWord(Word $word): void + { + $this->words[] = $word; + } +} diff --git a/src/Program/Program.php b/src/Program/Program.php new file mode 100644 index 0000000..ec6411d --- /dev/null +++ b/src/Program/Program.php @@ -0,0 +1,38 @@ +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); + } +} diff --git a/src/Program/ProgramParser.php b/src/Program/ProgramParser.php new file mode 100644 index 0000000..88c5d55 --- /dev/null +++ b/src/Program/ProgramParser.php @@ -0,0 +1,77 @@ +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; + } +} diff --git a/src/Program/Word.php b/src/Program/Word.php new file mode 100644 index 0000000..37a3e70 --- /dev/null +++ b/src/Program/Word.php @@ -0,0 +1,28 @@ +register = $register; + $this->value = $value; + } + + + public function toString(): string + { + return "{$this->register}{$this->value}"; + } + + + public function __toString() + { + return $this->toString(); + } +} diff --git a/src/ProgramLoader.php b/src/ProgramLoader.php new file mode 100644 index 0000000..9749c3c --- /dev/null +++ b/src/ProgramLoader.php @@ -0,0 +1,22 @@ +parseFile($partProgramFile); + $machine->partProgramMemory->save($partProgram); + } + + foreach (glob(__DIR__ . '/../programs/sub/*') as $subProgramFile) { + $subProgram = $parser->parseFile($subProgramFile); + $machine->subProgramMemory->save($subProgram); + } + } +}