Bash++
Bash++ compiler internal documentation
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
BashppListener Class Reference

The main listener class for the Bash++ compiler. More...

#include <BashppListener.h>

Inheritance diagram for BashppListener:
Inheritance graph
[legend]
Collaboration diagram for BashppListener:
Collaboration graph
[legend]

Public Member Functions

void set_source_file (std::string source_file)
 
void set_include_paths (std::shared_ptr< std::vector< std::string >> include_paths)
 
void set_included (bool included)
 
void set_included_from (BashppListener *included_from)
 Sets the included_from pointer to the given listener. More...
 
void set_errors ()
 Sets the program_has_errors flag to true. More...
 
void set_output_stream (std::shared_ptr< std::ostream > output_stream)
 
void set_output_file (std::string output_file)
 
void set_run_on_exit (bool run_on_exit)
 
void set_suppress_warnings (bool suppress_warnings)
 
void set_arguments (std::vector< char * > arguments)
 
std::shared_ptr< bpp::bpp_programget_program ()
 
std::set< std::string > get_included_files ()
 
std::stack< std::string > get_include_stack ()
 
void enterProgram (BashppParser::ProgramContext *ctx) override
 
void exitProgram (BashppParser::ProgramContext *ctx) override
 
void enterInclude_statement (BashppParser::Include_statementContext *ctx) override
 Handles. More...
 
void exitInclude_statement (BashppParser::Include_statementContext *ctx) override
 
void enterClass_definition (BashppParser::Class_definitionContext *ctx) override
 
void exitClass_definition (BashppParser::Class_definitionContext *ctx) override
 
void enterMember_declaration (BashppParser::Member_declarationContext *ctx) override
 
void exitMember_declaration (BashppParser::Member_declarationContext *ctx) override
 
void enterObject_instantiation (BashppParser::Object_instantiationContext *ctx) override
 
void exitObject_instantiation (BashppParser::Object_instantiationContext *ctx) override
 
void enterPointer_declaration (BashppParser::Pointer_declarationContext *ctx) override
 
void exitPointer_declaration (BashppParser::Pointer_declarationContext *ctx) override
 
void enterValue_assignment (BashppParser::Value_assignmentContext *ctx) override
 
void exitValue_assignment (BashppParser::Value_assignmentContext *ctx) override
 
void enterMethod_definition (BashppParser::Method_definitionContext *ctx) override
 
void exitMethod_definition (BashppParser::Method_definitionContext *ctx) override
 
void enterConstructor_definition (BashppParser::Constructor_definitionContext *ctx) override
 
void exitConstructor_definition (BashppParser::Constructor_definitionContext *ctx) override
 
void enterDestructor_definition (BashppParser::Destructor_definitionContext *ctx) override
 
void exitDestructor_definition (BashppParser::Destructor_definitionContext *ctx) override
 
void enterSelf_reference (BashppParser::Self_referenceContext *ctx) override
 
void exitSelf_reference (BashppParser::Self_referenceContext *ctx) override
 
void enterSelf_reference_as_lvalue (BashppParser::Self_reference_as_lvalueContext *ctx) override
 
void exitSelf_reference_as_lvalue (BashppParser::Self_reference_as_lvalueContext *ctx) override
 
void enterStatement (BashppParser::StatementContext *ctx) override
 
void exitStatement (BashppParser::StatementContext *ctx) override
 
void enterClass_body_statement (BashppParser::Class_body_statementContext *ctx) override
 
void exitClass_body_statement (BashppParser::Class_body_statementContext *ctx) override
 
void enterGeneral_statement (BashppParser::General_statementContext *ctx) override
 
void exitGeneral_statement (BashppParser::General_statementContext *ctx) override
 
void enterObject_assignment (BashppParser::Object_assignmentContext *ctx) override
 
void exitObject_assignment (BashppParser::Object_assignmentContext *ctx) override
 
void enterPointer_dereference (BashppParser::Pointer_dereferenceContext *ctx) override
 
void exitPointer_dereference (BashppParser::Pointer_dereferenceContext *ctx) override
 
void enterObject_address (BashppParser::Object_addressContext *ctx) override
 
void exitObject_address (BashppParser::Object_addressContext *ctx) override
 
void enterObject_reference (BashppParser::Object_referenceContext *ctx) override
 
void exitObject_reference (BashppParser::Object_referenceContext *ctx) override
 
void enterObject_reference_as_lvalue (BashppParser::Object_reference_as_lvalueContext *ctx) override
 
void exitObject_reference_as_lvalue (BashppParser::Object_reference_as_lvalueContext *ctx) override
 
void enterNullptr_ref (BashppParser::Nullptr_refContext *ctx) override
 
void exitNullptr_ref (BashppParser::Nullptr_refContext *ctx) override
 
void enterNew_statement (BashppParser::New_statementContext *ctx) override
 
void exitNew_statement (BashppParser::New_statementContext *ctx) override
 
