Viewing file: MICG_gen.h (3.61 KB) -rw-rw-r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* * phc -- the open source php compiler * see doc/license/readme.license for licensing information * * Macro-Inline Code Generator (pronounced 'mig', like wig) */
#ifndef PHC_MICG_GEN #define PHC_MICG_GEN
#include "MICG.h"
#include "lib/String.h" #include "lib/Map.h"
#define MICG_TRUE "TRUE" #define MICG_FALSE "FALSE" namespace MICG {
/* The symtable keeps track of the objects passed to a macro instantiation, and * their names. It handles type checks, and abstracts a number of operations * like lookups. */ class Symtable : public virtual GC_obj { Map<string, Object*> obj_map; Map<string, TYPE_NAME*> type_map;
public: // Each of these returns a String or Node. If coerce is set, a Node will // be converted to a String with convert_to_string. Booleans are always // converted. Object* get_lookup (Lookup*, bool coerce = false); Object* get_param (Param*, bool coerce = false);
// Check type and return an MIR::Node for the parameter NAME. MIR::Node* get_node (PARAM_NAME* in);
// Get the parameter, checking its type, that it exists, etc. Object* get (PARAM_NAME* param, bool coerce = false);
void add_parameter (PARAM_NAME* param_name, TYPE_NAME* type_name, Object* param); void check_param (PARAM_NAME* name); };
}
class MICG_gen : public virtual GC_obj { public: // callback_t: A function which takes a string and returns a string. typedef string (*callback_t)(Object_list*);
// Convert an Object to a String: // Booleans are converted to MICG_TRUE/MICG_FALSE // Identifiers are converted using get_value_as_string. // Other Objects are converted to "true" (this allows lookups to // succeed if they find anything). static String* convert_to_string (Object*);
// Return a string representation of the list. This should never fail, and // is primarily for debugging. static String* to_string_rep (Object_list*);
private: Map<string, std::pair<callback_t, int> > callbacks; Map<string, MICG::Macro_list> macros;
public: void add_macro (MICG::Macro*); void add_macro_def (string str, string filename);
string instantiate (string macro_name, Object_list* params, MICG::Node* anchor = NULL);
// Check that the signature matches (its not called 'matches' to avoid // overloading the word 'match', which is generated by maketea). bool suitable (MICG::Macro* sig, Object_list* params);
// Get the macro named NAME, whose rules match PARAMs. MICG::Macro* get_macro (string name, Object_list* params);
// Look through PARAMS, finding any lists which are not declared with the // 'list' type. These are intended to be iterated through at call-time. // Return a list of parameter lists on which the the macro must be // instantiated. // We assume that only 1 list can be expanded per time, and this // will throw an error if this is violated. List<Object_list*>* expand_list_params (MICG::Macro* m, Object_list* params);
// Actually substitute the parameters into the body. string instantiate_body (MICG::Body* body, MICG::Symtable* symtable);
MICG::Symtable* get_symtable (MICG::Macro* macro, Object_list*);
Object* get_expr (MICG::Expr* expr, MICG::Symtable* symtable, bool coerce = false); Object_list* get_expr_list (MICG::Expr_list* exprs, MICG::Symtable* symtable, bool coerce = false);
string callback (MICG::MACRO_NAME* macro, Object_list* params); void register_callback (string name, callback_t callback, int param_count);
// Wrappers around common calls. The parameters are fetched from SYMTABLE // using their actual parameters in MC and CB. String* exec (MICG::Macro_call* mc, MICG::Symtable* symtable); String* exec (MICG::Callback* cb, MICG::Symtable* symtable); };
#endif // PHC_MICG_GEN
|