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