void enterDelete_statement (BashppParser::Delete_statementContext *ctx) override
 
void exitDelete_statement (BashppParser::Delete_statementContext *ctx) override
 
void enterDynamic_cast_statement (BashppParser::Dynamic_cast_statementContext *ctx) override
 
void exitDynamic_cast_statement (BashppParser::Dynamic_cast_statementContext *ctx) override
 
void enterSupershell (BashppParser::SupershellContext *ctx) override
 
void exitSupershell (BashppParser::SupershellContext *ctx) override
 
void enterSubshell (BashppParser::SubshellContext *ctx) override
 
void exitSubshell (BashppParser::SubshellContext *ctx) override
 
void enterDeprecated_subshell (BashppParser::Deprecated_subshellContext *ctx) override
 
void exitDeprecated_subshell (BashppParser::Deprecated_subshellContext *ctx) override
 
void enterBash_arithmetic (BashppParser::Bash_arithmeticContext *ctx) override
 
void exitBash_arithmetic (BashppParser::Bash_arithmeticContext *ctx) override
 
void enterString (BashppParser::StringContext *ctx) override
 
void exitString (BashppParser::StringContext *ctx) override
 
void enterSinglequote_string (BashppParser::Singlequote_stringContext *ctx) override
 
void exitSinglequote_string (BashppParser::Singlequote_stringContext *ctx) override
 
void enterParameter (BashppParser::ParameterContext *ctx) override
 
void exitParameter (BashppParser::ParameterContext *ctx) override
 
void enterOther_statement (BashppParser::Other_statementContext *ctx) override
 
void exitOther_statement (BashppParser::Other_statementContext *ctx) override
 
void enterRaw_rvalue (BashppParser::Raw_rvalueContext *ctx) override
 
void exitRaw_rvalue (BashppParser::Raw_rvalueContext *ctx) override
 
void enterArray_value (BashppParser::Array_valueContext *ctx) override
 
void exitArray_value (BashppParser::Array_valueContext *ctx) override
 
void enterArray_index (BashppParser::Array_indexContext *ctx) override
 
void exitArray_index (BashppParser::Array_indexContext *ctx) override
 
void enterBash_if_statement (BashppParser::Bash_if_statementContext *ctx) override
 
void exitBash_if_statement (BashppParser::Bash_if_statementContext *ctx) override
 
void enterBash_if_root_branch (BashppParser::Bash_if_root_branchContext *ctx) override
 
void exitBash_if_root_branch (BashppParser::Bash_if_root_branchContext *ctx) override
 
void enterBash_if_else_branch (BashppParser::Bash_if_else_branchContext *ctx) override
 
void exitBash_if_else_branch (BashppParser::Bash_if_else_branchContext *ctx) override
 
void enterBash_if_condition (BashppParser::Bash_if_conditionContext *ctx) override
 
void exitBash_if_condition (BashppParser::Bash_if_conditionContext *ctx) override
 
void enterBash_case_statement (BashppParser::Bash_case_statementContext *ctx) override
 
void exitBash_case_statement (BashppParser::Bash_case_statementContext *ctx) override
 
void enterBash_case_pattern (BashppParser::Bash_case_patternContext *ctx) override
 
void exitBash_case_pattern (BashppParser::Bash_case_patternContext *ctx) override
 
void enterBash_case_pattern_header (BashppParser::Bash_case_pattern_headerContext *ctx) override
 
void exitBash_case_pattern_header (BashppParser::Bash_case_pattern_headerContext *ctx) override
 
void enterBash_while_loop (BashppParser::Bash_while_loopContext *ctx) override
 
void exitBash_while_loop (BashppParser::Bash_while_loopContext *ctx) override
 
void enterBash_while_condition (BashppParser::Bash_while_conditionContext *ctx) override
 
void exitBash_while_condition (BashppParser::Bash_while_conditionContext *ctx) override
 
void enterBash_for_loop (BashppParser::Bash_for_loopContext *ctx) override
 
void exitBash_for_loop (BashppParser::Bash_for_loopContext *ctx) override
 
void enterBash_for_header (BashppParser::Bash_for_headerContext *ctx) override
 
void exitBash_for_header (BashppParser::Bash_for_headerContext *ctx) override
 
void enterBash_function (BashppParser::Bash_functionContext *ctx) override
 
void exitBash_function (BashppParser::Bash_functionContext *ctx) override
 
void enterHeredoc (BashppParser::HeredocContext *ctx) override
 
void exitHeredoc (BashppParser::HeredocContext *ctx) override
 
void enterHeredoc_header (BashppParser::Heredoc_headerContext *ctx) override
 
void exitHeredoc_header (BashppParser::Heredoc_headerContext *ctx) override
 
void enterExtra_statement (BashppParser::Extra_statementContext *ctx) override
 
void exitExtra_statement (BashppParser::Extra_statementContext *ctx) override
 
