Annotation of parser3/src/types/pa_value.h, revision 1.92
1.22 paf 1: /** @file
1.24 paf 2: Parser: Value, Method, Junction class decls.
3:
1.78 paf 4: Copyright (c) 2001, 2002 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.92 ! paf 11: static const char* IDENT_VALUE_H="$Date: 2002/08/12 11:22:55 $";
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.13 paf 17: #include "pa_globals.h"
1.1 paf 18:
1.9 paf 19: class VStateless_class;
1.1 paf 20: class WContext;
21: class Request;
1.35 paf 22: class Table;
1.17 paf 23: class Junction;
24: class Method;
1.20 paf 25: class Hash;
1.42 paf 26: class VFile;
1.64 parser 27: class MethodParams;
1.1 paf 28:
1.31 paf 29: /// grandfather of all @a values in @b Parser
1.1 paf 30: class Value : public Pooled {
31: public: // Value
32:
1.53 paf 33: /// all: value type, used for error reporting and 'is' expression operator
1.1 paf 34: virtual const char *type() const =0;
1.89 paf 35:
1.91 paf 36: /** remember derived class instance
37: - VObject: the only client
38: */
1.92 ! paf 39: virtual Value *set_derived(Value * /*aderived*/) { return 0; }
1.91 paf 40:
1.89 paf 41: /**
42: all except derived class: this if @atype eq type()
43: derived class: can locate parent class by it's type
44: */
45: virtual Value *as(const char *atype) {
46: return atype && strcmp(type(), atype)==0?this:0;
47: }
1.59 parser 48:
1.23 paf 49: /** is this value defined?
1.22 paf 50: @return for
1.63 parser 51: - VVoid: false
1.69 parser 52: - VString: eq ''=false, ne ''=true
1.72 parser 53: - VHash: count!=0
1.71 parser 54: - VTable: count!=0
1.22 paf 55: - others: true
56: */
1.38 paf 57: virtual bool is_defined() const { return true; }
1.59 parser 58:
1.35 paf 59: /** is this value string?
60: @return for
61: - VString: true
62: - others: false
63: */
1.38 paf 64: virtual bool is_string() const { return false; }
1.59 parser 65:
1.23 paf 66: /** what's the meaning of this value in context of expression?
1.22 paf 67: @return for
1.34 paf 68: - VString: fstring as VDouble or this depending on return_string_as_is
1.70 parser 69: - VBool: clone
70: - VDouble: clone
71: - VInt: clone
1.63 parser 72: - VVoid: this
1.27 paf 73: - VFile: this
1.45 paf 74: - VImage: this
1.64 parser 75: - VDate: ftime -> float days
1.72 parser 76: - VTable: count
77: - VHash: count
1.22 paf 78: */
1.75 parser 79: virtual Value *as_expr_result(bool /*return_string_as_is*/=false) {
1.34 paf 80: bark("(%s) can not be used in expression"); return 0;
81: }
1.59 parser 82:
1.23 paf 83: /** extract Hash
1.22 paf 84: @return for
1.25 paf 85: - VHash: fhash
86: - VResponse: ffields
1.22 paf 87: */
1.76 parser 88: virtual Hash *get_hash(const String * /*source*/) { return 0; }
1.59 parser 89:
1.23 paf 90: /** extract const String
1.22 paf 91: @return for
1.25 paf 92: - VString: value
1.63 parser 93: - VVoid: ""
1.25 paf 94: - VDouble: value
1.66 parser 95: - VInt: value
1.25 paf 96: - VBool: must be 0: so in ^if(1>2) it would'nt become "FALSE" string which is 'true'
1.22 paf 97: - others: 0
98: - WContext: accumulated fstring
99: */
1.1 paf 100: virtual const String *get_string() { return 0; }
1.59 parser 101:
1.23 paf 102: /** extract double
1.22 paf 103: @return for
1.25 paf 104: - VString: value
105: - VDouble: value
1.59 parser 106: - VInt: value
1.25 paf 107: - VBool: value
1.63 parser 108: - VVoid: 0
1.64 parser 109: - VDate: ftime -> float days
1.22 paf 110: */
1.72 parser 111: virtual double as_double() const { bark("(%s) does not have numerical (double) value"); return 0; }
1.59 parser 112:
113: /** extract integer
114: - VString: value
115: - VDouble: value
116: - VInt: value
117: - VBool: value
1.63 parser 118: - VVoid: 0
1.73 parser 119: - VTable: count
120: - VHash: count
1.59 parser 121: */
1.72 parser 122: virtual int as_int () const { bark("(%s) does not have numerical (int) value"); return 0; }
1.59 parser 123:
1.23 paf 124: /** extract bool
1.22 paf 125: @return for
1.63 parser 126: - VVoid: false
1.25 paf 127: - VBool: value
128: - VInt: 0 or !0
129: - VDouble: 0 or !0
1.27 paf 130: - VFile: true
1.64 parser 131: - VDate: 0 or !0
1.73 parser 132: - VTable: count
133: - VHash: count
1.22 paf 134: */
1.72 parser 135: virtual bool as_bool() const { bark("(%s) does not have logical value"); return 0; }
1.59 parser 136:
1.42 paf 137: /** extract file
138: @return for
139: - VFile: this
140: - VString: vfile
1.45 paf 141: - VImage: true
1.42 paf 142: */
1.75 parser 143: virtual VFile *as_vfile(String::Untaint_lang /*lang*/=String::UL_UNSPECIFIED,
144: bool /*origins_mode*/=false) {
1.42 paf 145: bark("(%s) does not have file value"); return 0;
146: }
1.59 parser 147:
1.23 paf 148: /** extract Junction
1.22 paf 149: @return for
150: - junction: itself
151: */
1.1 paf 152: virtual Junction *get_junction() { return 0; }
1.59 parser 153:
1.23 paf 154: /** extract Value element
1.22 paf 155: @return for
1.25 paf 156: - VHash: (key)=value
1.29 paf 157: - VStateless_class: +$method
158: - VStateless_object: +$method
1.58 paf 159: - VClass: (field)=STATIC value;(method)=method_ref with self=object_class
1.51 paf 160: - VCodeFrame: wcontext_transparent
161: - VMethodFrame: my or self_transparent
1.52 paf 162: - VTable: columns,methods
1.28 paf 163: - VEnv: field
1.67 parser 164: - VForm: CLASS,method,field
1.45 paf 165: - VString: $method
1.30 paf 166: - VRequest: fields
1.45 paf 167: - VResponse: method,fields
1.28 paf 168: - VCookie: field
1.45 paf 169: - VFile: method,field
1.67 parser 170: - VDate: CLASS,method,field
1.26 paf 171: */
1.75 parser 172: virtual Value *get_element(const String& /*name*/) { bark("(%s) has no elements"); return 0; }
1.92 ! paf 173:
! 174: /** extract Value junction of name @a name, when @a looking_down looks only down
! 175: @return for
! 176: - VStateless_class: self or parent method junction
! 177: - VObject: child or self or parent method junction
! 178: */
! 179: virtual Junction *get_junction(const String& /*name*/, bool /*looking_down*/) { bark("(%s) has no junctions"); return 0; }
! 180:
! 181: /** extract base object of Value
! 182: @return for
! 183: - VObject: fbase
! 184: */
! 185: virtual Value *base_object() { bark("(%s) has no base object"); return 0; }
1.59 parser 186:
1.31 paf 187: /** store Value element under @a name
1.22 paf 188: @return for
1.25 paf 189: - VHash: (key)=value
1.67 parser 190: - VStateless_object: (CLASS)=vclass;(method)=method_ref
1.26 paf 191: - VStateless_class: (field)=value - static values only
192: - VStateless_object: (field)=value
1.51 paf 193: - VCodeFrame: wcontext_transparent
194: - VMethodFrame: my or self_transparent
1.25 paf 195: - VResponse: (attribute)=value
196: - VCookie: field
1.22 paf 197: */
1.75 parser 198: virtual void put_element(const String& name, Value * /*value*/) {
1.65 parser 199: // to prevent modification of system classes,
200: // created at system startup, and not having exception
201: // handler installed, we neet to bark using request.pool
202: bark("(%s) does not accept elements",
203: "element can not be stored to %s", &name);
204: }
1.59 parser 205:
1.23 paf 206: /** extract VStateless_class
1.22 paf 207: @return for
1.85 paf 208: - VX: x_class
1.25 paf 209: - VStateless_class: this
1.92 ! paf 210: - VObject: fclass
1.26 paf 211: - WContext: none yet | transparent
1.85 paf 212: these are methodless classes:
213: - VBool: 0
214: - VJunction: 0
215: - VEnv: 0
216: - VRequest: 0
217: - VCookie: 0
1.22 paf 218: */
1.85 paf 219: virtual VStateless_class *get_class()=0;
1.32 paf 220:
221: /** extract VTable
222: @return for
1.35 paf 223: - VTable: ftable
1.32 paf 224: */
1.35 paf 225: virtual Table *get_table() { return 0; }
1.1 paf 226:
227: public: // usage
228:
1.84 paf 229: Value(Pool& apool) : Pooled(apool) {
1.68 parser 230: }
1.1 paf 231:
1.26 paf 232: /// @return sure String. if it doesn't have string value barks
1.1 paf 233: const String& as_string() {
234: const String *result=get_string();
235: if(!result)
1.35 paf 236: bark("(%s) has no string representation");
1.6 paf 237:
1.1 paf 238: return *result;
239: }
240:
1.6 paf 241: protected:
1.1 paf 242:
1.22 paf 243: /// throws exception specifying bark-reason and name() type() of problematic value
1.65 parser 244: void bark(char *reason,
245: const char *alt_reason=0, const String *problem_source=0) const {
1.80 paf 246: throw Exception("parser.runtime",
1.84 paf 247: problem_source,
248: alt_reason?alt_reason:reason, type());
1.1 paf 249: }
250:
1.17 paf 251: };
252:
1.23 paf 253: /** \b junction is some code joined with context of it's evaluation.
1.22 paf 254:
255: there are code-junctions and method-junctions
256: - code-junctions are used when some parameter passed in cury brackets
257: - method-junctions used in ^method[] calls or $method references
258: */
1.17 paf 259: class Junction : public Pooled {
260: public:
261:
262: Junction(Pool& apool,
263: Value& aself,
264: VStateless_class *avclass, const Method *amethod,
265: Value *aroot,
266: Value *arcontext,
267: WContext *awcontext,
268: const Array *acode) : Pooled(apool),
269:
270: self(aself),
271: vclass(avclass), method(amethod),
272: root(aroot),
273: rcontext(arcontext),
274: wcontext(awcontext),
275: code(acode) {
1.81 paf 276: }
277:
278: void change_context(Junction *source) {
279: if(source) {
280: root=source->root;
281: rcontext=source->rcontext;
282: wcontext=source->wcontext;
283: } else {
284: root=rcontext=0;
285: wcontext=0;
286: }
1.17 paf 287: }
288:
1.22 paf 289: /// always present
1.17 paf 290: Value& self;
1.22 paf 291: //@{
292: /// @name either these // so called 'method-junction'
1.17 paf 293: VStateless_class *vclass; const Method *method;
1.22 paf 294: //@}
295: //@{
296: /// @name or these are present // so called 'code-junction'
1.17 paf 297: Value *root;
298: Value *rcontext;
299: WContext *wcontext;
300: const Array *code;
1.22 paf 301: //@}
1.48 paf 302: };
303:
304: /**
305: native code method
306: params can be NULL when
1.53 paf 307: method min&max params (see VStateless_class::add_native_method)
1.48 paf 308: counts are zero.
309: */
1.39 paf 310: typedef void (*Native_code_ptr)(Request& request,
311: const String& method_name,
1.48 paf 312: MethodParams *params);
1.39 paf 313:
1.23 paf 314: /**
1.22 paf 315: class method.
316:
317: methods can have
318: - named or
319: - numbered parameters
320:
321: methods can be
322: - parser or
323: - native onces
324:
1.40 paf 325: holds
1.22 paf 326: - parameter names or number limits
327: - local names
328: - code [parser or native]
329: */
1.17 paf 330: class Method : public Pooled {
331: public:
1.39 paf 332:
1.41 paf 333: /// allowed method call types
1.39 paf 334: enum Call_type {
1.41 paf 335: CT_ANY, ///< method can be called either statically or dynamically
336: CT_STATIC, ///< method can be called only statically
337: CT_DYNAMIC ///< method can be called only dynamically
1.39 paf 338: };
339:
340: /// name for error reporting
1.17 paf 341: const String& name;
1.39 paf 342: ///
343: Call_type call_type;
1.22 paf 344: //@{
345: /// @name either numbered params // for native-code methods = operators
1.17 paf 346: int min_numbered_params_count, max_numbered_params_count;
1.22 paf 347: //@}
348: //@{
349: /// @name or named params&locals // for parser-code methods
1.17 paf 350: Array *params_names; Array *locals_names;
1.22 paf 351: //@}
352: //@{
353: /// @name the Code
1.17 paf 354: const Array *parser_code;/*OR*/Native_code_ptr native_code;
1.22 paf 355: //@}
1.17 paf 356:
357: Method(
358: Pool& apool,
359: const String& aname,
1.39 paf 360: Call_type call_type,
1.17 paf 361: int amin_numbered_params_count, int amax_numbered_params_count,
362: Array *aparams_names, Array *alocals_names,
363: const Array *aparser_code, Native_code_ptr anative_code) :
364:
365: Pooled(apool),
366: name(aname),
1.39 paf 367: call_type(call_type),
1.17 paf 368: min_numbered_params_count(amin_numbered_params_count),
369: max_numbered_params_count(amax_numbered_params_count),
370: params_names(aparams_names), locals_names(alocals_names),
371: parser_code(aparser_code), native_code(anative_code) {
372: }
373:
1.22 paf 374: /// call this before invoking to ensure proper actual numbered params count
1.75 parser 375: void check_actual_numbered_params(
1.84 paf 376: Value& self, const String& actual_name, Array *actual_numbered_params) const;
1.86 paf 377: };
378:
379: /// Auto-object used for temporarily substituting/removing elements
380: class Temp_value_element {
381: Value& fwhere;
382: const String& fname;
383: Value *saved;
384: public:
385: Temp_value_element(Value& awhere, const String& aname, Value *awhat) :
386: fwhere(awhere),
387: fname(aname),
388: saved(awhere.get_element(aname)) {
389: fwhere.put_element(aname, awhat);
390: }
391: ~Temp_value_element() {
392: fwhere.put_element(fname, saved);
393: }
1.1 paf 394: };
395:
396: #endif
E-mail: