diff --git a/prototypes/craftlang/README.md b/prototypes/craftlang/README.md index b4fd82a31b1..c73ca24ab50 100644 --- a/prototypes/craftlang/README.md +++ b/prototypes/craftlang/README.md @@ -7,15 +7,14 @@ of parsing `.craft` files and generating image outputs. ## Usage -This tool is written in [Raku](https://raku.org) and such you need to have `rakudo` -installed on your system. Additionally you need to make your minetest -assets tree and environment files available via ennvironment -variables. +This tool is written in [Raku](https://raku.org) and such you need to +have `rakudo` installed on your system. Additionally you need to make +your minetest assets tree and environment files available via +ennvironment variables. ```console -$ env MTCRAFT_ENV_PATH=/path/to/environments \ - MINETEST_ASSETS=/path/to/minetest/assets/root \ - craftlangc ./path-to-recipe.mtcraft +$ craftlangc ./path-to-recipe.mtcraft --env=/path/to/environments \ + --assets=/path/to/minetest/assets/root ``` @@ -56,9 +55,9 @@ to have nested `ENV`, `INPUTS`, and `OUTPUTS` scopes. ### Environment files -The environment provided via the `ENV` keyword must be present in the -`MTCRAFT_ENV_PATH`. An environment specifies the input-output -mappings for `INPUTS` and `OUTPUTS` scopes. +The environment provided via the `ENV` keyword must be present as a +`.craftenv` file in the provided `ENV` parameter. An environment +specifies the input-output mappings for `INPUTS` and `OUTPUTS` scopes. Required keywords for an ENV file are `BG`, `INPUTS`, `MODE`, and `OUTPUTS`. The `SPACING` keyword is permitted outside of the `INPUTS` diff --git a/prototypes/craftlang/craftlangc b/prototypes/craftlang/craftlangc index 240f46a278e..bb9520aa089 100755 --- a/prototypes/craftlang/craftlangc +++ b/prototypes/craftlang/craftlangc @@ -1,10 +1,10 @@ #!/usr/bin/env raku grammar FileGrammar { - # The top-level file is a list of statements + # The top-level file is a list of lines token TOP { ^ * %% \v* $ } - # A line is either a list of keyword-payload or scope + # A line is either a statement or scope token line { | } # A statement is a simple keyword-payload mapping @@ -17,12 +17,12 @@ grammar FileGrammar { token payload { \S+ %% \h* } # A scope is a scope-word + list of scope-lines - token scope { * } + token scope { + } # The set of scope-opening keywords token scope-word { < INPUTS OUTPUTS > } - # A scope line is either a simple payload or a full statement + # A scope is 2-space indented and either a statement or payload token scope-line { \v+ \h \h [ | ] } } @@ -52,13 +52,37 @@ class Actions { method scope-word($/) { make ~$/ } } -sub MAIN($file, Bool :$verbose) { +sub load_env($path, $env, $verbose) { + unless "$path/$env.craftenv".IO.e { + say "Required environment '$env' not found in search path '$path'!"; + exit 2; + } + + my $input = slurp "$path/$env.craftenv"; + say "Parsing input: $input" if $verbose; + + my @parsed = FileGrammar.parse($input, actions => Actions.new).made; + @parsed.map({ if $_ ~~ Str:D { + $_ => $_ + } else { + $_ => $_.map({ $_ => $_}).Hash + } + }).Hash +} + +sub MAIN($file, Str :$env="/dev/null", Str :$assets, Bool :$verbose) { + + # Load and parse the main input file my $input = slurp $file; say "Parsing input: $input" if $verbose; - - my @parse = FileGrammar.parse($input, actions => Actions.new).made; + my @parsed = FileGrammar.parse($input, actions => Actions.new).made; + my %tree = @parsed.map({ $_ => $_ ~~ Str:D ?? $_ !! $_.map({ $_ }) }).Hash; - for @parse -> %line { - say %line - } + # Load and parse the environment tree from the loaded input + my %env = load_env($env, %tree, $verbose); + + # Print both for good measure + %tree.say; + %env.say; + } diff --git a/prototypes/craftlang/test.cl b/prototypes/craftlang/test.cl deleted file mode 100644 index 438baa2ed1c..00000000000 --- a/prototypes/craftlang/test.cl +++ /dev/null @@ -1,6 +0,0 @@ -ENV alloys -INPUTS - copper_ingot 7 - tin_ingot 1 -OUTPUTS - bronze_ingot 8 \ No newline at end of file