void enterTerminal_token (BashppParser::Terminal_tokenContext *ctx) override
 
void exitTerminal_token (BashppParser::Terminal_tokenContext *ctx) override
 

Private Member Functions

bool is_protected_keyword (const std::string &keyword)
 

Private Attributes

std::string source_file
 Path to the source file being compiled (used for error reporting) More...
 
bool included = false
 
std::shared_ptr< std::vector< std::string > > include_paths = nullptr
 A list of paths to search for included files. More...
 
bool suppress_warnings = false
 
std::set< std::string > included_files = {}
 A set of (unique) included files (used for '@include_once' directives) More...
 
BashppListenerincluded_from = nullptr
 
std::stack< std::string > include_stack
 A chain of included files, from the main file to the current file (used for error reporting) More...
 
std::shared_ptr< std::ostream > output_stream
 Pointer to the output stream to write the compiled code to. More...
 
std::string output_file
 
bool run_on_exit = false
 
std::vector< char * > arguments = {}
 Command-line arguments to pass to the compiled program if run_on_exit is true. More...
 
std::shared_ptr< bpp::bpp_programprogram = std::make_shared<bpp::bpp_program>()
 
bool in_while_condition = false
 
std::shared_ptr< bpp::bash_while_conditioncurrent_while_condition = nullptr
 
bool in_method = false
 
std::stack< std::shared_ptr< bpp::bpp_entity > > entity_stack
 A stack to keep track of the current entity being processed. More...
 
std::shared_ptr< bpp::bpp_classprimitive
 
bool error_thrown = false
 
antlr4::ParserRuleContext * error_context = nullptr
 
bool program_has_errors = false
 

Static Private Attributes

static constexpr const char * protected_keywords []
 

Detailed Description

The main listener class for the Bash++ compiler.

This class is the main listener for the Bash++ compiler. This is where the main logic for the compiler is implemented by walking the parse tree generated by the ANTLR parser.

The listener is responsible for generating the compiled Bash code from the parsed Bash++ code. The listener is also responsible for handling errors and warnings.

A brief run-down of how the parse tree works:

When we enter a node in the parse tree, we execute the enter* function for that node. When we exit a node in the parse tree, we execute the exit* function for that node.

Member Function Documentation

◆ enterArray_index()

void BashppListener::enterArray_index ( BashppParser::Array_indexContext *  ctx)
override

Array indices take the form: [...] Where the contents of the brackets are the array index And can be any valid sequence of statements

◆ enterArray_value()

void BashppListener::enterArray_value ( BashppParser::Array_valueContext *  ctx)
override

Array values are rvalues in assignment operations which take the form (...) Where the contents of the parentheses are the array elements Empty arrays are written as ()

◆ enterBash_arithmetic()

void BashppListener::enterBash_arithmetic ( BashppParser::Bash_arithmeticContext *  ctx)
override

Bash arithmetic is a series of arithmetic operations that are enclosed in $((...)) They do not run in a subshell. So, unlike with the subshell rule, We can preserve objects instantiated within the arithmetic context, etc

◆ enterBash_case_pattern()

void BashppListener::enterBash_case_pattern ( BashppParser::Bash_case_patternContext *  ctx)
override

◆ enterBash_case_pattern_header()

void BashppListener::enterBash_case_pattern_header ( BashppParser::Bash_case_pattern_headerContext *  ctx)
override

◆ enterBash_case_statement()

void BashppListener::enterBash_case_statement ( BashppParser::Bash_case_statementContext *  ctx)
override

Bash case statements take the form case (something) in pattern1) ... ;; ... esac

The code to handle each pattern will be caught by the Bash_case_pattern context These will be children of the Bash_case_statement context in the parse tree

The patterns to be matched will be caught by the Bash_case_pattern_header context These will be children of the Bash_case_pattern context in the parse tree

◆ enterBash_for_header()

void BashppListener::enterBash_for_header ( BashppParser::Bash_for_headerContext *  ctx)
override

◆ enterBash_for_loop()

void BashppListener::enterBash_for_loop ( BashppParser::Bash_for_loopContext *  ctx)
override

◆ enterBash_function()

void BashppListener::enterBash_function ( BashppParser::Bash_functionContext *  ctx)
override

Bash functions take the format:

function function_name { ... }

Or: function function_name() { ... }

Or: function_name() { ... }

◆ enterBash_if_condition()

void BashppListener::enterBash_if_condition ( BashppParser::Bash_if_conditionContext *  ctx)
override

◆ enterBash_if_else_branch()

void BashppListener::enterBash_if_else_branch ( BashppParser::Bash_if_else_branchContext *  ctx)
override

◆ enterBash_if_root_branch()

void BashppListener::enterBash_if_root_branch ( BashppParser::Bash_if_root_branchContext *  ctx)
override

◆ enterBash_if_statement()

void BashppListener::enterBash_if_statement ( BashppParser::Bash_if_statementContext *  ctx)
override

