Annotation of parser3/src/types/pa_value.h, revision 1.109.2.17
1.22 paf 1: /** @file
1.109.2.11 paf 2: Parser: Value, Method, Junction .
1.24 paf 3:
1.109.2.14 paf 4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.79 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
8: #ifndef PA_VALUE_H
9: #define PA_VALUE_H
1.87 paf 10:
1.109.2.17! paf 11: static const char* IDENT_VALUE_H="$Date: 2003/02/03 09:17:48 $";
1.1 paf 12:
13: #include "pa_pool.h"
14: #include "pa_string.h"
15: #include "pa_array.h"
16: #include "pa_exception.h"
1.109.2.11 paf 17: #include "pa_operation.h"
1.1 paf 18:
1.99 paf 19: // forwards
20:
1.9 paf 21: class VStateless_class;
1.1 paf 22: class WContext;
23: class Request;
1.109.2.4 paf 24: class Junction; DECLARE_OBJECT_PTR(Junction);
1.109.2.12 paf 25: class Method; DECLARE_OBJECT_PTR(Method);
1.109.2.2 paf 26: template<typename K, typename V> class Hash;
1.109.2.12 paf 27: class Value; DECLARE_OBJECT_PTR(Value);
1.109.2.13 paf 28: typedef Hash<StringPtr, ValuePtr> HashStringValue; DECLARE_OBJECT_PTR(HashStringValue);
1.109.2.17! paf 29: typedef Array<ValuePtr> ArrayValue; DECLARE_OBJECT_PTR(ArrayValue);
1.64 parser 30: class MethodParams;
1.109.2.4 paf 31: class VObject; DECLARE_OBJECT_PTR(VObject);
1.99 paf 32: class VMethodFrame;
1.109.2.15 paf 33: class VFile; DECLARE_OBJECT_PTR(VFile);
34: class Table;
1.1 paf 35:
1.31 paf 36: /// grandfather of all @a values in @b Parser
1.109.2.11 paf 37: class Value: public PA_Object {
1.1 paf 38: public: // Value
39:
1.106 paf 40: /// value type, used for error reporting and 'is' expression operator
1.109.2.14 paf 41: virtual const char* type() const =0;
1.89 paf 42:
1.91 paf 43: /** remember derived class instance
44: - VObject: the only client
45: */
1.109.2.4 paf 46: virtual VObjectPtr set_derived(VObjectPtr /*aderived*/) { return 0; }
1.91 paf 47:
1.89 paf 48: /**
1.95 paf 49: all except VObject/VClass: this if @atype eq type()
50: VObject/VClass: can locate parent class by it's type
1.89 paf 51: */
1.109.2.14 paf 52: virtual ValuePtr as(const char* atype, bool looking_up) {
1.96 paf 53: return atype && strcmp(type(), atype)==0?this:0;
1.89 paf 54: }
1.97 paf 55: /// type checking helper, uses Value::as
1.109.2.14 paf 56: bool is(const char* atype) { return as(atype, false)!=0; }
1.59 parser 57:
1.106 paf 58: /// is this value defined?
1.38 paf 59: virtual bool is_defined() const { return true; }
1.59 parser 60:
1.106 paf 61: /// is this value string?
1.38 paf 62: virtual bool is_string() const { return false; }
1.59 parser 63:
1.106 paf 64: /// what's the meaning of this value in context of expression?
1.109.2.2 paf 65: virtual ValuePtr as_expr_result(bool /*return_string_as_is*/=false) {
1.34 paf 66: bark("(%s) can not be used in expression"); return 0;
67: }
1.59 parser 68:
1.109.2.7 paf 69: /** extract HashStringValue if any
70: WARNING: FOR LOCAL USE ONLY, THIS POINTER IS NOT TO PASS TO ANYBODY!
71: */
1.109.2.13 paf 72: virtual HashStringValue* get_hash(StringPtr /*source*/) { return 0; }
1.59 parser 73:
1.106 paf 74: /// extract const String
1.109.2.13 paf 75: virtual StringPtr get_string(Pool *pool) { return 0; }
1.59 parser 76:
1.106 paf 77: /// extract double
1.72 parser 78: virtual double as_double() const { bark("(%s) does not have numerical (double) value"); return 0; }
1.59 parser 79:
1.106 paf 80: /// extract integer
1.72 parser 81: virtual int as_int () const { bark("(%s) does not have numerical (int) value"); return 0; }
1.59 parser 82:
1.106 paf 83: /// extract bool
1.72 parser 84: virtual bool as_bool() const { bark("(%s) does not have logical value"); return 0; }
1.59 parser 85:
1.106 paf 86: /// extract file
1.109.2.4 paf 87: virtual VFilePtr as_vfile(Pool& pool, String::Untaint_lang lang=String::UL_UNSPECIFIED,
88: bool origins_mode=false);
1.59 parser 89:
1.106 paf 90: /// extract Junction
1.109.2.2 paf 91: virtual JunctionPtr get_junction() { return 0; }
1.59 parser 92:
1.93 paf 93: /** extract base object of Value
94: @return for
95: - VObject: fbase
96: */
1.109.2.2 paf 97: virtual ValuePtr base_object() { bark("(%s) has no base object"); return 0; }
1.93 paf 98:
1.106 paf 99: /// extract Value element
1.109.2.13 paf 100: virtual ValuePtr get_element(StringPtr /*aname*/, Value& /*aself*/, bool /*looking_up*/) { bark("(%s) has no elements"); return 0; }
1.92 paf 101:
1.106 paf 102: /// store Value element under @a name
1.109.2.13 paf 103: virtual bool put_element(StringPtr name, ValuePtr /*value*/, bool /*replace*/) {
1.65 parser 104: // to prevent modification of system classes,
105: // created at system startup, and not having exception
106: // handler installed, we neet to bark using request.pool
107: bark("(%s) does not accept elements",
1.109.2.2 paf 108: "element can not be stored to %s", name);
1.93 paf 109: return false;
1.65 parser 110: }
1.59 parser 111:
1.106 paf 112: /// extract VStateless_class
1.85 paf 113: virtual VStateless_class *get_class()=0;
1.107 paf 114:
115: /// extract VStateless_class
116: virtual VStateless_class *get_last_derived_class() {
117: return get_class();
118: };
1.108 paf 119: /// extract base object or class of Value, if any
1.109.2.6 paf 120: virtual ValuePtr base() { bark("(%s) has can not have base"); return 0; }
1.32 paf 121:
1.106 paf 122: /// extract VTable
1.109.2.15 paf 123: virtual Table* get_table() { return 0; }
1.1 paf 124:
125: public: // usage
126:
1.26 paf 127: /// @return sure String. if it doesn't have string value barks
1.109.2.13 paf 128: StringPtr as_string(Pool *pool) {
129: StringPtr result=get_string(pool);
1.109.2.2 paf 130: if(!result.get())
1.35 paf 131: bark("(%s) has no string representation");
1.6 paf 132:
1.109.2.2 paf 133: return result;
1.1 paf 134: }
135:
1.6 paf 136: protected:
1.1 paf 137:
1.22 paf 138: /// throws exception specifying bark-reason and name() type() of problematic value
1.65 parser 139: void bark(char *reason,
1.109.2.14 paf 140: const char* alt_reason=0, StringPtr problem_source=Exception::undefined_source) const {
1.80 paf 141: throw Exception("parser.runtime",
1.84 paf 142: problem_source,
143: alt_reason?alt_reason:reason, type());
1.1 paf 144: }
145:
1.17 paf 146: };
147:
1.23 paf 148: /** \b junction is some code joined with context of it's evaluation.
1.22 paf 149:
150: there are code-junctions and method-junctions
151: - code-junctions are used when some parameter passed in cury brackets
152: - method-junctions used in ^method[] calls or $method references
1.99 paf 153:
154: Junctions register themselves in method_frame [if any] for consequent invalidation.
155: This prevents evaluation of junctions in outdated context
156:
157: To stop situations like this:
158: @code
159: @main[]
160: ^method1[]
161: ^method2[]
162:
163: @method1[]
164: $junction{
165: some code
166: }
167:
168: @method2[]
169: ^junction[]
170: @endcode
171:
1.101 paf 172: On wcontext[most dynamic context of all] scope exit (WContext::~WContext()) got cleaned -
173: Junction::wcontext becomes WContext.fparent (if any),
174: or Junction::method_frame becomes 0 (if no parent), which later in Request::process triggers exception
175:
176: parent changing helps ^switch implementation to remain simple
1.22 paf 177: */
1.109.2.2 paf 178: class Junction: public PA_Object {
1.17 paf 179: public:
180:
1.109.2.2 paf 181: Junction(
1.109.2.16 paf 182: ValuePtr aself,
1.109.2.11 paf 183: const Method* amethod,
184: VMethodFrame* amethod_frame,
185: Value* arcontext,
186: WContext* awcontext,
187: ArrayOperationPtr acode);
1.81 paf 188:
1.100 paf 189: void reattach(WContext *new_wcontext);
1.17 paf 190:
1.105 paf 191: /// always present
1.109.2.16 paf 192: ValuePtr self;
1.22 paf 193: //@{
194: /// @name either these // so called 'method-junction'
1.109.2.11 paf 195: const Method* method;
1.22 paf 196: //@}
197: //@{
198: /// @name or these are present // so called 'code-junction'
1.109.2.11 paf 199: VMethodFrame* method_frame;
200: Value* rcontext;
201: WContext* wcontext;
202: ArrayOperationPtr code;
1.22 paf 203: //@}
1.48 paf 204: };
205:
206: /**
207: native code method
208: params can be NULL when
1.53 paf 209: method min&max params (see VStateless_class::add_native_method)
1.48 paf 210: counts are zero.
211: */
1.109.2.11 paf 212: typedef void (*NativeCodePtr)(Request& request,
1.109.2.13 paf 213: StringPtr method_name,
1.109.2.10 paf 214: MethodParams& params);
215:
1.109.2.13 paf 216: typedef Array<StringPtr> ArrayString; DECLARE_OBJECT_PTR(ArrayString);
1.109.2.10 paf 217:
1.39 paf 218:
1.23 paf 219: /**
1.22 paf 220: class method.
221:
222: methods can have
223: - named or
224: - numbered parameters
225:
226: methods can be
227: - parser or
228: - native onces
229:
1.40 paf 230: holds
1.22 paf 231: - parameter names or number limits
232: - local names
233: - code [parser or native]
234: */
1.109.2.2 paf 235: class Method: public PA_Object {
1.17 paf 236: public:
1.39 paf 237:
1.41 paf 238: /// allowed method call types
1.39 paf 239: enum Call_type {
1.41 paf 240: CT_ANY, ///< method can be called either statically or dynamically
241: CT_STATIC, ///< method can be called only statically
242: CT_DYNAMIC ///< method can be called only dynamically
1.39 paf 243: };
244:
245: /// name for error reporting
1.109.2.13 paf 246: StringPtr name;
1.39 paf 247: ///
248: Call_type call_type;
1.22 paf 249: //@{
250: /// @name either numbered params // for native-code methods = operators
1.17 paf 251: int min_numbered_params_count, max_numbered_params_count;
1.22 paf 252: //@}
253: //@{
254: /// @name or named params&locals // for parser-code methods
1.109.2.13 paf 255: ArrayStringPtr params_names; ArrayStringPtr locals_names;
1.22 paf 256: //@}
257: //@{
258: /// @name the Code
1.109.2.11 paf 259: ArrayOperationPtr parser_code;/*OR*/NativeCodePtr native_code;
1.22 paf 260: //@}
1.17 paf 261:
1.109.2.11 paf 262: Method::Method(
1.109.2.13 paf 263: StringPtr aname,
1.39 paf 264: Call_type call_type,
1.17 paf 265: int amin_numbered_params_count, int amax_numbered_params_count,
1.109.2.13 paf 266: ArrayStringPtr aparams_names, ArrayStringPtr alocals_names,
1.109.2.11 paf 267: ArrayOperationPtr aparser_code, NativeCodePtr anative_code) :
1.17 paf 268:
269: name(aname),
1.39 paf 270: call_type(call_type),
1.17 paf 271: min_numbered_params_count(amin_numbered_params_count),
272: max_numbered_params_count(amax_numbered_params_count),
273: params_names(aparams_names), locals_names(alocals_names),
274: parser_code(aparser_code), native_code(anative_code) {
275: }
276:
1.22 paf 277: /// call this before invoking to ensure proper actual numbered params count
1.75 parser 278: void check_actual_numbered_params(
1.109.2.13 paf 279: Value& self, StringPtr actual_name, MethodParams& actual_numbered_params) const;
1.86 paf 280: };
281:
282: /// Auto-object used for temporarily substituting/removing elements
283: class Temp_value_element {
284: Value& fwhere;
1.109.2.13 paf 285: StringPtr fname;
1.109.2.2 paf 286: ValuePtr saved;
1.86 paf 287: public:
1.109.2.13 paf 288: Temp_value_element(Value& awhere, StringPtr aname, ValuePtr awhat) :
1.86 paf 289: fwhere(awhere),
290: fname(aname),
1.108 paf 291: saved(awhere.get_element(aname, awhere, false)) {
1.93 paf 292: fwhere.put_element(aname, awhat, false);
1.86 paf 293: }
294: ~Temp_value_element() {
1.93 paf 295: fwhere.put_element(fname, saved, false);
1.86 paf 296: }
1.1 paf 297: };
1.109.2.1 paf 298:
299: /**
300: $content-type[text/html] ->
301: content-type: text/html
302: $content-type[$value[text/html] charset[windows-1251]] ->
303: content-type: text/html; charset=windows-1251
304: */
1.109.2.17! paf 305: StringPtr attributed_meaning_to_string(Pool& pool,
! 306: ValuePtr meaning,
! 307: String::Untaint_lang lang=String::UL_UNSPECIFIED, bool forced=false);
1.109.2.7 paf 308:
309: // defines
310:
311: ///@{common field names
312: #define CHARSET_NAME "charset"
1.109.2.8 paf 313: #define VALUE_NAME "value"
1.109.2.9 paf 314: #define CONTENT_TYPE_NAME "content-type"
315: //@}
1.109.2.8 paf 316:
317: ///@{common field names
318: extern StringPtr value_name;
1.109.2.9 paf 319: extern StringPtr content_type_name;
1.109.2.7 paf 320: ///@}
1.1 paf 321:
322: #endif
1.109.2.5 paf 323:
E-mail: