|
@@ -118,11 +118,14 @@ my %PARSE_TABLE = (
|
|
|
'title' => '^Title: (.*)$',
|
|
|
'mod_path' => '^ModuleDir\ "(.*)"$',
|
|
|
'import' => '^import (Module)::([a-zA-Z0-9]{1,})::([a-zA-Z0-9]{1,})(.*$)',
|
|
|
- 'set' => '^set\ (.*)$',
|
|
|
+ 'set' => '^set\ (.*)$',
|
|
|
+ 'connect' => '^connect(.*)$',
|
|
|
);
|
|
|
|
|
|
my %PARSE_RULES = (
|
|
|
- 'comment' => sub {},
|
|
|
+ 'comment' => sub {
|
|
|
+ # Do nothing, throw this line out
|
|
|
+ },
|
|
|
'title' => sub {
|
|
|
my $title = shift;
|
|
|
$AST{'Title'} = $title;
|
|
@@ -136,14 +139,21 @@ my %PARSE_RULES = (
|
|
|
push(@module_library_paths, $file_path);
|
|
|
},
|
|
|
'import' => sub {
|
|
|
- my $module_path = shift;
|
|
|
+ my $module_import = shift;
|
|
|
+ my $import_manu = shift;
|
|
|
+ my $import_mod = shift;
|
|
|
+ my $import_as = shift;
|
|
|
my @module_files = sub {
|
|
|
my @files;
|
|
|
foreach my $path ( @module_library_paths ) {
|
|
|
my @f = split("\n", `find $path`);
|
|
|
foreach my $file ( @f ) {
|
|
|
if ( $file =~ m/.module$/ ) {
|
|
|
- push(@files, $file);
|
|
|
+ my $f_bn = `basename $file`;
|
|
|
+ chomp $f_bn;
|
|
|
+ if ( ! grep(/$f_bn/, @files) ) {
|
|
|
+ push(@files, $file);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -153,18 +163,103 @@ my %PARSE_RULES = (
|
|
|
my $mod_file_content = read_to_var($mod_file);
|
|
|
my $mod_ref = parse_module_file($mod_file_content);
|
|
|
|
|
|
- foreach my $ref ( @{$AST{'Modules'}} ) {
|
|
|
- if ( $$mod_ref{'Manufacturer'} eq $$ref{'Manufacturer'} &&
|
|
|
- $$mod_ref{'Rev'} eq $$ref{'Rev'} ) {
|
|
|
- # We've already imported this module
|
|
|
- next;
|
|
|
+ if ( $import_mod eq $$mod_ref{'Module'} ) {
|
|
|
+
|
|
|
+ if ( defined $AST{'Modules'} ) {
|
|
|
+ my $r = grep { $import_mod eq $_->{'Module'} } @{$AST{'Modules'}};
|
|
|
+ if ( $r == 0 ) {
|
|
|
+ push(@{$AST{'Modules'}}, $mod_ref);
|
|
|
+ }
|
|
|
} else {
|
|
|
push(@{$AST{'Modules'}}, $mod_ref);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 'set' => sub {
|
|
|
+ my $set_line = shift;
|
|
|
+ my $mod_to_set;
|
|
|
+ my $attr_to_set;
|
|
|
+ my $attr_param;
|
|
|
+ my $value;
|
|
|
+ my $setter = sub {
|
|
|
+ my $mod_to_set = shift;
|
|
|
+ my $attr_to_set = shift;
|
|
|
+ my $attr_param = shift;
|
|
|
+ if ( $attr_param eq "position" ) {
|
|
|
+ $attr_param = "pos";
|
|
|
+ }
|
|
|
+ my $value = shift;
|
|
|
+
|
|
|
+ my %set_params = (
|
|
|
+ 'Param' => $attr_param,
|
|
|
+ 'Value' => $value,
|
|
|
+ );
|
|
|
+
|
|
|
+ # Check values against mod definition
|
|
|
+ # Pull mod ref out of AST for straight forward checking
|
|
|
+ my $mod_ref;
|
|
|
+ # Check we have module in AST
|
|
|
+ my $r = grep { $mod_to_set eq $_->{'Module'} } @{$AST{'Modules'}};
|
|
|
+ if ( $r eq 0 ) {
|
|
|
+ die "Can't set value on module that is not imported: $mod_to_set\n";
|
|
|
+ } else {
|
|
|
+ foreach my $module_ref ( @{$AST{'Modules'}} ) {
|
|
|
+ if ( $mod_to_set eq $$module_ref{'Module'} ) {
|
|
|
+ $mod_ref = $module_ref;
|
|
|
+ last;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ # Check that module has param we want to set
|
|
|
+ if ( ! $attr_to_set eq $$mod_ref{'Inputs'}->{$attr_to_set} ) {
|
|
|
+ die "Can't set a param that doesn't existing in the module spec: $attr_to_set";
|
|
|
+ }
|
|
|
+
|
|
|
+ # If the set has an attr param, check that it's in the allowed range on the attr
|
|
|
+ if ( $attr_param ne "null" ) {
|
|
|
+ my $attr_range = $$mod_ref{'Inputs'}->{$attr_to_set}->{'pos'};
|
|
|
+ if ( $attr_range =~ m/([0-9]{1,2})\-([0-9]{1,2})/ ) {
|
|
|
+ my $r_begin = $1;
|
|
|
+ my $r_end = $2;
|
|
|
+ if ( $value > $r_end || $value < $r_begin ) {
|
|
|
+ die "Parse error: attr_param value: $value for $attr_to_set : $attr_param is outside of range: $r_begin $r_end";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ die "Somehow encountered parse error in setter for module file $$mod_ref{'Module'}\n";
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ $AST{'Sets'}->{$mod_to_set}->{$attr_to_set} = \%set_params;
|
|
|
+ };
|
|
|
+
|
|
|
+ if ( $set_line =~ m/(^[A-Z]{1}[a-z]{1,})\.{1}([A-Za-z0-9]{1,})\ \=\ (.*)$/ ) {
|
|
|
+ $mod_to_set = $1;
|
|
|
+ $attr_to_set = $2;
|
|
|
+ $value = $3;
|
|
|
+ } elsif ( $set_line =~ m/(^[A-Z]{1}[a-z]{1,})\.{1}([A-Za-z0-9]{1,})\.([A-Za-z0-9]{1,})\ \=\ (.*)$/ ) {
|
|
|
+ $mod_to_set = $1;
|
|
|
+ $attr_to_set = $2;
|
|
|
+ $attr_param = $3;
|
|
|
+ $value = $4;
|
|
|
+ } else {
|
|
|
+ die "Parse error at $set_line";
|
|
|
}
|
|
|
+
|
|
|
+ if ( ! defined $attr_param || $attr_param eq "" ) {
|
|
|
+ $attr_param = "null",
|
|
|
+ };
|
|
|
+
|
|
|
+ $setter->($mod_to_set,$attr_to_set,$attr_param,$value);
|
|
|
+ },
|
|
|
+ 'connect' => sub {
|
|
|
+ my $connect_line = shift;
|
|
|
+ $connect_line = trim($connect_line);
|
|
|
},
|
|
|
- 'set' => sub { print("$_[0]\n"); },
|
|
|
+
|
|
|
);
|
|
|
|
|
|
# Basic line parser
|
|
@@ -179,8 +274,11 @@ sub line_parse($) {
|
|
|
}
|
|
|
|
|
|
if ( $line_type ne "null" && $line =~ m/$PARSE_TABLE{$line_type}/) {
|
|
|
- if ( defined $1 ) {
|
|
|
+ if ( defined $1 && ! defined $2 ) {
|
|
|
$PARSE_RULES{$line_type}->($1);
|
|
|
+ } elsif ( defined $1 && defined $2 && defined $3 && defined $4 ) {
|
|
|
+ # This is for `import`
|
|
|
+ $PARSE_RULES{$line_type}->($1,$2,$3,$4);
|
|
|
} else {
|
|
|
$PARSE_RULES{$line_type}->();
|
|
|
}
|