Bash if statement take the form if CONDITION; then ... elif CONDITION; then ... else ... fi

The elif/else branches will be caught by the Bash_if_root_branch and Bash_if_else_branch contexts Both of those will be children of the Bash_if_statement context in the parse tree

The only thing that we need to be careful about is this: All of the pre-code which is generated INSIDE of the if CONDITION Should be placed before the if statement altogether, not only before the condition Likewise all of the post-code for the condition should be placed after the if statement

For example, consider the following code: if [[ -f "@this.filePath" ]]; then ... elif [[ -f "@this.otherFilePath" ]]; then ... fi

Pre-code has to be generated in order to access @this.filePath and @this.otherFilePath The pre-code converts these references into ordinary variable references which we can substitute directly into the if condition As in, for example, swapping 'if [[ -f "@this.filePath" ]]' with 'if [[ -f "$filePath" ]]' Although we have better naming conventions for the variables, this is just an example

If we weren't careful, and just placed the pre-code the way we always do, we would end up with something like this: $filePath={whatever we need to do to access @this.filePath} if [[ -f "$filePath" ]]; then ... $otherFilePath={whatever we need to do to access @this.otherFilePath} elif [[ -f "$otherFilePath" ]]; then ... fi

As you can tell from the above, the $otherFilePath assignment is INSIDE the first branch of the if statement And therefore is completely useless – if the first branch is taken, the second branch will never be taken And in the event that the second branch IS taken, $otherFilePath will not be defined

So, what we have to do instead is a bit more like: $filePath={whatever we need to do to access @this.filePath} $otherFilePath={whatever we need to do to access @this.otherFilePath} if [[ -f "$filePath" ]]; then ... elif [[ -f "$otherFilePath" ]]; then ... fi

◆ enterBash_while_condition()

void BashppListener::enterBash_while_condition ( BashppParser::Bash_while_conditionContext *  ctx)
override

◆ enterBash_while_loop()

void BashppListener::enterBash_while_loop ( BashppParser::Bash_while_loopContext *  ctx)
override

◆ enterClass_body_statement()

void BashppListener::enterClass_body_statement ( BashppParser::Class_body_statementContext *  ctx)
override

◆ enterClass_definition()

void BashppListener::enterClass_definition ( BashppParser::Class_definitionContext *  ctx)
override

◆ enterConstructor_definition()

void BashppListener::enterConstructor_definition ( BashppParser::Constructor_definitionContext *  ctx)
override

Constructor definitions take the form @constructor { ... }

◆ enterDelete_statement()

void BashppListener::enterDelete_statement ( BashppParser::Delete_statementContext *  ctx)
override

Delete statements take the form @delete @object Where object is the name of the object to delete

This statement calls the __delete function for the object and the object's destructor if it exists If the destructor exists, it will be called first (before __delete) It then unsets the object

◆ enterDeprecated_subshell()

void BashppListener::enterDeprecated_subshell ( BashppParser::Deprecated_subshellContext *  ctx)
override

◆ enterDestructor_definition()

void BashppListener::enterDestructor_definition ( BashppParser::Destructor_definitionContext *  ctx)
override

Destructor definitions take the form @destructor { ... }

◆ enterDynamic_cast_statement()

void BashppListener::enterDynamic_cast_statement ( BashppParser::Dynamic_cast_statementContext *  ctx)
override

Dynamic cast statements take the form @dynamic_cast<ClassName> Object Where ClassName is the name of the class to cast to And Object is the object to cast

This statement performs a runtime check to verify the cast is valid And substitutes either the address of the cast object or the @nullptr value

◆ enterExtra_statement()

void BashppListener::enterExtra_statement ( BashppParser::Extra_statementContext *  ctx)
override

◆ enterGeneral_statement()

void BashppListener::enterGeneral_statement ( BashppParser::General_statementContext *  ctx)
override

◆ enterHeredoc()

void BashppListener::enterHeredoc ( BashppParser::HeredocContext *  ctx)
override

◆ enterHeredoc_header()

void BashppListener::enterHeredoc_header ( BashppParser::Heredoc_headerContext *  ctx)
override

◆ enterInclude_statement()

void BashppListener::enterInclude_statement ( BashppParser::Include_statementContext *  ctx)
override

Handles.

@include_once statements

This function is called when the parser enters an

@include_once statement.

The syntax of an include is:

| dynamic] {PATH} [as "{PATH}"]

For example:

@include_once dynamic <Stack> as "/usr/lib/Stack.sh"

Or:

◆ enterMember_declaration()

void BashppListener::enterMember_declaration ( BashppParser::Member_declarationContext *  ctx)
override

This will either be:

  1. A primitive
  2. An object
  3. A pointer If it's a primitive, then IDENTIFIER will be set If it's an object, then object_instantiation will be set, and we'll handle that in the object_instantiation rule If it's a pointer, then pointer_declaration will be set, and we'll handle that in the pointer_declaration rule

