mirror of
https://github.com/nasa/trick.git
synced 2024-12-18 20:57:55 +00:00
Improve parsing of base-clauses in S_define
A base-clause is the stuff in an inheritance list after the colon in a class declaration. https://en.cppreference.com/w/cpp/language/derived_class Closes #723 Closes #733
This commit is contained in:
parent
3364cd3836
commit
ef1d105bfb
@ -504,7 +504,7 @@ sub handle_sim_class ($$$$) {
|
|||||||
my ($s, $file_contents, $sim_ref, $comments_ref) = @_;
|
my ($s, $file_contents, $sim_ref, $comments_ref) = @_;
|
||||||
my ($full_template_args, $template_args) ;
|
my ($full_template_args, $template_args) ;
|
||||||
my ($class_contents , $constructor_contents) ;
|
my ($class_contents , $constructor_contents) ;
|
||||||
my ($class_name , $inherit_class, $inherit_constructor) ;
|
my ($class_name , $base_clause) ;
|
||||||
my $final_contents ;
|
my $final_contents ;
|
||||||
my $int_call_functions ;
|
my $int_call_functions ;
|
||||||
my $double_call_functions ;
|
my $double_call_functions ;
|
||||||
@ -518,7 +518,7 @@ sub handle_sim_class ($$$$) {
|
|||||||
$s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg ;
|
$s =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX//esg ;
|
||||||
|
|
||||||
# grab the class name and the name of the class we are inheriting from
|
# grab the class name and the name of the class we are inheriting from
|
||||||
($full_template_args, $class_name, $inherit_class) = $s =~ /(?:\s*template\s*<\s*([^>]+?)\s*>)?\s*class\s+(\w+)\s*(?::\s*public\s+(.+?)\s*)?$/ ;
|
($full_template_args, $class_name, $base_clause) = $s =~ /(?:\s*template\s*<\s*([^>]+?)\s*>)?\s*class\s+(\w+)\s*(?::\s*(.+?)\s*)?$/ ;
|
||||||
|
|
||||||
$template_args = $full_template_args ;
|
$template_args = $full_template_args ;
|
||||||
$template_args =~ s/class|typename//g ;
|
$template_args =~ s/class|typename//g ;
|
||||||
@ -535,10 +535,35 @@ sub handle_sim_class ($$$$) {
|
|||||||
#final_contents contains the processed class. Start if off with the incoming class name
|
#final_contents contains the processed class. Start if off with the incoming class name
|
||||||
$final_contents = $s ;
|
$final_contents = $s ;
|
||||||
|
|
||||||
my ($unparameterized_name) = $inherit_class =~ /([^<]+)/ ;
|
# remove all whitespace from the base-clause to simplify regex patterns
|
||||||
|
$base_clause =~ s/\s//g;
|
||||||
|
|
||||||
|
# This is the full regex for matching (I hope) any valid string following the ':' in a class
|
||||||
|
# declaration. (?1) is the syntax for recursive matching, which handles arbitrarily deeply
|
||||||
|
# nested template brackets. There are only two capture groups (the other groups are non-
|
||||||
|
# capturing). Because a class can inherit from any number of parents, the second group is
|
||||||
|
# repeated wth the * operator. Unfortunately, only the final capture is retained (until
|
||||||
|
# Perl 6), so we can't actually use this regex to capture all the parents. We could use it
|
||||||
|
# to validate the string, but the compiler is going to do that anyway.
|
||||||
|
#my @parents = $base_clause =~ /^(?:private|protected|public|virtual)*([\w:]+(?:<(?:[^<>]|(?1))*>)?)(?:,(?:private|protected|public)?((?1)))*$/;
|
||||||
|
|
||||||
|
# This regex is less strict and will accept some invalid strings, but it will capture all
|
||||||
|
# of the parents. Since the compiler will eventually flag any syntax errors, I think it's
|
||||||
|
# ok if we let them pass here.
|
||||||
|
my @parents = $base_clause =~ /\G,?(?:private|protected|public|virtual)*([\w:]+(?:<(?:[^<>]|(?1))*>)?)/g;
|
||||||
|
|
||||||
|
my $sim_object_parent;
|
||||||
|
foreach (@parents) {
|
||||||
|
# remove template arguments
|
||||||
|
($_) = $_ =~ /([^<]+)/;
|
||||||
|
if (exists $$sim_ref{sim_class_index}{$_}) {
|
||||||
|
$sim_object_parent = $_;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# if this class is not a SimObject pass it whole to S_Source.cpp
|
# if this class is not a SimObject pass it whole to S_Source.cpp
|
||||||
if ( $inherit_class eq "" or !exists $$sim_ref{sim_class_index}{$unparameterized_name} ) {
|
if ( !$sim_object_parent ) {
|
||||||
$class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/g ;
|
$class_contents =~ s/ZZZYYYXXX(\d+)ZZZYYYXXX/@$comments_ref[$1]/g ;
|
||||||
$final_contents .= "$class_contents ;\n\n" ;
|
$final_contents .= "$class_contents ;\n\n" ;
|
||||||
$$sim_ref{sim_class_code} .= $final_contents ;
|
$$sim_ref{sim_class_code} .= $final_contents ;
|
||||||
@ -564,7 +589,7 @@ sub handle_sim_class ($$$$) {
|
|||||||
$double_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n" ;
|
$double_call_functions .= " if ( curr_job->disabled ) return (trick_ret) ;\n\n" ;
|
||||||
$double_call_functions .= " switch ( curr_job->id ) {\n" ;
|
$double_call_functions .= " switch ( curr_job->id ) {\n" ;
|
||||||
|
|
||||||
$$sim_ref{sim_class_index}{$class_name} = $$sim_ref{sim_class_index}{$unparameterized_name} ;
|
$$sim_ref{sim_class_index}{$class_name} = $$sim_ref{sim_class_index}{$sim_object_parent} ;
|
||||||
|
|
||||||
# look for constructor
|
# look for constructor
|
||||||
while ( $class_contents =~ /^(.*?)$class_name\s*\([^;]*{/s ) {
|
while ( $class_contents =~ /^(.*?)$class_name\s*\([^;]*{/s ) {
|
||||||
@ -633,12 +658,12 @@ sub handle_sim_class ($$$$) {
|
|||||||
if ( $constructor_found == 1 ) {
|
if ( $constructor_found == 1 ) {
|
||||||
|
|
||||||
# if there is an inherited base class then the job id may reside in the base class
|
# if there is an inherited base class then the job id may reside in the base class
|
||||||
if ( $inherit_class eq "Trick::SimObject" or $inherit_class eq "SimObject" ) {
|
if ( $sim_object_parent eq "Trick::SimObject" or $sim_object_parent eq "SimObject" ) {
|
||||||
$int_call_functions .= " default:\n trick_ret = -1 ;\n break ;\n" ;
|
$int_call_functions .= " default:\n trick_ret = -1 ;\n break ;\n" ;
|
||||||
$double_call_functions .= " default:\n trick_ret = 0.0 ;\n break ;\n" ;
|
$double_call_functions .= " default:\n trick_ret = 0.0 ;\n break ;\n" ;
|
||||||
} else {
|
} else {
|
||||||
$int_call_functions .= " default:\n trick_ret = ${inherit_class}::call_function( curr_job ) ;\n break ;\n" ;
|
$int_call_functions .= " default:\n trick_ret = ${sim_object_parent}::call_function( curr_job ) ;\n break ;\n" ;
|
||||||
$double_call_functions .= " default:\n trick_ret = ${inherit_class}::call_function_double( curr_job ) ;\n break ;\n" ;
|
$double_call_functions .= " default:\n trick_ret = ${sim_object_parent}::call_function_double( curr_job ) ;\n break ;\n" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
$int_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n" ;
|
$int_call_functions .= " }\n\n return(trick_ret) ;\n}\n\n" ;
|
||||||
|
207
test/SIM_parse_s_define/S_define
Normal file
207
test/SIM_parse_s_define/S_define
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
#include "sim_objects/default_trick_sys.sm"
|
||||||
|
##include "Classes.hh"
|
||||||
|
|
||||||
|
// not sim objects, no namespace
|
||||||
|
class A : public Normal {
|
||||||
|
};
|
||||||
|
class B : public Template1<int> {};
|
||||||
|
class C : public Template2<int, Template1<Normal> > {};
|
||||||
|
|
||||||
|
// no namespace, sim object last
|
||||||
|
class D : public Normal, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
D() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromD : public D {
|
||||||
|
public:
|
||||||
|
DerivedFromD() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class E : public Template1<int>, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
E() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromE : public E {
|
||||||
|
public:
|
||||||
|
DerivedFromE() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class F : public Template2<int, Template1<Normal> >, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
F() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromF : public F {
|
||||||
|
public:
|
||||||
|
DerivedFromF() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// no namespace, sim object first
|
||||||
|
class G : public Trick::SimObject, public Normal {
|
||||||
|
public:
|
||||||
|
G() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromG : public G {
|
||||||
|
public:
|
||||||
|
DerivedFromG() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class H : public Trick::SimObject, public Template1<int> {
|
||||||
|
public:
|
||||||
|
H() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromH : public H {
|
||||||
|
public:
|
||||||
|
DerivedFromH() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class I : public Trick::SimObject, public Template2<int, Template1<Normal> > {
|
||||||
|
public:
|
||||||
|
I() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromI : public I {
|
||||||
|
public:
|
||||||
|
DerivedFromI() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// not sim objects, namespace
|
||||||
|
class J : public Foo::FooNormal {};
|
||||||
|
class K : public Foo::FooTemplate1<int> {};
|
||||||
|
class L : public Foo::FooTemplate2<int, Foo::FooTemplate1<Foo::FooNormal> > {};
|
||||||
|
|
||||||
|
// namespace, sim object last
|
||||||
|
class M : public Foo::FooNormal, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
M() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromM : public M {
|
||||||
|
public:
|
||||||
|
DerivedFromM() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class N : public Foo::FooTemplate1<int>, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
N() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromN : public N {
|
||||||
|
public:
|
||||||
|
DerivedFromN() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class O : public Foo::FooTemplate2<int, Foo::FooTemplate1<Foo::FooNormal> >, public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
O() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromO : public O {
|
||||||
|
public:
|
||||||
|
DerivedFromO() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// namespace, sim object first
|
||||||
|
class P : public Trick::SimObject, public Foo::FooNormal {
|
||||||
|
public:
|
||||||
|
P() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromP : public P {
|
||||||
|
public:
|
||||||
|
DerivedFromP() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class Q : public Trick::SimObject, public Foo::FooTemplate1<int> {
|
||||||
|
public:
|
||||||
|
Q() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromQ : public Q {
|
||||||
|
public:
|
||||||
|
DerivedFromQ() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class R : public Trick::SimObject, public Foo::FooTemplate2<int, Foo::FooTemplate1<Foo::FooNormal> > {
|
||||||
|
public:
|
||||||
|
R() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromR : public R {
|
||||||
|
public:
|
||||||
|
DerivedFromR() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SimObject templates!
|
||||||
|
template <class T>
|
||||||
|
class S : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
S() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromS : public S<int> {
|
||||||
|
public:
|
||||||
|
DerivedFromS() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <class U, class V>
|
||||||
|
class T : public S<int> {
|
||||||
|
public:
|
||||||
|
T() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromT : public T<int, Foo::FooTemplate1<Foo::FooNormal> > {
|
||||||
|
public:
|
||||||
|
DerivedFromT() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// crazy stuff
|
||||||
|
class Crazy1 : Foo::FooNormal, virtual Normal, private Template1<short*>, protected virtual Template2<Normal, Foo::FooTemplate2<int, char&> >, public Trick::SimObject, virtual public Foo::FooTemplate1<Foo::FooNormal> {
|
||||||
|
public:
|
||||||
|
Crazy1() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class DerivedFromCrazy1 : public Crazy1 {
|
||||||
|
public:
|
||||||
|
DerivedFromCrazy1() {
|
||||||
|
("initialization") foo();
|
||||||
|
}
|
||||||
|
};
|
2
test/SIM_parse_s_define/S_overrides.mk
Normal file
2
test/SIM_parse_s_define/S_overrides.mk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
TRICK_CFLAGS += -Imodels
|
||||||
|
TRICK_CXXFLAGS += -Imodels
|
1
test/SIM_parse_s_define/models/Classes.cpp
Normal file
1
test/SIM_parse_s_define/models/Classes.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
void foo() {};
|
22
test/SIM_parse_s_define/models/Classes.hh
Normal file
22
test/SIM_parse_s_define/models/Classes.hh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//@trick_link_dependency{Classes.cpp}
|
||||||
|
|
||||||
|
#ifndef CLASSES_HH
|
||||||
|
#define CLASSES_HH
|
||||||
|
|
||||||
|
#include "trick/SimObject.hh"
|
||||||
|
|
||||||
|
void foo();
|
||||||
|
|
||||||
|
class Normal {};
|
||||||
|
template <class T> class Template1 {};
|
||||||
|
template <class T, typename U> struct Template2 {};
|
||||||
|
|
||||||
|
namespace Foo {
|
||||||
|
|
||||||
|
class FooNormal {};
|
||||||
|
template <class T> class FooTemplate1 {};
|
||||||
|
template <class T, typename U> struct FooTemplate2 {};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -20,6 +20,7 @@ SIMS_NEEDING_TEST = \
|
|||||||
SIM_alloc_test \
|
SIM_alloc_test \
|
||||||
SIM_demo_inputfile \
|
SIM_demo_inputfile \
|
||||||
SIM_measurement_units \
|
SIM_measurement_units \
|
||||||
|
SIM_parse_s_define \
|
||||||
SIM_test_abstract \
|
SIM_test_abstract \
|
||||||
SIM_test_inherit \
|
SIM_test_inherit \
|
||||||
SIM_test_ip2 \
|
SIM_test_ip2 \
|
||||||
|
Loading…
Reference in New Issue
Block a user