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