◆ enterMethod_definition()

void BashppListener::enterMethod_definition ( BashppParser::Method_definitionContext *  ctx)
override

◆ enterNew_statement()

void BashppListener::enterNew_statement ( BashppParser::New_statementContext *  ctx)
override

New statements take the form @new ClassName Where ClassName is the name of the class to instantiate

This statement creates a new object of the specified class And replaces the "@new ClassName" statement with the address of the new object

◆ enterNullptr_ref()

void BashppListener::enterNullptr_ref ( BashppParser::Nullptr_refContext *  ctx)
override

Nullptr references take the form @nullptr

This reference will be replaced with the value of the nullptr constant

◆ enterObject_address()

void BashppListener::enterObject_address ( BashppParser::Object_addressContext *  ctx)
override

Object addresses take the form &@IDENTIFIER.IDENTIFIER... Or &@this.IDENTIFIER.IDENTIFIER...

This reference will be replaced with the memory address of the object

◆ enterObject_assignment()

void BashppListener::enterObject_assignment ( BashppParser::Object_assignmentContext *  ctx)
override

◆ enterObject_instantiation()

void BashppListener::enterObject_instantiation ( BashppParser::Object_instantiationContext *  ctx)
override

The object type will be stored in one of either IDENTIFIER_LVALUE or IDENTIFIER(0) If IDENTIFIER_LVALUE, then the object name will be in IDENTIFIER(0) If IDENTIFIER(0), then the object name will be in IDENTIFIER(1)

◆ enterObject_reference()

void BashppListener::enterObject_reference ( BashppParser::Object_referenceContext *  ctx)
override

Object references take the form @IDENTIFIER.IDENTIFIER.IDENTIFIER... Where each IDENTIFIER following a dot is a member of the object referenced by the preceding IDENTIFIER

This reference may resolve to either an object or a method If it's a primitive object, treat this as an rvalue and get the value of the primitive object If it's a non-primitive object, this is a method call to .toPrimitive If it's a method, call the method in a supershell and substitute the result

◆ enterObject_reference_as_lvalue()

void BashppListener::enterObject_reference_as_lvalue ( BashppParser::Object_reference_as_lvalueContext *  ctx)
override

Lvalue object references take the form @IDENTIFIER_LVALUE.IDENTIFIER.IDENTIFIER... Where each IDENTIFIER following a dot is a member of the object referenced by the preceding IDENTIFIER

This reference may resolve to either an object or a method If it's a primitive object, replace the reference with the address of the primitive object If it's a non-primitive object, this is a method call to .toPrimitive If it's a method, replace the reference with a call to the method There is no need to call the method in a supershell for lvalues. We can (and must) just call it directly

◆ enterOther_statement()

void BashppListener::enterOther_statement ( BashppParser::Other_statementContext *  ctx)
override

◆ enterParameter()

void BashppListener::enterParameter ( BashppParser::ParameterContext *  ctx)
override

◆ enterPointer_declaration()

void BashppListener::enterPointer_declaration ( BashppParser::Pointer_declarationContext *  ctx)
override

The pointer type will be stored in one of either IDENTIFIER_LVALUE or IDENTIFIER(0) If IDENTIFIER_LVALUE, then the pointer name will be in IDENTIFIER(0) If IDENTIFIER(0), then the pointer name will be in IDENTIFIER(1)

◆ enterPointer_dereference()

void BashppListener::enterPointer_dereference ( BashppParser::Pointer_dereferenceContext *  ctx)
override

Pointer dereferences take the form *@IDENTIFIER.IDENTIFIER... Or *@this.IDENTIFIER.IDENTIFIER... The result should be the object pointed to by the pointer For instance, @MyClass myObject=*@myPointer Should copy the object pointed to by myPointer into myObject Or: var=*@myPointer Should store the output of the object's toPrimitive method in var

◆ enterProgram()

void BashppListener::enterProgram ( BashppParser::ProgramContext *  ctx)
override

◆ enterRaw_rvalue()

void BashppListener::enterRaw_rvalue ( BashppParser::Raw_rvalueContext *  ctx)
override

◆ enterSelf_reference()

void BashppListener::enterSelf_reference ( BashppParser::Self_referenceContext *  ctx)
override

Self references take the form @this.IDENTIFIER.IDENTIFIER... Where each IDENTIFIER following a dot is a member of the object referenced by the preceding IDENTIFIER

This reference may resolve to either an object or a method If it's a primitive object, treat this as an rvalue and get the value of the primitive object If it's a non-primitive object, this is a method call to .toPrimitive If it's a method, call the method in a supershell and substitute the result

◆ enterSelf_reference_as_lvalue()

void BashppListener::enterSelf_reference_as_lvalue ( BashppParser::Self_reference_as_lvalueContext *  ctx)
override

Self references take the form @this.IDENTIFIER.IDENTIFIER... Where each IDENTIFIER following a dot is a member of the object referenced by the preceding IDENTIFIER

