/* G-Cows - scripting language for creation of web sites Copyright (C) 2002, 2003, 2004, 2005, 2006 Andrea Sozzi This file is part of G-Cows. G-Cows is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. G-Cows is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef SRC_LANGUAGE_H #define SRC_LANGUAGE_H #include // #include #include #include #include #include #include #include "common.H" #include "variables.H" #include "file_utils.H" #include "error.H" #include "utils.H" class Tree; using std::string; using std::vector; using std::set; using std::deque; using std::ostringstream; typedef vector Int_vect; typedef Int_vect::iterator Int_iter; typedef vector Bool_vect; typedef Bool_vect::iterator Bool_iter; typedef set String_set; typedef String_set::const_iterator String_set_iter; // Generic Syntax Node class Node { public: // Node () { } virtual ~Node () { } virtual Gen_type exec () = 0; virtual void deps () { /* Most nodes have no dependencies */ } //friend class Tree; friend class Exec_tree; friend class Deps_tree; virtual bool is_var () { return false; } protected: void set_msg_buffers () { Msg::inst()->set_exec_log_infos (log_infos); } Tree *p2tree; Log_infos log_infos; }; // A Syntax Node introducing dependencies among files class N_dep : public Node { public: N_dep (Node *file_in) : file (file_in) { } virtual ~N_dep () { delete file; } virtual void deps (); protected: Node *file; }; typedef deque Node_Cont; typedef Node_Cont::iterator Node_Iter; typedef vector String_vect; typedef String_vect::iterator String_iter; // Syntax Tree class Tree { public: // Tree () { } virtual ~Tree () { }; virtual bool is_deps () { return false; } virtual bool is_fast_deps () { return false; } virtual bool is_exec () { return false; } virtual void ensure_exec () { }; virtual void ensure_dep () { }; virtual Node *push_node (Node *node) = 0; virtual void start () = 0; string get_input_file () { return input_file; } string get_abs_input_file () { return abs_input_file; } virtual string get_output_file () { return output_file; } string get_abs_output_file () { return abs_output_file; } void write_output (string out) { output << out; } // void write_output (filebuf *fb) { output << fb; } ostringstream &get_output () { return output; } // meglio x riferimento string adjust_level (); Variables vars; // move to Exec_tree protected: Node_Cont nodes; ostringstream output; string input_file; string abs_input_file; string output_file; string abs_output_file; int root_dir_level; int starting_dir_level; }; class Exec_tree : public Tree { public: Exec_tree (string input, string output, string root_dir, string noext_in); Node *push_node (Node *node); void init_var (string assignment) { vars.set_var (assignment); } void start (); bool is_exec () { return true; } void ensure_dep () { Msg::inst()->fatal ("Exec_tree::ensure_dep () Internal Error"); } string format_date (time_t time, string format); //Should be protected void save_args (); void set_include_flag () { restore_flags_stack.push_back (false); } void restore_args (); string get_noext () { return noext; } protected: string noext; Bool_vect restore_flags_stack; Int_vect argc_stack; Gen_type_vector argv_stack; }; class Deps_tree : public Tree { public: Deps_tree (string target): fast_deps (false), always_update (false), silent (false), noout_dir_mode (0), first_file (true), target_extension (target), launching_dir (string (get_w_dir ()) + "/") { } bool is_deps () { return fast_deps == false; } bool is_fast_deps () { return fast_deps == true; } void set_fast_deps () { fast_deps = true; } void ensure_exec () { Msg::inst()->fatal ("Deps_tree::ensure_exec () -- Internal Error"); } void set_up (string file_scanned); Node *push_node (Node *node); void start (); void enter_silent_mode () { if (first_file) silent = true; } void leave_silent_mode () { silent = false; } bool is_silent () { return silent; } void enter_noout_dir_mode () { noout_dir_mode++; } void leave_noout_dir_mode () { noout_dir_mode--; } bool is_noout_dir_mode () { return noout_dir_mode > 0; } void always () { always_update = true; } void unset_always () { always_update = false; } bool is_always () { return always_update; } void write_always (string out) {if (always_update) always_cmds += out;} void unset_first_file () { first_file = false; } void set_custom_ext (string ext) { // ext: "__EXT__"{GS}*.+ ext = ext.substr (ext.find ("__EXT__") + string ("__EXT__").size ()); custom_extension = ext.substr (ext.find_first_not_of (" \t")); } // VERIFICARE COME ADATTARE PER FAST MODE void set_dep (string dep) { dep = Utils::trim (dep.substr (dep.find ("__DEP__") + string ("__DEP__").size ())); if (dep[0] != '/') dep = get_current_dir () + dep; write_cache (" \\\n\t" + opt_file_name (dep)); } void set_input_file (string input) { input_file = opt_file_name (input); abs_input_file = launching_dir + input_file; } void set_output_file (string output) { output_file = opt_file_name (output); abs_output_file = launching_dir + output_file; } string get_output_file (); string get_and_delete_custom_ext (); void refresh (string file_name); void undo_refresh (); string get_current_dir () { return current_dir; } void write_file_list (string text); string get_file_list () { return file_list; } string get_always_list () { return always_list; } string get_always_cmds () { return always_cmds; } void write_sources_list (string file) { src_cache.insert (file); } string get_sources_list (); void write_cache (string file) { dep_cache.insert (file); } void dump_cache (); int get_cache_size () { return dep_cache.size (); } void clear_cache (); protected: bool fast_deps; bool always_update; bool silent; int noout_dir_mode; bool first_file; string target_extension; string custom_extension; string current_dir; String_vect current_dir_stack; string file_list; string always_list; string always_cmds; String_set src_cache; String_set dep_cache; string launching_dir; }; /* Language Implementation. There is a derived class for every statement */ // Language Structure class N_stmt : public Node { public: N_stmt (Node *st_list_in, Node *st_in) : st_list (st_list_in), st (st_in) { } ~N_stmt () { delete st_list; delete st; } Gen_type exec () { st_list->exec (); st->exec (); return Gen_type (0); } protected: Node *st_list; Node *st; }; class N_empty : public Node { public: N_empty () { } Gen_type exec () { return Gen_type (0); } }; class N_end : public Node { public: N_end () { } Gen_type exec () { return Gen_type (0); } }; class N_eof : public Node { public: N_eof () { } Gen_type exec () { ((Exec_tree *)p2tree)->restore_args (); return Gen_type (0); } }; // Display class N_echo : public Node { public: N_echo (Node *message_in) : message (message_in) { } ~N_echo () { delete message; } Gen_type exec (); protected: Node *message; }; class N_print : public Node { public: N_print (Node *message_in) : message (message_in) { } ~N_print () { delete message; } Gen_type exec (); protected: Node *message; }; // Conditionals class N_if : public Node { public: N_if (Node *cond_in, Node *st_in) : cond (cond_in), st (st_in) { } ~N_if () { delete cond; delete st; } Gen_type exec (); protected: Node *cond; Node *st; }; class N_ifdef : public Node { public: N_ifdef (Node *var_in, Node *st_in) : var (var_in), st (st_in) { } ~N_ifdef () { delete var; delete st; } Gen_type exec (); protected: Node *var; Node *st; }; class N_ifndef : public Node { public: N_ifndef (Node *var_in, Node *st_in) : var (var_in), st (st_in) { } ~N_ifndef () { delete var; delete st; } Gen_type exec (); protected: Node *var; Node *st; }; class N_cond_seq : public Node { public: N_cond_seq (Node *seq_in, Node *if_st_in) : seq (seq_in), if_st (if_st_in) { } ~N_cond_seq () { delete seq; delete if_st; } Gen_type exec (); protected: Node *seq; Node *if_st; }; class N_if_else : public Node { public: N_if_else (Node *seq_in, Node *st_in) : seq (seq_in), st (st_in) { } ~N_if_else() { delete seq; delete st; } Gen_type exec (); protected: Node *seq; Node *st; }; // Operators class N_assign : public Node { public: N_assign (Node *var_in, Node *value_in, bool if_undef_in=false) : var (var_in), value (value_in), only_if_undef (if_undef_in) { } ~N_assign () { delete var; delete value; } Gen_type exec (); protected: Node *var; Node *value; bool only_if_undef; }; class N_assign_rec : public Node { public: N_assign_rec (Node *var_in, Node *value_in, bool if_undef_in=false) : var (var_in), value (value_in), only_if_undef (if_undef_in) { } ~N_assign_rec () { delete value; } Gen_type exec (); protected: Node *var; Node *value; bool only_if_undef; }; class N_empty_array : public Node { public: N_empty_array (Node *var_in) : var (var_in){ } ~N_empty_array () { delete var; } Gen_type exec (); protected: Node *var; }; class N_not : public Node { public: N_not (Node *st_in) : st (st_in) { } ~N_not () { delete st; } Gen_type exec () { return ! st->exec (); } protected: Node *st; }; class N_uminus : public Node { public: N_uminus (Node *st_in) : st (st_in) { } ~N_uminus () { delete st; } Gen_type exec () { set_msg_buffers (); return - (st->exec ()); } protected: Node *st; }; class N_gt : public Node { public: N_gt (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_gt () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return st1->exec () > st2->exec (); } protected: Node *st1; Node *st2; }; class N_lt : public Node { public: N_lt (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_lt () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return st1->exec () < st2->exec ();} protected: Node *st1; Node *st2; }; class N_ge : public Node { public: N_ge (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_ge () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return st1->exec () >= st2->exec (); } protected: Node *st1; Node *st2; }; class N_le : public Node { public: N_le (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_le () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return st1->exec () <= st2->exec (); } protected: Node *st1; Node *st2; }; class N_eq : public Node { public: N_eq (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_eq () { delete st1; delete st2; } Gen_type exec (); protected: Node *st1; Node *st2; }; class N_w_eq : public Node { public: N_w_eq (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_w_eq () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return (st1->exec ()).weak_eq (st2->exec ()); } protected: Node *st1; Node *st2; }; class N_neq : public Node { public: N_neq (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_neq () { delete st1; delete st2; } Gen_type exec (); protected: Node *st1; Node *st2; }; class N_w_neq : public Node { public: N_w_neq (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_w_neq () { delete st1; delete st2; } Gen_type exec () { set_msg_buffers (); return (st1->exec ()).weak_neq (st2->exec ()); } protected: Node *st1; Node *st2; }; class N_and : public Node { public: N_and (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_and () { delete st1; delete st2; } Gen_type exec (); protected: Node *st1; Node *st2; }; class N_or : public Node { public: N_or (Node *st1_in, Node *st2_in) : st1 (st1_in), st2 (st2_in) { } ~N_or () { delete st1; delete st2; } Gen_type exec (); protected: Node *st1; Node *st2; }; class N_plus : public Node { public: N_plus (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_plus () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; class N_epp : public Node { public: N_epp (Node *var_in, int increment_in, bool postfix_in) : var (var_in), increment (increment_in), postfix (postfix_in) { } ~N_epp () { delete var; } Gen_type exec (); protected: Node *var; int increment; bool postfix; }; class N_minus : public Node { public: N_minus (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_minus () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; class N_times : public Node { public: N_times (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_times () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; class N_div : public Node { public: N_div (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_div () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; class N_mod : public Node { public: N_mod (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_mod () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; class N_pow : public Node { public: N_pow (Node *n1_in, Node *n2_in) : n1 (n1_in), n2 (n2_in) { } ~N_pow () { delete n1; delete n2; } Gen_type exec (); protected: Node *n1; Node *n2; }; // Constants and Variables class N_const : public Node { public: N_const (Gen_type *value_in) : cst (value_in) { } ~N_const () { delete cst; } Gen_type exec (); protected: Gen_type *cst; }; class N_base_var : public Node { public: N_base_var (string var_name_in, char type_in): var_name (var_name_in), type (type_in), var (NULL), index (NULL) { } N_base_var (string var_name_in, Node *index_in) : var_name (var_name_in), type ('i'), var (NULL), index (index_in) { }; N_base_var (Node *var_in, Node *index_in) : type ('I'), var (var_in), index (index_in) { } virtual ~N_base_var () { delete var; delete index; } virtual Gen_type exec () = 0; char get_type () { return type; } bool item_syntax () { return type == 'i'; } bool array_syntax () { return type == 'a'; } bool var_item_syntax () { return type == 'I'; } virtual bool is_var () { return true; } virtual string get_var_name (); virtual Gen_type get_base_index (); protected: string var_name; char type; Node *var; // Used for multidimensional arrays Node *index; // Used for extracting array elements. }; class N_var : public N_base_var { public: N_var (string var_name_in, char type_in) : N_base_var (var_name_in, type_in) { } N_var (string var_name_in, Node *index_in) : N_base_var (var_name_in, index_in) { } N_var (Node *var_in, Node *index_in) : N_base_var (var_in, index_in) { } Gen_type exec (); Gen_type get_index () { return index->exec (); } }; class N_ind_expr : public N_base_var { public: N_ind_expr (Node *var_exp_in, char type_in) : N_base_var ("", type_in), var_exp (var_exp_in) { } N_ind_expr (Node *var_exp_in, Node *index_in) : N_base_var ("", index_in), var_exp (var_exp_in) { } ~N_ind_expr () { delete var_exp; } Gen_type exec (); string get_var_name (); protected: Node *var_exp; }; class N_undef : public Node { public: N_undef (Node *var_in) : var (var_in) { } ~N_undef () { delete var; } Gen_type exec (); protected: Node *var; }; class N_tobool : public Node { public: N_tobool (Node *var_in) : var (var_in) { } ~N_tobool () { delete var; } Gen_type exec (); protected: Node *var; }; class N_toint : public Node { public: N_toint (Node *var_in) : var (var_in) { } ~N_toint () { delete var; } Gen_type exec (); protected: Node *var; }; class N_tostring : public Node { public: N_tostring (Node *var_in) : var (var_in) { } ~N_tostring () { delete var; } Gen_type exec (); protected: Node *var; }; class N_toarray : public Node { public: N_toarray (Node *var_in) : var (var_in) { } ~N_toarray () { delete var; } Gen_type exec (); protected: Node *var; }; class N_isint : public Node { public: N_isint (Node *var_in) : var (var_in) { } ~N_isint () { delete var; } Gen_type exec () { return Gen_type ((var->exec ()).is_int ()); } protected: Node *var; }; class N_isstring : public Node { public: N_isstring (Node *var_in) : var (var_in) { } ~N_isstring () { delete var; } Gen_type exec () { return Gen_type ((var->exec ()).is_string ()); } protected: Node *var; }; class N_isarray : public Node { public: N_isarray (Node *var_in) : var (var_in) { } ~N_isarray () { delete var; } Gen_type exec () { return Gen_type ((var->exec ()).is_array ()); } protected: Node *var; }; // Functions class N_input : public Node { public: N_input () { } N_input (Gen_type *prefix_in); Gen_type exec () { return prefix + p2tree->get_input_file (); } protected: string prefix; }; class N_abs_input : public Node { public: N_abs_input () { } Gen_type exec () { return p2tree->get_abs_input_file (); } }; class N_output : public Node { public: N_output () { } N_output (Gen_type *prefix_in); Gen_type exec () {return prefix + p2tree->get_output_file (); } protected: string prefix; }; class N_abs_output : public Node { public: N_abs_output () { } Gen_type exec () { return p2tree->get_abs_output_file (); } }; class N_date : public Node { public: N_date (Node *format_init) : format (format_init) { } ~N_date () { delete format; } Gen_type exec (); protected: Node *format; }; class N_fdate : public N_dep { public: N_fdate (Node *file_in, Node *format_in) : N_dep (file_in), format (format_in), dir (string (get_w_dir ()) + "/" ) { } ~N_fdate () { delete format; } Gen_type exec (); protected: Node *format; string dir; }; class N_fsize : public N_dep { public: N_fsize (Node *file_in, Node *format_in) : N_dep (file_in), format (format_in), dir (string(get_w_dir ()) + "/" ) { } ~N_fsize () { delete format; } Gen_type exec (); protected: Node *format; string dir; }; class N_substr : public Node { public: N_substr (Node *str_in, Node *from_in) : str_n (str_in), from (from_in), len (NULL) { } N_substr (Node *str_in, Node *from_in, Node *len_in) : str_n (str_in), from (from_in), len (len_in) { } ~N_substr () { delete str_n; delete from; delete len; } Gen_type exec (); protected: Node *str_n; Node *from; Node *len; }; // Searching // find()/rfind() class N_find : public Node { public: N_find (Node *src_in, Node *chars_in, Node *from_in, bool reverse_in=false) : src (src_in), chars (chars_in), from (from_in), rev (reverse_in) { } ~N_find () { delete src; delete chars; delete from; } Gen_type exec (); protected: Node *src; Node *chars; Node *from; bool rev; }; //findfirstof()/findlastof()/findfirstnotof()/findlastnotof()/ class N_find_match : public Node { public: N_find_match (Node *src_in, Node *chrs_in, bool last_in, bool not_in=false) : src (src_in), chrs (chrs_in), last_flg (last_in), not_flg (not_in) { } ~N_find_match () { delete src; delete chrs; } Gen_type exec (); protected: Node *src; Node *chrs; bool last_flg; bool not_flg; }; class N_char : public Node { public: N_char (Node *src_in, Node *index_in) : src (src_in), index (index_in) { } ~N_char () { delete src; delete index; } Gen_type exec (); protected: Node *src; Node *index; }; class N_startswith : public Node { public: N_startswith (Node *src_in, Node *start_in) : src (src_in), start (start_in) { } ~N_startswith () { delete src; delete start; } Gen_type exec (); protected: Node *src; Node *start; }; class N_endswith : public Node { public: N_endswith (Node *src_in, Node *end_in) : src (src_in), end (end_in) { } ~N_endswith () { delete src; delete end; } Gen_type exec (); protected: Node *src; Node *end; }; // Functions modifying strings class N_insert : public Node { public: N_insert (Node *source_in, Node *index_in, Node *ins_in) : source (source_in), index (index_in), ins (ins_in) { } ~N_insert () { delete source; delete index; delete ins; } Gen_type exec (); protected: Node *source; Node *index; Node *ins; }; class N_replace : public Node { public: N_replace (Node *source_in, Node *from_in, Node *to_in, bool all_in) : source (source_in), from (from_in), to (to_in), all (all_in) { } ~N_replace () { delete source; delete from; delete to; } Gen_type exec (); protected: Node *source; Node *from; Node *to; bool all; }; class N_tok : public Node { public: N_tok (Node *source_in, Node *sep_list_in) : source (source_in), sep_list (sep_list_in) { } ~N_tok () { delete source; delete sep_list; } Gen_type exec (); protected: Node *source; Node *sep_list; }; class N_join : public Node { public: N_join (Node *source_in, Node *sep_in) : source (source_in), sep (sep_in) { } ~N_join () { delete source; delete sep; } Gen_type exec (); protected: Node *source; Node *sep; }; class N_trim : public Node { public: N_trim (Node *source_in) : source (source_in) { } ~N_trim () { delete source; } Gen_type exec (); protected: Node *source; }; class N_ltrim : public Node { public: N_ltrim (Node *source_in) : source (source_in) { } ~N_ltrim () { delete source; } Gen_type exec (); protected: Node *source; }; class N_rtrim : public Node { public: N_rtrim (Node *source_in) : source (source_in) { } ~N_rtrim () { delete source; } Gen_type exec (); protected: Node *source; }; class N_ch_case : public Node { public: N_ch_case (Node *source_in, bool to_lower_in=false) : source (source_in), to_lower (to_lower_in) { } ~N_ch_case () { delete source; } Gen_type exec (); protected: Node *source; bool to_lower; }; class N_length : public Node { public: N_length (Node *expr_in) : expr (expr_in) { } ~N_length () { delete expr; } Gen_type exec (); protected: Node *expr; }; class N_raiseerr : public Node { public: N_raiseerr (Node *expr_in) : expr1 (expr_in), expr2 (NULL) { } N_raiseerr (Node *expr1_in, Node *expr2_in) : expr1 (expr1_in), expr2 (expr2_in) { } ~N_raiseerr () { delete expr1; delete expr2; } Gen_type exec (); protected: Node *expr1; Node *expr2; }; class N_raisewarn : public Node { public: N_raisewarn (Node *expr_in) : expr1 (expr_in), expr2 (NULL) { } N_raisewarn (Node *expr1_in, Node *expr2_in) : expr1 (expr1_in), expr2 (expr2_in) { } ~N_raisewarn () { delete expr1; delete expr2; } Gen_type exec (); protected: Node *expr1; Node *expr2; }; class N_term : public Node { public: N_term (Node *msg_in) : msg (msg_in) { } ~N_term () { delete msg; } Gen_type exec (); protected: Node *msg; }; // Inclusions class N_verbatim : public N_dep { public: N_verbatim (Node *file_in) : N_dep (file_in), dir (string(get_w_dir ()) + "/" ) { } Gen_type exec (); protected: string dir; }; class N_include : public N_dep { public: N_include (Node *file_in) : N_dep (file_in) { } Gen_type exec (); }; class N_arg_include : public N_dep { public: N_arg_include (Node *file_in, Node *n_args_in) : N_dep (file_in), n_args (n_args_in) { } ~N_arg_include () { delete n_args; } Gen_type exec (); protected: Node *n_args; }; // External Commands and Scripts class N_cmd : public Node { public: N_cmd (Node *cmd_in, bool eval_in=false) : cmd (cmd_in), eval (eval_in) { } ~N_cmd () { delete cmd; } Gen_type exec (); protected: static const int buff_size = 200; Node *cmd; bool eval; }; class N_exec : public N_dep { public: N_exec (Node *file_in, bool eval_in=false) : N_dep (file_in), n_args (NULL), eval (eval_in) { } N_exec (Node *file_in, Node *n_args_in, bool eval_in=false) : N_dep (file_in), n_args (n_args_in), eval (eval_in) { } ~N_exec () { delete n_args; } Gen_type exec (); void deps (); protected: static const int buff_size = 200; Node *n_args; bool eval; }; class N_for : public Node { public: N_for (Node *before_in, Node *cond_in, Node *action_in, Node *stmt_in) : before (before_in), cond (cond_in), action (action_in), stmt (stmt_in) { } ~N_for () {delete before; delete cond; delete action; delete stmt;} Gen_type exec (); protected: Node *before; Node *cond; Node *action; Node *stmt; }; class N_while : public Node { public: N_while (Node *cond_in, Node *stmt_in): cond (cond_in), stmt (stmt_in) { } ~N_while () { delete cond; delete stmt; } Gen_type exec (); protected: Node *cond; Node *stmt; }; // Arrays class N_foreach : public Node { public: N_foreach (Node *loop_var_in, Node *arr_expr_in, Node *stmt_in) : loop_var (loop_var_in), arr_expr (arr_expr_in), stmt (stmt_in) { } ~N_foreach () {delete loop_var; delete arr_expr; delete stmt;} Gen_type exec (); protected: Node *loop_var; Node *arr_expr; Node *stmt; }; class N_list : public Node { public: N_list (Node *expr_list_in, Node *new_expr_in) : expr_list (expr_list_in), new_expr (new_expr_in) { } ~N_list () { delete expr_list; delete new_expr; } Gen_type exec (); protected: Node *expr_list; Node *new_expr; }; class N_fix_list : public Node { public: N_fix_list (Node *list_in) : list (list_in) { } ~N_fix_list () { delete list; } Gen_type exec (); protected: Node *list; }; class N_del : public Node { public: N_del (Node *source_in, Node *pos_in, Node *len_in) : source (source_in), pos (pos_in), len (len_in) { } ~N_del () { delete source; delete pos; delete len; } Gen_type exec (); protected: Node *source; Node *pos; Node *len; }; class N_push : public Node { public: N_push (Node *source_in, Node *item_in, Node *pos_in) : source (source_in), item (item_in), pos (pos_in) { } ~N_push () { delete source; delete item; delete pos; } Gen_type exec (); protected: Node *source; Node *item; Node *pos; }; class N_random : public Node { public: N_random (Node *from_in, Node *to_in) : from (from_in), to (to_in) { } ~N_random () { delete from; delete to; } Gen_type exec (); protected: Node *from; Node *to; }; class N_fileexists : public Node { public: N_fileexists (Node *file_in) : file (file_in), dir (string(get_w_dir ()) + "/" ) { } ~N_fileexists () { delete file; } Gen_type exec (); protected: Node *file; string dir; }; class N_fill : public Node { public: N_fill (Node *tmpl_string_in, Node *n_vars_in) : tmpl_string (tmpl_string_in), n_vars (n_vars_in) { } ~N_fill () { delete tmpl_string; delete n_vars; } Gen_type exec (); protected: Node *tmpl_string; Node *n_vars; }; // Link Adjustment class N_adj_link : public Node { public: N_adj_link () { }; Gen_type exec (); }; #endif // ! SRC_LANGUAGE_H