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