This reference may resolve to either an object or a method If it's a primitive object, replace the reference with the address of the primitive object If it's a non-primitive object, this is a method call to .toPrimitive If it's a method, replace the reference with a call to the method There is no need to call the method in a supershell for lvalues. We can (and must) just call it directly

◆ enterSinglequote_string()

void BashppListener::enterSinglequote_string ( BashppParser::Singlequote_stringContext *  ctx)
override

◆ enterStatement()

void BashppListener::enterStatement ( BashppParser::StatementContext *  ctx)
override

◆ enterString()

void BashppListener::enterString ( BashppParser::StringContext *  ctx)
override

◆ enterSubshell()

void BashppListener::enterSubshell ( BashppParser::SubshellContext *  ctx)
override

◆ enterSupershell()

void BashppListener::enterSupershell ( BashppParser::SupershellContext *  ctx)
override

Supershells take the form @(...) Where ... is a series of commands to be executed in a supershell Supershells can be nested

◆ enterTerminal_token()

void BashppListener::enterTerminal_token ( BashppParser::Terminal_tokenContext *  ctx)
override

◆ enterValue_assignment()

void BashppListener::enterValue_assignment ( BashppParser::Value_assignmentContext *  ctx)
override

◆ exitArray_index()

void BashppListener::exitArray_index ( BashppParser::Array_indexContext *  ctx)
override

◆ exitArray_value()

void BashppListener::exitArray_value ( BashppParser::Array_valueContext *  ctx)
override

◆ exitBash_arithmetic()

void BashppListener::exitBash_arithmetic ( BashppParser::Bash_arithmeticContext *  ctx)
override

◆ exitBash_case_pattern()

void BashppListener::exitBash_case_pattern ( BashppParser::Bash_case_patternContext *  ctx)
override

◆ exitBash_case_pattern_header()

void BashppListener::exitBash_case_pattern_header ( BashppParser::Bash_case_pattern_headerContext *  ctx)
override

◆ exitBash_case_statement()

void BashppListener::exitBash_case_statement ( BashppParser::Bash_case_statementContext *  ctx)
override

◆ exitBash_for_header()

void BashppListener::exitBash_for_header ( BashppParser::Bash_for_headerContext *  ctx)
override

◆ exitBash_for_loop()

void BashppListener::exitBash_for_loop ( BashppParser::Bash_for_loopContext *  ctx)
override

◆ exitBash_function()

void BashppListener::exitBash_function ( BashppParser::Bash_functionContext *  ctx)
override

◆ exitBash_if_condition()

void BashppListener::exitBash_if_condition ( BashppParser::Bash_if_conditionContext *  ctx)
override

◆ exitBash_if_else_branch()

void BashppListener::exitBash_if_else_branch ( BashppParser::Bash_if_else_branchContext *  ctx)
override

◆ exitBash_if_root_branch()

void BashppListener::exitBash_if_root_branch ( BashppParser::Bash_if_root_branchContext *  ctx)
override

◆ exitBash_if_statement()

void BashppListener::exitBash_if_statement ( BashppParser::Bash_if_statementContext *  ctx)
override

◆ exitBash_while_condition()

void BashppListener::exitBash_while_condition ( BashppParser::Bash_while_conditionContext *  ctx)
override

◆ exitBash_while_loop()

void BashppListener::exitBash_while_loop ( BashppParser::Bash_while_loopContext *  ctx)
override

◆ exitClass_body_statement()

void BashppListener::exitClass_body_statement ( BashppParser::Class_body_statementContext *  ctx)
override

◆ exitClass_definition()

void BashppListener::exitClass_definition ( BashppParser::Class_definitionContext *  ctx)
override

◆ exitConstructor_definition()

void BashppListener::exitConstructor_definition ( BashppParser::Constructor_definitionContext *  ctx)
override

◆ exitDelete_statement()

void BashppListener::exitDelete_statement ( BashppParser::Delete_statementContext *  ctx)
override

◆ exitDeprecated_subshell()

void BashppListener::exitDeprecated_subshell ( BashppParser::Deprecated_subshellContext *  ctx)
override

◆ exitDestructor_definition()

void BashppListener::exitDestructor_definition ( BashppParser::Destructor_definitionContext *  ctx)
override

◆ exitDynamic_cast_statement()

void BashppListener::exitDynamic_cast_statement ( BashppParser::Dynamic_cast_statementContext *  ctx)
override

◆ exitExtra_statement()

void BashppListener::exitExtra_statement ( BashppParser::Extra_statementContext *  ctx)
override

◆ exitGeneral_statement()

void BashppListener::exitGeneral_statement ( BashppParser::General_statementContext *  ctx)
override

◆ exitHeredoc()

void BashppListener::exitHeredoc ( BashppParser::HeredocContext *  ctx)
override

◆ exitHeredoc_header()

