"Fossies" - the Fresh Open Source Software Archive

Member "RPerl-5.002000/docs/devs_getting_started.txt" (30 Aug 2019, 30605 Bytes) of package /linux/misc/RPerl-5.002000.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "devs_getting_started.txt" see the Fossies "Dox" file reference documentation.

    1 # RPerl System Developers
    2 # Getting Started, A How-To Guide
    3 # Last Updated 20160824 2016.208
    4 
    5 Welcome to RPerl, and thank you for your interest in joining the RPerl system developers!
    6 
    7 If you would like to create software libraries and applications (AKA "programs" or "apps") to be utilized by end-users, then this is not the correct document for you.
    8 Instead, please read the book Learning RPerl and join the RPerl application developers:
    9 
   10 Learning RPerl
   11 http://rperl.org/learning_rperl.html
   12 
   13 RPerl App Devs Group
   14 https://www.facebook.com/groups/1551887621787018
   15 
   16 RPerl App Devs Intake Board
   17 https://trello.com/b/XmmPJQJj/austin-pm-rperl-app-devs-intake
   18 
   19 If, however, you are interested in contributing to the development of the RPerl compiler itself, then you are in the right place!
   20 This document will take you through the steps required to create a new RPerl operator, which will help you start learning the basic architecture of RPerl.
   21 
   22 
   23 STEP 0.  Complete RPerl Developers Intake Process
   24 
   25 The intake process for RPerl system developers is the same as used for RPerl application developers.
   26 If you already have a Trello account, then please follow the URL for Trello above.
   27 If you have a Facebook account, then please submit a request to join at the URL below:
   28 
   29 RPerl System Devs Group
   30 https://www.facebook.com/groups/999476090136466
   31 
   32 If you have neither a Trello nor Facebook account, then please send an e-mail with the subject line "RPerl System Devs" to the address below (remove NOSPAM):
   33 william.braswell at NOSPAM.autoparallel.com
   34 
   35 
   36 STEP 1.  Choose An Operator
   37 
   38 When you have completed the intake process and are ready to start contributing, then the first main step is to choose an operator which has not yet been implemented.
   39 Start by opening up the URL below to Learning RPerl section 2.1.11, then perform a browser search for the string "Coming Soon":
   40 http://rperl.org/learning_rperl.html#Section_2.1.11%3A_Arithmetic_Operators
   41 
   42 You should be able to choose among most or all of the "Coming Soon" operators, although it is possible that another RPerl system developer is currently working on your first choice operator, so be sure to check with the lead developers on Trello and Facebook before finalizing your selection.
   43 
   44 For this example, we will choose the absolute value operator 'abs', implemented by our first authorized RPerl system developer, Pablo Rodríguez González. 
   45 Imagine that you are Pablo, and this is the process you are going through to implement the 'abs' operator.
   46 (Obviously you will not actually be implementing the 'abs' operator because Pablo already did, you will choose a different operator instead.) 
   47 
   48 Technically, absolute value is a "named operator", as found in the RPerl grammar file with the token OP01_NAMED_SCOLON:
   49 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Grammar.eyp
   50 
   51 By searching for 'OP01_NAMED_SCOLON' at the URL above, you can see a long list showing that all of Perl's named operators are already enabled, but in the grammar only.
   52 Also, search for the token 'OP10_NAMED_UNARY_SCOLON' to see all the "named unary operators", which are a type of named operator that accept exactly one argument.
   53 Many of the remaining non-named operators are already fully implemented, whereas most of the named operators are not yet implemented outside of the grammar.
   54 To see a list of all operators which are already (at least partially) implemented, view the URLs below:
   55 
   56 https://github.com/wbraswell/rperl/blob/master/lib/rperloperations.pm
   57 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Operation/Expression/Operator/Named
   58 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Operation/Expression/Operator/NamedUnary
   59 
   60 Some of the operators listed in the URL above are only partially implemented, in that they only support PERLOPS_PERLTYPES mode (see step 2 below for modes explanation), whereas we need both PERLOPS_PERLTYPES mode as well as CPPOPS_CPPTYPES mode implemented for each operator.  Thus, any operators which have a stub subroutine for CPPOPS_CPPTYPES mode are eligible for you to choose, simply search for anywhere the string 'DUMMY_SOURCE_CODE' appears inside a subroutine named 'ast_to_cpp__generate__CPPOPS_CPPTYPES()'.
   61 
   62 
   63 STEP 2.  Study Similar Operators
   64 
   65 From an RPerl system developer's point of view, absolute value is a named operator, as specified in the RPerl grammar and overall architecture.
   66 However, absolute value is included in the "Arithmetic Operators" section of Learning RPerl, for easier understanding by RPerl application developers.
   67 There is no "Named Operators" section of Learning RPerl, because it would be a long unorganized list which is not easy to grasp or utilize for reference.
   68 Again, absolute value is technically not an "Arithmetic Operator" like the '+' (addition) or '*' (multiplication) operators, even though they are all used for math.
   69 
   70 Thus, before implementing absolute value, you should study the existing implementations of other named operators at the URL below:
   71 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Operation/Expression/Operator/Named
   72 
   73 If you have instead chosen to implement a named unary operator, they may be found here:
   74 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Operation/Expression/Operator/NamedUnary 
   75 
   76 Each operator's Perl module file in the 2 URLs above has 3 primary subroutines, which correspond to RPerl's 3 primary modes, and each generate source code as output:
   77 
   78 ast_to_rperl__generate()
   79 ast_to_cpp__generate__CPPOPS_PERLTYPES()
   80 ast_to_cpp__generate__CPPOPS_CPPTYPES()
   81 
   82 The corresponding 3 primary modes of RPerl are:
   83 
   84 0.  Perl Operations & Perl Data Types, AKA "slow mode"   or "interpreted mode" or "test mode" or "normal Perl mode", runs via normal dynamic Perl interpreter, 1x speed
   85 1.  C++  Operations & Perl Data Types, AKA "medium mode" or "mixed mode", runs via combination of dynamic Perl interpreter & static C++ compiler, approx 7x - 10x speed 
   86 2.  C++  Operations & C++  Data Types, AKA "fast mode"   or "compiled mode", runs via static C++ compiler, approx 100x - 400x speed
   87 
   88 Each of these 3 code generation subroutines accepts as input an RPerl abstract syntax tree (AST), which is a Perl object (blessed hashref) data structure generated by lexing and parsing some RPerl application source code.  Because all named operators are combined together into just 2 groups in the RPerl grammar (named and named unary), they require special handling in the RPerl architecture.  All RPerl code generation subroutines use the same names as these 3 subroutines, and most RPerl code generation subroutines accept their AST argument in the $self variable as part of RPerl's object-oriented architecture.  However, the special handling for named operators causes use to receive an artificially-generated dummy object into the $self variable, while our real AST object is received into the $operator_named variable.
   89 
   90 All RPerl code generation subroutines also accept as their final input argument the globally-utilized $modes variable, which is a string_hashref data structure containing the current RPerl modes, symbol table, and a number of other possible flags or values required for proper RPerl functionality.  The $modes variable should be passed as the final argument to all RPerl code generation subroutines, as well as many (or perhaps most) other RPerl system subroutines.
   91 
   92 Each of the subroutines generates as output a source group variable, which is another Perl string_hashref data structure containing all generated source code.  In the PERLOPS_PERLTYPES code generation subroutines, this return value variable is named $rperl_source group, and in the other 2 modes it is named $cpp_source_group.  Each key in the source group hashes is the all-uppercase equivalent of the generated source code file suffix, so in PERLOPS_PERLTYPES mode the $rperl_source_group hash variable only contains the key 'PMC' ("Perl Module Compiled"), and all generated Perl source code is stored within the corresponding 'PMC' hash value, which could eventually be saved to a file ending with the suffix '.pmc'.  The generated '.pmc' file should be exactly equivalent to the original '.pm' input file, not counting code comments, which is why PERLOPS_PERLTYPES is also called "test mode", as the original RPerl input source code is completely parsed and then generated back into the matching original form as a test of the RPerl grammar, etc.
   93 
   94 In CPPOPS_PERLTYPES and CPPOPS_CPPTYPES modes, the $cpp_source_group hash variable contains at least the 'CPP' key which can be saved to a '.cpp' output C++ source code file.  The $cpp_source_group hash may also contain 'H' and 'PMC' keys, although most named operators will only need to output into the 'CPP' source code.
   95 
   96 The PERLOPS_PERLTYPES subroutine is implemented first for all operators, and in the cases where an operator's Perl module file has already been created, there should already be a completed 'ast_to_rperl__generate()' subroutine present.  The CPPOPS_PERLTYPES mode is currently not implemented for most RPerl operators, and will be left as a stub containing "DUMMY_SOURCE_CODE" until a later version of RPerl.  The CPPOPS_CPPTYPES mode is the main focus of our RPerl system development efforts, because it offers the most speed benefits by far.  Do not attempt to implement any CPPOPS_PERLTYPES code whatsoever, only the other 2 modes.
   97 
   98 
   99 STEP 3.  Make A Fork On GitHub
  100 
  101 If you did not already have a GitHub account, then you should have created one during step 0.
  102 Also, you should know how to use git itself, at least the basic functionality, or else you could end up accidentally messing up your own code and losing work!
  103 
  104 Now you will create your own fork of RPerl on GitHub, which means you will have your own new copy of RPerl in a GitHub repository (AKA "repo").
  105 This forked repository will contain all your new code changes, without accidentally breaking the main RPerl repo.
  106 
  107 While logged in to your GitHub account, visit the URL below and select the "Fork" button in the upper-right, then follow the instructions:
  108 https://github.com/wbraswell/rperl
  109 
  110 For all commits you make in any branches of your new repo, please always use the following format for git commit messages:
  111 Operator, Absolute Value, Your Concise Message Here
  112 
  113 In the next step, you will notice the commits by Pablo do not use this uniform message format, while the commits from Will do use the proper format.
  114 
  115 You may optionally create as many branches as you like within your new forked repository, or you can stay at 1 branch in the new repo to keep it simple.
  116 In step 7, you will carefully merge your new code back in to the main RPerl repo.
  117 
  118 
  119 STEP 4.  Create Tests, Part 1
  120 
  121 We will practice test-driven development (TDD), which means you should create at least 1 of your new 'abs' tests before you create your actual Perl module file.
  122 At this point the new 'abs' operator is not implemented in RPerl except for parsing through the RPerl grammar, but 'abs' will work just fine in normal interpreted Perl code, which is why you can write some tests before fully implementing the operator itself.
  123 This is a bit of a chicken-and-egg issue, because you will not be able to run your new tests through the `rperl` command until after you complete steps 5 and 6.
  124 Thus, we have split the creation of tests into 2 parts, step 4 and step 7.
  125 
  126 First, you will create a new test directory "lib/RPerl/Test/Operator01NamedAbsoluteValue" containing test files for the 'abs' operator.
  127 For this step, it is likely you will go through a similar process of development as you will experience while creating the Perl module file in step 5.
  128 (Please see step 5 for a relatively thorough explanation of the multi-commit development thought process, for brevity I will not repeat it in this step.)
  129 
  130 As in step 5, you find the most similar reference file with CPPOPS_CPPTYPES already implemented is the named unary 'scalar' operator, which has tests here:
  131 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Test/Operator10NamedUnaryScalar
  132 
  133 You make a copy of the file "lib/RPerl/Test/Operator10NamedUnaryScalar/program_00_good.pl" into "lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl".
  134 (In reality, you can copy 'scalar' operator files for named unary operators, and you can copy 'abs' operator files for non-unary named operators.)
  135 
  136 You notice the file names for all tests contain either "Good", "good", "Bad", or "bad"; this tells RPerl if the test file should succeed or fail.
  137 All "good" tests with file names ending in ".pl" should contain the following RPerl preprocessor directive:
  138 # <<< EXECUTE_SUCCESS: 'FOO' >>>
  139 
  140 All "bad" tests should contain exactly 1 of the following RPerl preprocessor directives:
  141 # <<< PARSE_ERROR: 'FOO' >>>
  142 # <<< GENERATE_ERROR: 'FOO' >>>
  143 # <<< COMPILE_ERROR: 'FOO' >>>
  144 # <<< EXECUTE_ERROR: 'FOO' >>>
  145 
  146 Finally, edit your newly-copied test file named "program_00_good.pl", so it tests proper usage of the new 'abs' operator instead of the 'scalar' operator.
  147 Be sure the file uses the 'print' operator to display meaningful output.
  148 Manually run the test program to ensure it at least executes correctly via the normal Perl interpreter, without the `rperl` command involved:
  149 $ lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  150 
  151 
  152 STEP 5.  Create The Operator's Perl Module File
  153 
  154 You will be creating a new file named 'lib/RPerl/Operation/Expression/Operator/Named/AbsoluteValue.pm' which will contain most of your new code.
  155 
  156 To find a file which you can use as a starting template, you start by looking in the directory containing all named operators:
  157 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Operation/Expression/Operator/Named
  158 
  159 You see that RPerl support for the 'chomp' operator only allows the low-magic 'chomp VARIABLE' syntax, which is similar to the 'abs VALUE' syntax you need to support:
  160 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Operation/Expression/Operator/Named/Chomp.pm
  161 
  162 Thus, you create a copy of the "Chomp.pm" file and rename it to "AbsoluteValue.pm", then begin changing anywhere specific to 'chomp' to become 'abs', etc.
  163 
  164 Follow the URL below to see Pablo's first commit of the Perl module file, which includes support for PERLOPS_PERLTYPES mode only:
  165 https://github.com/wbraswell/rperl/blob/4d997f91a52a34d8f4fa1a47830bc246aacd736e/lib/RPerl/Operation/Expression/Operator/Named/AbsoluteValue.pm
  166 
  167 But wait!  While you were working, a change was made to the RPerl grammar in the main RPerl repo, so we have to update the grammar rule serial numbers as seen here:
  168 https://github.com/wbraswell/rperl/commit/9d6b53f447a370869fb32835d1266a4f7f825f2e#diff-fc9b0cbe0168b9b1c7ec7026ea8175efL9
  169 
  170 Hopefully you won't have a grammar change happen while you are working on your own operator, but as we can see it is definitely possible.
  171 
  172 Next, you have noticed that you need to implement CPPOPS_CPPTYPES, because the 'chomp' operator only supports PERLOPS_PERLTYPES.
  173 The most similar reference file with CPPOPS_CPPTYPES already implemented is the named unary 'scalar' operator:
  174 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Operation/Expression/Operator/NamedUnary/Scalar.pm
  175 
  176 So you copy the ast_to_cpp__generate__CPPOPS_CPPTYPES() subroutine from "Scalar.pm" into your new "AbsoluteValue.pm" and modify as needed:
  177 https://github.com/wbraswell/rperl/blob/99f74bd40d0214713f92c4efaac746f89d0821d6/lib/RPerl/Operation/Expression/Operator/Named/AbsoluteValue.pm
  178 
  179 (As in step 4, in reality you can copy 'scalar' operator files for named unary operators, and you can copy 'abs' operator files for non-unary named operators.)
  180 
  181 And we forgot to change the PERLOPS_PERLTYPES error code to the correct format for CPPOPS_CPPTYPES, so you fix that:
  182 https://github.com/wbraswell/rperl/commit/1350e0bbe8a21659faa4798f536e78fafe720034
  183 
  184 Next, you realize we want our generated C++ code to match the original RPerl input source code as closely as possible, which means we want to generate 'abs' in C++ instead of 'std::abs', which is achieved by removing 'std::' from "AbsoluteValue.pm" and adding a C++ '#define' statement to the "rperloperations.h" file:
  185 https://github.com/wbraswell/rperl/commit/3153a85327dd7116eeb757692c05d2ec077ada2d#diff-fc9b0cbe0168b9b1c7ec7026ea8175efL111
  186 https://github.com/wbraswell/rperl/commit/3153a85327dd7116eeb757692c05d2ec077ada2d#diff-1e5c0f27b0c43112d615cf4e6b903899R16
  187 
  188 Oops, another bug!  (Remember this one, we'll revist it shortly...)
  189 We can not add extra parentheses where there were none required, so they must be removed:
  190 https://github.com/wbraswell/rperl/commit/c893b70e9e047c6a7a0f9b1d9029c2f5195af53f#diff-fc9b0cbe0168b9b1c7ec7026ea8175efL114
  191 
  192 All RPerl source code files should be auto-formatted using the Perltidy utility:
  193 http://perltidy.sourceforge.net
  194 
  195 It is important that you are using the official RPerl formatting configuration file, contained within the Perltidy run commands ("RC") file:
  196 https://github.com/wbraswell/lampuniversity.org/blob/master/docs/.perltidyrc
  197 
  198 When formatted with the correct Perltidy RC file, you see some minor cosmetic changes:
  199 https://github.com/wbraswell/rperl/commit/272a7ffc7a515839803168dd696bd1ae2711d06d#diff-fc9b0cbe0168b9b1c7ec7026ea8175efL21
  200 
  201 Almost there!  You forgot to update the 'abs' calling convention in the Perl module file's "DOCUMENTATION" section, so you fix that minor error:
  202 https://github.com/wbraswell/rperl/commit/125160fb375b9378f42069ce49473c87d6783ea2#diff-fc9b0cbe0168b9b1c7ec7026ea8175efL2
  203 
  204 Last but not least, you realize that you actually DID need to generate extra parentheses after all, in order to avoid a C++ compiler error:
  205 $ rperl -V -D -nop lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  206 "... cannot resolve overloaded function ‘abs’ based on conversion to type ..."
  207 
  208 So it was actually a bug to remove the parentheses, and thus you replace them to finish this step:
  209 https://github.com/wbraswell/rperl/commit/e99125474340ca3f1867ff77ccadb9693e9dec6c#diff-fc9b0cbe0168b9b1c7ec7026ea8175efR103
  210 
  211 To test your new operator in PERLOPS_PERLTYPES mode, run this command:
  212 $ rperl -V -D -nop -t lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  213 
  214 To test your new operator in CPPOPS_CPPTYPES mode, run these 2 commands:
  215 $ rperl -V -D -nop lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  216 $ ./lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good
  217 
  218 DEBUGGING NOTES #1:
  219 The '-V' command-line argument turns on "verbose" output, and the '-D' argument turns on "debugging" or "diagnostic" output.
  220 These 2 arguments are exactly equivalent to setting the 'RPERL_VERBOSE=1' and 'RPERL_DEBUG=1' environmental variables. 
  221 Within any RPerl system file, such as your "AbsoluteValue.pm" module file, all verbose output must be displayed by using the 'RPerl::verbose()' subroutine.
  222 Similarly, any RPerl system file should display all debugging output via the identical 'RPerl::diag()' or 'RPerl::debug()' subroutines, which are interchangeable.
  223 Within any RPerl application file, such as your "program_00_good.pl" test file, all normal output should be displayed using the 'print' operator.
  224 If an RPerl application file requires actual debugging output, you may use either the normal 'print' operator or the 'print {*STDERR}' variant.
  225 (Technically, RPerl apps can also call 'RPerl::verbose()' and friends, but this would be an app generating system output, which is probably not right.)
  226 Verbose output is meant to be viewed by our users (RPerl application developers), so most calls to 'RPerl::verbose()' should remain enabled in the RPerl source code.
  227 Diagnostic output is meant for us (RPerl system developers), so calls to 'RPerl::debug()' and 'RPerl::diag()' should be commented-out when not in use, in order to optimize runtime performance of the compiler itself.
  228 It is possible to run RPerl software within a Perl debugger or a C++ debugger, although both represent their own difficulties, and are not supported.
  229 
  230 That's it!  Your new Perl module file is now complete.
  231 
  232 As you can see from the multiple URLs in this step, it took multiple commits to reach this point.
  233 The new "AbsoluteValue.pm" file was merged into the main RPerl repo before CPPOPS_CPPTYPES was implemented and before all bugs were worked out.
  234 It is fine if it takes you several commits in your forked repo to complete work on your new operator, but hopefully you will NOT try to merge your unfinished code into the main RPerl repo before all the work is done and all the bugs are fixed.
  235 
  236 To see the full, real history of this file, follow the URL below:
  237 https://github.com/wbraswell/rperl/commits/master/lib/RPerl/Operation/Expression/Operator/Named/AbsoluteValue.pm
  238 
  239 To view the latest copy of this Perl module file, follow this URL:
  240 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Operation/Expression/Operator/Named/AbsoluteValue.pm
  241 
  242 
  243 STEP 6.  Update Appendant Files
  244 
  245 Whenever you create a new named operator, you will need to update a few extra files so RPerl will know about it.
  246 In the RPerl source code, this step is referenced with the following comment:
  247 # DEV NOTE, CORRELATION #rp020: upon adding new named op file lib/RPerl/Operation/Expression/Operator/Named*/* also add in Named*.pm and rperloperations.*
  248 
  249 Thus, you can search for everywhere affected by this step by executing the following command while in the RPerl source code directory:
  250 $ grep -nr '#rp020' ./*
  251 ./lib/rperloperations.pm
  252 ./lib/rperloperations.h
  253 ./lib/RPerl/Operation/Expression/Operator/Named.pm
  254 ./lib/RPerl/Operation/Expression/Operator/NamedUnary.pm
  255 
  256 First, you will need to update the "rperloperations.pm" file, if it does not already contain a 'use' command for your new Perl module file.
  257 Check the latest copy of "rperloperations.pm" to see if 'use RPerl::Operation::Expression::Operator::Named::AbsoluteValue;' is already included:
  258 https://github.com/wbraswell/rperl/blob/master/lib/rperloperations.pm
  259 
  260 When Pablo first checked the URL above, his new absolute value Perl module was not included, so we can see when he added it here:
  261 https://github.com/wbraswell/rperl/commit/4d997f91a52a34d8f4fa1a47830bc246aacd736e#diff-66e6372bddd4fc051a1cde1a632880a8R43
  262 
  263 Second, you will need to update "rperloperations.h" with any C++ header code which may be required by your operator.
  264 Only some operators will need C++ header code, some may not.
  265 In this case, we do need to perform a C++ preprocessor directive to define the 'abs' operator to be the same as the 'std::abs' operator, as mentioned in step 5:
  266 https://github.com/wbraswell/rperl/commit/3153a85327dd7116eeb757692c05d2ec077ada2d#diff-1e5c0f27b0c43112d615cf4e6b903899R16
  267 
  268 Third, you need to add the 'abs' operator into either the "Named.pm" or "NamedUnary.pm" files (but not both), depending on which category your operator falls within:
  269 https://github.com/wbraswell/rperl/commit/01e556314f967762f494270d6e3335eaf1f70b4d#diff-6276b3143f4ba5b5e1cb10e8bbf8b30fR22
  270 
  271 At this point the new 'abs' operator should be working in both PERLOPS_PERLTYPES and CPPOPS_CPPTYPES modes.
  272 RPerl should be able to load and recognize your new operator!
  273 
  274 
  275 STEP 7.  Create Tests, Part 2
  276 
  277 Now we will continue where we left off in step 4.
  278 
  279 Manually run the `rperl` compiler front-end command in test mode to ensure your good test parses without any errors:
  280 $ rperl -V -D -nop -t lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  281 
  282 When your first good test is working properly, run it and copy all pertinent output into 1 or more "EXECUTE_SUCCESS" RPerl preprocessor directives.
  283 In most cases, you will want to match multiple success output strings to be sure a single good test is correct, which is accomplished by multiple "EXECUTE_SUCCESS" preprocessor directives in the correct order of appearance:
  284 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  285 
  286 Next, copy the "program_00_good.pl" file into another file named "program_00_bad_00.pl", and introduce exactly 1 error of some kind.
  287 For failures, you will use one of the "ERROR" preprocessor directives listed above.
  288 You must manually run the `rperl` command to know which error message each bad test should produce.
  289 As with good tests, you will usually want to match multiple error message strings to be sure a single failure is correct, which is accomplished by multiple error preprocessor directives of the same kind.
  290 For example, it is okay to have 2 or more "PARSE_ERROR" directives, but it is not okay to mix different kinds of preprocessor test directives in one test file.
  291 
  292 To determine the correct error message for each test, simply supply the test file as the input to the `rperl` command:
  293 $ rperl -V -D -nop lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_bad_00.pl
  294 
  295 You can see the "PARSE_ERROR" messages we want to match here:
  296 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_bad_00.pl
  297 
  298 Now you will want to create "program_00_bad_01.pl" and so forth, which should all be failing variations on the "program_00_good.pl" test.
  299 Each bad test should be designed to cause a different error when using the 'abs' operator, such as passing 0 or 2 arguments to abs, or passing invalid arguments, or other grammar errors like omitting a semicolon after properly calling abs.
  300 
  301 Next, make another copy of "program_00_good.pl" into "program_01_good.pl" and change it to test the 'abs' operator in some different way, such as by utilizing different input data, or different data types, or different combinations of operators.
  302 As before, "program_01_good.pl" should then be used to create "program_01_bad_00.pl" and so on.
  303 You should always plan to create at least a half dozen failing (bad) tests and 2 or 3 passing (good) tests for each new operator.
  304 
  305 Lastly, enable testing of the CPPOPS_CPPTYPES mode by manually calling the `rperl` command again, in order to generate C++ output reference code:
  306 $ rperl -V -D -nop lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.pl
  307 
  308 If the C++ output code is correctly generated with no "DUMMY_SOURCE_CODE" or errors, then the reference files are denoted by appending the ".CPPOPS_CPPTYPES" file suffix to each generated file ending with ".cpp" or ".h".
  309 For advanced developers who choose to generate test classes or packages instead of test programs only, then the reference ".pmc" files are denoted by appending the ".CPPOPS_DUALTYPES" file suffix.
  310 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Test/Operator01NamedAbsoluteValue/program_00_good.cpp.CPPOPS_CPPTYPES
  311 
  312 Please create enough tests to thoroughly ensure your new operator is both running correctly and also failing correctly.
  313 
  314 Of course, please run the full RPerl test suite on your local machine to make sure all new tests (and current tests) pass:
  315 $ perl Makefile.PL; make realclean; perl Makefile.PL; make test
  316 
  317 DEBUGGING NOTES #2:
  318 Your new tests will be automatically accessed by 3 parts of the RPerl system test suite: t/09, t/12, and t/13.
  319 https://github.com/wbraswell/rperl/blob/master/t/09_interpret_execute.t
  320 https://github.com/wbraswell/rperl/blob/master/t/12_parse.t
  321 https://github.com/wbraswell/rperl/blob/master/t/13_generate.t
  322 You can run tests for your new 'abs' operator only.
  323 You can just run 1 test at a time, using the environmental variables to enable verbose and debugging output:
  324 $ export RPERL_VERBOSE=1
  325 $ export RPERL_DEBUG=1
  326 $
  327 $ #### you may want to use perl switches '-Mblib' and '-Mlib=lib' ####
  328 $
  329 $ perl ./t/09_interpret_execute.t lib/RPerl/Test/Operator01NamedAbsoluteValue
  330 $ perl ./t/12_parse.t             lib/RPerl/Test/Operator01NamedAbsoluteValue
  331 $ perl ./t/13_generate.t          lib/RPerl/Test/Operator01NamedAbsoluteValue
  332 
  333 You should see over 3,300 tests pass without 1 single failure when the entire test suite runs correctly via the `make test` command above.  Feels good, doesn't it?
  334 
  335 You can see the final product of creating the 'abs' tests here:
  336 https://github.com/wbraswell/rperl/tree/master/lib/RPerl/Test/Operator01NamedAbsoluteValue
  337 
  338 From the URL above, you can view the full history for each test file by clicking on the file's name, then clicking on the "History" button.
  339 
  340 
  341 STEP 8.  Make A Pull Request On GitHub
  342 
  343 Before submitting a pull request on GitHub, please make sure your development branch or fork is up to date and compatible with the latest GitHub master branch.
  344 (Remember the issue with the grammar rule serial numbers changing in the main RPerl repo in step 5?  That actually caused real problems with git.)
  345 You should be able to achieve this by performing a pull from your forked repo, which will import the latest code from the main RPerl repo.
  346 WARNING!  Always backup your work in another folder before performing unfamiliar git commands such as `git pull`, which could accidentally mess up your own code.
  347 
  348 When you are confident that all your code and tests are correct, you may request your new changes be merged into the main RPerl repo for general public usage.
  349 Visit the URL below, then click the "New pull request" button and follow the directions:
  350 https://github.com/wbraswell/rperl/pulls
  351 
  352 The main RPerl repo should automatically run your new tests via the Travis CI (continuous integration) platform:
  353 https://travis-ci.org/wbraswell/rperl/pull_requests
  354 
  355 If your code passes on Travis and looks good in general, then your pull request should be accepted and merged into the main RPerl repository.
  356 
  357 Congratulations, you are now a published RPerl author!  Give yourself a small gift or treat of some kind.  :-)
  358 
  359 
  360 STEP 9.  Update Learning RPerl
  361 
  362 After your new operator is proven to work correctly, we will want to update all corresponding sections of the Learning RPerl book, written using the POD format:
  363 http://perldoc.perl.org/perlpod.html
  364 
  365 The very latest version of Learning RPerl is always on GitHub:
  366 https://github.com/wbraswell/rperl/blob/master/lib/RPerl/Learning.pm
  367 
  368 The latest published version of Learning RPerl is always on the official RPerl website, although it may well be older than the GitHub version:
  369 http://rperl.org/learning_rperl.html
  370 
  371 Please do a thorough search for your new operator in all sections of the Learning RPerl book, and update it as necessary.
  372 At the very least, you will need to change the "Coming Soon" label to "Yes" in the table of supported operators!
  373 
  374 As with the previous steps, you should make all changes to the "Learning.pm" file within your own forked repo, then make a pull request like in step 8.
  375 
  376 Double congratulations, you are now a published Learning RPerl author!  Give yourself a slightly larger gift or treat!  ;-)
  377 
  378 ...
  379 
  380 THAT'S ALL, FOLKS!