craftlang: parse both input file and associate environment

main
Katharina Fey 2 years ago
parent 40d5cd5e6b
commit e65fc2d2d3
Signed by: kookie
GPG Key ID: 90734A9E619C8A6C
  1. 19
      prototypes/craftlang/README.md
  2. 44
      prototypes/craftlang/craftlangc
  3. 6
      prototypes/craftlang/test.cl

@ -7,15 +7,14 @@ of parsing `.craft` files and generating image outputs.
## Usage ## Usage
This tool is written in [Raku](https://raku.org) and such you need to have `rakudo` This tool is written in [Raku](https://raku.org) and such you need to
installed on your system. Additionally you need to make your minetest have `rakudo` installed on your system. Additionally you need to make
assets tree and environment files available via ennvironment your minetest assets tree and environment files available via
variables. ennvironment variables.
```console ```console
$ env MTCRAFT_ENV_PATH=/path/to/environments \ $ craftlangc ./path-to-recipe.mtcraft --env=/path/to/environments \
MINETEST_ASSETS=/path/to/minetest/assets/root \ --assets=/path/to/minetest/assets/root
craftlangc ./path-to-recipe.mtcraft
``` ```
@ -56,9 +55,9 @@ to have nested `ENV`, `INPUTS`, and `OUTPUTS` scopes.
### Environment files ### Environment files
The environment provided via the `ENV` keyword must be present in the The environment provided via the `ENV` keyword must be present as a
`MTCRAFT_ENV_PATH`. An environment specifies the input-output `.craftenv` file in the provided `ENV` parameter. An environment
mappings for `INPUTS` and `OUTPUTS` scopes. specifies the input-output mappings for `INPUTS` and `OUTPUTS` scopes.
Required keywords for an ENV file are `BG`, `INPUTS`, `MODE`, and Required keywords for an ENV file are `BG`, `INPUTS`, `MODE`, and
`OUTPUTS`. The `SPACING` keyword is permitted outside of the `INPUTS` `OUTPUTS`. The `SPACING` keyword is permitted outside of the `INPUTS`

@ -1,10 +1,10 @@
#!/usr/bin/env raku #!/usr/bin/env raku
grammar FileGrammar { grammar FileGrammar {
# The top-level file is a list of statements # The top-level file is a list of lines
token TOP { ^ <line>* %% \v* $ } token TOP { ^ <line>* %% \v* $ }
# A line is either a list of keyword-payload or scope # A line is either a statement or scope
token line { <statement> | <scope> } token line { <statement> | <scope> }
# A statement is a simple keyword-payload mapping # A statement is a simple keyword-payload mapping
@ -17,12 +17,12 @@ grammar FileGrammar {
token payload { \S+ %% \h* } token payload { \S+ %% \h* }
# A scope is a scope-word + list of scope-lines # A scope is a scope-word + list of scope-lines
token scope { <scope-word> <scope-line>* } token scope { <scope-word> <scope-line>+ }
# The set of scope-opening keywords # The set of scope-opening keywords
token scope-word { < INPUTS OUTPUTS > } 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 [ <statement> | <payload> ] } token scope-line { \v+ \h \h [ <statement> | <payload> ] }
} }
@ -52,13 +52,37 @@ class Actions {
method scope-word($/) { make ~$/ } 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 $_<Payload> ~~ Str:D {
$_<Keyword> => $_<Payload>
} else {
$_<Keyword> => $_<Payload>.map({ $_<Keyword> => $_<Payload>}).Hash
}
}).Hash
}
sub MAIN($file, Str :$env="/dev/null", Str :$assets, Bool :$verbose) {
# Load and parse the main input file
my $input = slurp $file; my $input = slurp $file;
say "Parsing input: $input" if $verbose; say "Parsing input: $input" if $verbose;
my @parsed = FileGrammar.parse($input, actions => Actions.new).made;
my @parse = FileGrammar.parse($input, actions => Actions.new).made; my %tree = @parsed.map({ $_<Keyword> => $_<Payload> ~~ Str:D ?? $_<Payload> !! $_<Payload>.map({ $_<Payload> }) }).Hash;
for @parse -> %line { # Load and parse the environment tree from the loaded input
say %line my %env = load_env($env, %tree<ENV>, $verbose);
}
# Print both for good measure
%tree.say;
%env.say;
} }

@ -1,6 +0,0 @@
ENV alloys
INPUTS
copper_ingot 7
tin_ingot 1
OUTPUTS
bronze_ingot 8
Loading…
Cancel
Save