void BashppListener::exitHeredoc_header ( BashppParser::Heredoc_headerContext *  ctx)
override

◆ exitInclude_statement()

void BashppListener::exitInclude_statement ( BashppParser::Include_statementContext *  ctx)
override

◆ exitMember_declaration()

void BashppListener::exitMember_declaration ( BashppParser::Member_declarationContext *  ctx)
override

◆ exitMethod_definition()

void BashppListener::exitMethod_definition ( BashppParser::Method_definitionContext *  ctx)
override

◆ exitNew_statement()

void BashppListener::exitNew_statement ( BashppParser::New_statementContext *  ctx)
override

◆ exitNullptr_ref()

void BashppListener::exitNullptr_ref ( BashppParser::Nullptr_refContext *  ctx)
override

◆ exitObject_address()

void BashppListener::exitObject_address ( BashppParser::Object_addressContext *  ctx)
override

◆ exitObject_assignment()

void BashppListener::exitObject_assignment ( BashppParser::Object_assignmentContext *  ctx)
override

◆ exitObject_instantiation()

void BashppListener::exitObject_instantiation ( BashppParser::Object_instantiationContext *  ctx)
override

◆ exitObject_reference()

void BashppListener::exitObject_reference ( BashppParser::Object_referenceContext *  ctx)
override

If we're taking the address of the method, return the method_call_code This will be in the format: {function_name} {object_pointer} E.g, if we have a method called 'foo' in class 'bar', and we're taking the address "&@object.foo" Say for example: echo &@object.foo Then it will return: bpp__bar__foo address__of__object

If we're not taking the address (most cases), then we need to run the method in a supershell And substitute the result of the supershell in place of the reference

Suppose we have an 'object' with a datamember 'array' which is an array of primitives Accessing index 'i' of that array would, in Bash++, take the form: @object.array[$i] And the compiled code's version of the reference: ${bpp__objectClass__object__array[$i]}

Suppose however that 'object' has a non-primitive datamember 'inner' which has a datamember 'array' which is an array of primitives (In this case, we're nesting – the array is not a datamember of 'object', but of 'object.inner') Accessing index 'i' of that array would, in Bash++, take the form: @object.inner.array[$i] But the compiled code's version of the reference would have to take a slightly different form, Since we have to dereference the pointer to 'inner' before we can access 'array': bpp__objectClass__object__inner__array=${bpp__objectClass__object__inner}__array This "bpp__objectClass__object__inner__array" evaluates to a STRING which is the variable name where the array is actually stored We then have to evaluate that string to get the actual values stored in the array: bpp__objectClass__object__inner__arrayString="${bpp__objectClass__object__inner__array}[${i}]"

This first line gives us a string such as "actual_array_variable_name[$i]"

This string is not a variable reference, but a string which represents the variable reference

eval bpp__objectClass__object__inner__arrayIndex="\${${bpp__objectClass__object__inner__arrayString}"}"

This second line gives us the actual value stored in the array at index 'i'

So, we have to follow a different procedure based on whether or not we have to dereference a pointer

To make this code less disgraceful, at some point, object references should be re-worked altogether In the meantime, we can do a HACKY fix by checking the size of the IDENTIFIER list If it's greater than 2, we're guaranteed to have to dereference a pointer If it's not, we're guaranteed not to have to dereference a pointer (unless the very first identifier refers to a pointer)

TODO(@rail5): Fix this. Really just fix object references from the ground-up

◆ exitObject_reference_as_lvalue()

void BashppListener::exitObject_reference_as_lvalue ( BashppParser::Object_reference_as_lvalueContext *  ctx)
override

◆ exitOther_statement()

void BashppListener::exitOther_statement ( BashppParser::Other_statementContext *  ctx)
override

◆ exitParameter()

void BashppListener::exitParameter ( BashppParser::ParameterContext *  ctx)
override

◆ exitPointer_declaration()

void BashppListener::exitPointer_declaration ( BashppParser::Pointer_declarationContext *  ctx)
override

◆ exitPointer_dereference()

void BashppListener::exitPointer_dereference ( BashppParser::Pointer_dereferenceContext *  ctx)
override

◆ exitProgram()

void BashppListener::exitProgram ( BashppParser::ProgramContext *  ctx)
override

◆ exitRaw_rvalue()

void BashppListener::exitRaw_rvalue ( BashppParser::Raw_rvalueContext *  ctx)
override

◆ exitSelf_reference()

void BashppListener::exitSelf_reference ( BashppParser::Self_referenceContext *  ctx)
override

◆ exitSelf_reference_as_lvalue()

void BashppListener::exitSelf_reference_as_lvalue ( BashppParser::Self_reference_as_lvalueContext *  ctx)
override

◆ exitSinglequote_string()

void BashppListener::exitSinglequote_string ( BashppParser::Singlequote_stringContext *  ctx)
override

◆ exitStatement()

void BashppListener::exitStatement ( BashppParser::StatementContext *  ctx)
override

