From d02548c0925a02dd0af64a9dc13cce9e84d87b4f Mon Sep 17 00:00:00 2001 From: graydon Date: Mon, 14 Nov 2005 04:39:47 +0000 Subject: 2005-11-13 Graydon Hoare * staptree.h (struct indexable): New struct. (classify_indexable): New function. (classify_const_indexable): New function. (struct symbol): Implement indexable. (struct arrayindex): Take indexable as base. (struct foreach_loop): Take indexable as base. (struct print_format): New struct. (enum stat_component_type): New enum. (struct stat_op): New struct. (enum historgram_type): New enum. (struct hist_op): New struct. (struct visitor) (struct traversing_visitor) (struct throwing_visitor) (struct deep_copy_visitor): Add new visitor methods. (require): Specialize for indexable*. * staptree.cxx (print_format::*) (stat_op::*) (hist_op::*) (indexable::*) (traversing_visitor::*) (throwing_visitor::*) (deep_copy_visitor::*) (classify_indexable) (classify_const_indexable): Implement (deep_copy_visitor::*): Update to use indexables. * parse.h (parser::parse_indexable): New method. (parser::parse_hist_op_or_bare_name): New method. * parse.cxx (lexer::scan): Accept @ in identifiers. (parser::parse_array_in) (parser::parse_foreach_loop): Call parse_indexable. (parser::parse_hist_op_or_bare_name): Implement. (parser::parse_indexable): Implement. (parser::parse_symbol): Accept printf, stat_ops, hist_ops. * elaborate.h (struct typeresolution_info): Add methods for visiting print_format, stat_op, hist_op. * elaborate.cxx (symbol_fetcher): New class. (get_symbol_within_expression): New function. (get_symbol_within_indexable): New function. (mutated_var_collector): Replace mutated_map_collector. (no_var_mutation_during_iteration_check): Replace no_map_mutation_during_iteration_check. (semantic_pass_vars): Replace semantic_pass_maps. (semantic_pass): Update call accordingly. (symresolution_info::*) Add new visitors, teach about indexables (typeresolution_info::*) Likewise. * translate.cxx (c_unparser::getiter): Take symbol, not foreach_loop. (c_unparser::*) Add new visitors, teach about indexables. (c_tmpcounter::*) (delete_statement_operand_visitor::visit_arrayindex) (c_tmpcounter_assignment::*) (c_unparser_assignment::*): Likewise. (hist_op_downcaster): New struct. (expression_is_hist_op): New function. * testsuite/buildok/printf.stp: New test for print_format. --- staptree.h | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 5 deletions(-) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 11628b18..b509ad7a 100644 --- a/staptree.h +++ b/staptree.h @@ -172,15 +172,50 @@ struct assignment: public binary_expression void visit (visitor* u); }; +struct symbol; +struct hist_op; +struct indexable +{ + // This is a helper class which, type-wise, acts as a disjoint union + // of symbols and histograms. You can ask it whether it's a + // histogram or a symbol, and downcast accordingly. + void print_indexable (std::ostream& o) const; + void visit_indexable (visitor* u); + virtual bool is_symbol(symbol *& sym_out); + virtual bool is_hist_op(hist_op *& hist_out); + virtual bool is_const_symbol(const symbol *& sym_out) const; + virtual bool is_const_hist_op(const hist_op *& hist_out) const; + virtual const token *get_tok() const = 0; + virtual ~indexable() {} +}; + +// Perform a downcast to one out-value and NULL the other, throwing an +// exception if neither downcast succeeds. This is (sadly) about the +// best we can accomplish in C++. +void +classify_indexable(indexable* ix, + symbol *& array_out, + hist_op *& hist_out); + +void +classify_const_indexable(const indexable* ix, + symbol const *& array_out, + hist_op const *& hist_out); class vardecl; -struct symbol: public expression +struct symbol: + public expression, + public indexable { std::string name; vardecl *referent; symbol (); void print (std::ostream& o) const; void visit (visitor* u); + // overrides of type 'indexable' + const token *get_tok() const; + bool is_const_symbol(const symbol *& sym_out) const; + bool is_symbol(symbol *& sym_out); }; @@ -200,9 +235,8 @@ struct target_symbol : public expression struct arrayindex: public expression { - std::string base; std::vector indexes; - vardecl *referent; + indexable *base; arrayindex (); void print (std::ostream& o) const; void visit (visitor* u); @@ -221,6 +255,97 @@ struct functioncall: public expression }; +struct print_format: public expression +{ + bool print_with_format; + bool print_to_stream; + + enum format_flag + { + fmt_flag_zeropad = 1, + fmt_flag_plus = 2, + fmt_flag_space = 4, + fmt_flag_left = 8, + fmt_flag_special = 16 + }; + + enum conversion_type + { + conv_unspecified, + conv_signed_decimal, + conv_unsigned_decimal, + conv_unsigned_octal, + conv_unsigned_uppercase_hex, + conv_unsigned_lowercase_hex, + conv_string, + conv_literal + }; + + struct format_component + { + unsigned long flags; + unsigned width; + unsigned precision; + conversion_type type; + std::string literal_string; + void clear() + { + flags = 0; + width = 0; + precision = 0; + type = conv_unspecified; + literal_string.clear(); + } + }; + + std::vector components; + std::vector args; + + static std::string components_to_string(std::vector const & components); + static std::vector string_to_components(std::string const & str); + + void print (std::ostream& o) const; + void visit (visitor* u); +}; + + +enum stat_component_type + { + sc_average, + sc_count, + sc_sum, + sc_min, + sc_max, + }; + +struct stat_op: public expression +{ + stat_component_type ctype; + expression* stat; + void print (std::ostream& o) const; + void visit (visitor* u); +}; + +enum histogram_type + { + hist_linear, + hist_log + }; + +struct hist_op: public indexable +{ + const token* tok; + histogram_type htype; + expression* stat; + std::vector params; + void print (std::ostream& o) const; + void visit (visitor* u); + // overrides of type 'indexable' + const token *get_tok() const; + bool is_const_hist_op(const hist_op *& hist_out) const; + bool is_hist_op(hist_op *& hist_out); +}; + // ------------------------------------------------------------------------ @@ -316,8 +441,7 @@ struct foreach_loop: public statement { // this part is a specialization of arrayindex std::vector indexes; - std::string base; - vardecl* base_referent; + indexable *base; int sort_direction; // -1: decreasing, 0: none, 1: increasing unsigned sort_column; // 0: value, 1..N: index @@ -486,6 +610,9 @@ struct visitor virtual void visit_target_symbol (target_symbol* e) = 0; virtual void visit_arrayindex (arrayindex* e) = 0; virtual void visit_functioncall (functioncall* e) = 0; + virtual void visit_print_format (print_format* e) = 0; + virtual void visit_stat_op (stat_op* e) = 0; + virtual void visit_hist_op (hist_op* e) = 0; }; @@ -523,6 +650,9 @@ struct traversing_visitor: public visitor void visit_target_symbol (target_symbol* e); void visit_arrayindex (arrayindex* e); void visit_functioncall (functioncall* e); + void visit_print_format (print_format* e); + void visit_stat_op (stat_op* e); + void visit_hist_op (hist_op* e); }; @@ -565,6 +695,9 @@ struct throwing_visitor: public visitor void visit_target_symbol (target_symbol* e); void visit_arrayindex (arrayindex* e); void visit_functioncall (functioncall* e); + void visit_print_format (print_format* e); + void visit_stat_op (stat_op* e); + void visit_hist_op (hist_op* e); }; // A visitor which performs a deep copy of the root node it's applied @@ -609,6 +742,9 @@ struct deep_copy_visitor: public visitor virtual void visit_target_symbol (target_symbol* e); virtual void visit_arrayindex (arrayindex* e); virtual void visit_functioncall (functioncall* e); + virtual void visit_print_format (print_format* e); + virtual void visit_stat_op (stat_op* e); + virtual void visit_hist_op (hist_op* e); }; template static void @@ -624,6 +760,32 @@ require (deep_copy_visitor* v, T* dst, T src) } } +template <> static void +require (deep_copy_visitor* v, indexable** dst, indexable* src) +{ + if (src != NULL) + { + symbol *array_src=NULL, *array_dst=NULL; + hist_op *hist_src=NULL, *hist_dst=NULL; + + classify_indexable(src, array_src, hist_src); + + *dst = NULL; + + if (array_src) + { + require (v, &array_dst, array_src); + *dst = array_dst; + } + else + { + require (v, &hist_dst, hist_src); + *dst = hist_dst; + } + assert (*dst); + } +} + template static void provide (deep_copy_visitor* v, T src) { -- cgit