|
|
@ -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 %tree = @parsed.map({ $_<Keyword> => $_<Payload> ~~ Str:D ?? $_<Payload> !! $_<Payload>.map({ $_<Payload> }) }).Hash; |
|
|
|
|
|
|
|
|
|
|
|
my @parse = FileGrammar.parse($input, actions => Actions.new).made; |
|
|
|
# Load and parse the environment tree from the loaded input |
|
|
|
|
|
|
|
my %env = load_env($env, %tree<ENV>, $verbose); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Print both for good measure |
|
|
|
|
|
|
|
%tree.say; |
|
|
|
|
|
|
|
%env.say; |
|
|
|
|
|
|
|
|
|
|
|
for @parse -> %line { |
|
|
|
|
|
|
|
say %line |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|