-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake-modules.raku
More file actions
94 lines (79 loc) · 3.55 KB
/
make-modules.raku
File metadata and controls
94 lines (79 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use v6;
use experimental :rakuast;
use CSS::Specification::Compiler :&build-metadata;
use NativeCall;
sub path(RakuAST::Package $p) {
$p.name.parts>>.name.join: '/';
}
class Build {
method build($where) {
indir $where, {
my %props;
my Pair @metadata;
for (:CSS1[<src css1-properties.txt> => <CSS1>],
:CSS21[<src css21-properties.txt> => <CSS21>],
:CSS3[<src css3x-font-properties.txt> => <CSS3 Fonts>,
<src css3x-paged-media.txt> => <CSS3 PagedMedia>,
<src css-values-3-20240322.txt> => <CSS3 Values_and_Units>,
],
:SVG[<src svg-properties.txt> => <SVG>],
'CSS3::Fonts::AtFontFace' => [<src css3x-font-@fontface-properties.txt> => <CSS3 Fonts AtFontFace>],
) {
my $meta-root = .key;
%props = () if $meta-root eq 'CSS3::Fonts::AtFontFace';
for .value.list {
my ($input-spec, $class-isa) = .kv;
my @base-id = flat <CSS Module>, @$class-isa, <Gen>;
my @grammar-id = @base-id.Slip, 'Grammar';
my $scope := 'unit';
my CSS::Specification::Compiler $compiler .= new;
my $file = $input-spec.join: '/';
my @defs = $compiler.load-defs: :$file;
my %child-props = $compiler.child-props;
my RakuAST::Package $grammar-ast = $compiler.build-grammar(@grammar-id, :$scope);
"lib/{$grammar-ast.&path}.rakumod".IO.spurt: $grammar-ast.DEPARSE;
my @actions-id = @base-id.Slip, 'Actions';
my RakuAST::Package $actions-ast = $compiler.build-actions(@actions-id, :$scope);
"lib/{$actions-ast.&path}.rakumod".IO.spurt: $actions-ast.DEPARSE;
my @external-id = @base-id.Slip, 'External';
my RakuAST::Package $external-ast = $compiler.build-external(@external-id, :$scope);
"lib/{$external-ast.&path}.rakumod".IO.spurt: $external-ast.DEPARSE;
my %meta = @defs.&build-metadata(:%child-props);
%props ,= %meta;
}
%props.&write-metadata($meta-root);
}
}
}
}
sub write-metadata(%props, $meta) {
my $class-dir = $*SPEC.catdir(<lib CSS Module>, $meta.split('::').Slip);
my $class-path = $*SPEC.catfile( $class-dir, 'Metadata.rakumod' );
my $class-name = "CSS::Module::{$meta}::Metadata";
say "Building $class-name";
{
my $*OUT = open $class-path, :w;
say "# -- DO NOT EDIT --";
say "# generated by: $*PROGRAM-NAME {@*ARGS}".trim;
say 'use NativeCall;';
say 'use CSS::Module::Property;';
say '';
say "module $class-name \{";
say " BEGIN our \$property = {%props.item.raku};";
# todo: BEGIN our \$index = ... ; ## Missing serialize REPR function for REPR
say ' our enum prop-names <' ~ %props.keys.sort.join(' ') ~ '>;';
say q:to<END>;
our sub index {
state $ //= do {
my $enums := prop-names.enums;
CArray[CSS::Module::Property].new: |$property.sort.map({CSS::Module::Property.new(:$enums, name => .key, |.value)});
}
}
}
END
$*OUT.close;
}
}
sub MAIN(Str $working-directory = '.' ) {
Build.new.build($working-directory);
}