◆ exitString()

void BashppListener::exitString ( BashppParser::StringContext *  ctx)
override

◆ exitSubshell()

void BashppListener::exitSubshell ( BashppParser::SubshellContext *  ctx)
override

◆ exitSupershell()

void BashppListener::exitSupershell ( BashppParser::SupershellContext *  ctx)
override

◆ exitTerminal_token()

void BashppListener::exitTerminal_token ( BashppParser::Terminal_tokenContext *  ctx)
override

◆ exitValue_assignment()

void BashppListener::exitValue_assignment ( BashppParser::Value_assignmentContext *  ctx)
override

Value assignments will appear in the following contexts:

  1. Member declarations
  2. Object instantiations
  3. Pointer declarations
  4. Object assignments

◆ get_include_stack()

std::stack< std::string > BashppListener::get_include_stack ( )

◆ get_included_files()

std::set< std::string > BashppListener::get_included_files ( )

◆ get_program()

std::shared_ptr< bpp::bpp_program > BashppListener::get_program ( )

◆ is_protected_keyword()

bool BashppListener::is_protected_keyword ( const std::string &  keyword)
inlineprivate

◆ set_arguments()

void BashppListener::set_arguments ( std::vector< char * >  arguments)

◆ set_errors()

void BashppListener::set_errors ( )

Sets the program_has_errors flag to true.

This function is called when a syntax error is encountered during parsing.

◆ set_include_paths()

void BashppListener::set_include_paths ( std::shared_ptr< std::vector< std::string >>  include_paths)

◆ set_included()

void BashppListener::set_included ( bool  included)

◆ set_included_from()

void BashppListener::set_included_from ( BashppListener included_from)

Sets the included_from pointer to the given listener.

◆ set_output_file()

void BashppListener::set_output_file ( std::string  output_file)

◆ set_output_stream()

void BashppListener::set_output_stream ( std::shared_ptr< std::ostream >  output_stream)

◆ set_run_on_exit()

void BashppListener::set_run_on_exit ( bool  run_on_exit)

◆ set_source_file()

void BashppListener::set_source_file ( std::string  source_file)

◆ set_suppress_warnings()

void BashppListener::set_suppress_warnings ( bool  suppress_warnings)

Member Data Documentation

◆ arguments

BashppListener::arguments = {}
private

Command-line arguments to pass to the compiled program if run_on_exit is true.

◆ current_while_condition

std::shared_ptr<bpp::bash_while_condition> BashppListener::current_while_condition = nullptr
private

◆ entity_stack

BashppListener::entity_stack
private

A stack to keep track of the current entity being processed.

For example, when we encounter a class definition, we push the class onto the entity_stack. Then, inside that class, when we encounter a method definition, we push the method onto the entity_stack. Inside that method, when we encounter a value assignment, we push the value assignment onto the entity_stack. When we're done with the value assignment, we pop it off the entity_stack, so that the method is now at the top of the stack. When we're done with the method, we pop it off the entity_stack, so that the class is now at the top of the stack. When we're done with the class, we pop it off the entity_stack, so that the program is now at the top of the stack.

◆ error_context

antlr4::ParserRuleContext* BashppListener::error_context = nullptr
private

◆ error_thrown

bool BashppListener::error_thrown = false
private

◆ in_method

bool BashppListener::in_method = false
private

◆ in_while_condition

bool BashppListener::in_while_condition = false
private

◆ include_paths

BashppListener::include_paths = nullptr
private

A list of paths to search for included files.

◆ include_stack

BashppListener::include_stack
private

A chain of included files, from the main file to the current file (used for error reporting)

◆ included

bool BashppListener::included = false
private

◆ included_files

BashppListener::included_files = {}
private

A set of (unique) included files (used for '@include_once' directives)

◆ included_from

BashppListener* BashppListener::included_from = nullptr
private

◆ output_file

std::string BashppListener::output_file
private

◆ output_stream

BashppListener::output_stream
private

Pointer to the output stream to write the compiled code to.

◆ primitive

std::shared_ptr<bpp::bpp_class> BashppListener::primitive
private

◆ program

std::shared_ptr<bpp::bpp_program> BashppListener::program = std::make_shared<bpp::bpp_program>()
private

◆ program_has_errors

bool BashppListener::program_has_errors = false
private

◆ protected_keywords

constexpr const char* BashppListener::protected_keywords[]
staticconstexprprivate
Initial value:
= {
"class", "constructor", "delete", "destructor",
"dynamic_cast", "include", "include_once", "method",
"new", "nullptr", "primitive", "private",
"protected", "public", "this", "virtual"
}

◆ run_on_exit

bool BashppListener::run_on_exit = false
private

◆ source_file

BashppListener::source_file
private

Path to the source file being compiled (used for error reporting)

◆ suppress_warnings

bool BashppListener::suppress_warnings = false
private

The documentation for this class was generated from the following files: