Annotation of parser3/src/types/pa_value.h, revision 1.83
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.83 ! paf 7: $Id: pa_value.h,v 1.82 2002/04/15 11:34:24 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.82 paf 212: /// updates the name which is used in error messages [sets only when were unnamed]
213: void update_name(const String& aname) {
1.83 ! paf 214: if(fname==unnamed_name)
1.82 paf 215: fname=&aname;
216: }
217:
218: /// sets the name which is used in error messages
1.68 parser 219: void set_name(const String& aname) {
220: fname=&aname;
221: }
1.1 paf 222:
1.26 paf 223: /// @return sure String. if it doesn't have string value barks
1.1 paf 224: const String& as_string() {
225: const String *result=get_string();
226: if(!result)
1.35 paf 227: bark("(%s) has no string representation");
1.6 paf 228:
1.1 paf 229: return *result;
230: }
231:
232: private:
233:
234: const String *fname;
235:
1.6 paf 236: protected:
1.1 paf 237:
1.22 paf 238: /// throws exception specifying bark-reason and name() type() of problematic value
1.65 parser 239: void bark(char *reason,
240: const char *alt_reason=0, const String *problem_source=0) const {
1.80 paf 241: throw Exception("parser.runtime",
1.65 parser 242: problem_source?problem_source:&name(),
243: problem_source?alt_reason:reason, type());
1.1 paf 244: }
245:
1.17 paf 246: };
247:
1.23 paf 248: /** \b junction is some code joined with context of it's evaluation.
1.22 paf 249:
250: there are code-junctions and method-junctions
251: - code-junctions are used when some parameter passed in cury brackets
252: - method-junctions used in ^method[] calls or $method references
253: */
1.17 paf 254: class Junction : public Pooled {
255: public:
256:
257: Junction(Pool& apool,
258: Value& aself,
259: VStateless_class *avclass, const Method *amethod,
260: Value *aroot,
261: Value *arcontext,
262: WContext *awcontext,
263: const Array *acode) : Pooled(apool),
264:
265: self(aself),
266: vclass(avclass), method(amethod),
267: root(aroot),
268: rcontext(arcontext),
269: wcontext(awcontext),
270: code(acode) {
1.81 paf 271: }
272:
273: void change_context(Junction *source) {
274: if(source) {
275: root=source->root;
276: rcontext=source->rcontext;
277: wcontext=source->wcontext;
278: } else {
279: root=rcontext=0;
280: wcontext=0;
281: }
1.17 paf 282: }
283:
1.22 paf 284: /// always present
1.17 paf 285: Value& self;
1.22 paf 286: //@{
287: /// @name either these // so called 'method-junction'
1.17 paf 288: VStateless_class *vclass; const Method *method;
1.22 paf 289: //@}
290: //@{
291: /// @name or these are present // so called 'code-junction'
1.17 paf 292: Value *root;
293: Value *rcontext;
294: WContext *wcontext;
295: const Array *code;
1.22 paf 296: //@}
1.48 paf 297: };
298:
299: /**
300: native code method
301: params can be NULL when
1.53 paf 302: method min&max params (see VStateless_class::add_native_method)
1.48 paf 303: counts are zero.
304: */
1.39 paf 305: typedef void (*Native_code_ptr)(Request& request,
306: const String& method_name,
1.48 paf 307: MethodParams *params);
1.39 paf 308:
1.23 paf 309: /**
1.22 paf 310: class method.
311:
312: methods can have
313: - named or
314: - numbered parameters
315:
316: methods can be
317: - parser or
318: - native onces
319:
1.40 paf 320: holds
1.22 paf 321: - parameter names or number limits
322: - local names
323: - code [parser or native]
324: */
1.17 paf 325: class Method : public Pooled {
326: public:
1.39 paf 327:
1.41 paf 328: /// allowed method call types
1.39 paf 329: enum Call_type {
1.41 paf 330: CT_ANY, ///< method can be called either statically or dynamically
331: CT_STATIC, ///< method can be called only statically
332: CT_DYNAMIC ///< method can be called only dynamically
1.39 paf 333: };
334:
335: /// name for error reporting
1.17 paf 336: const String& name;
1.39 paf 337: ///
338: Call_type call_type;
1.22 paf 339: //@{
340: /// @name either numbered params // for native-code methods = operators
1.17 paf 341: int min_numbered_params_count, max_numbered_params_count;
1.22 paf 342: //@}
343: //@{
344: /// @name or named params&locals // for parser-code methods
1.17 paf 345: Array *params_names; Array *locals_names;
1.22 paf 346: //@}
347: //@{
348: /// @name the Code
1.17 paf 349: const Array *parser_code;/*OR*/Native_code_ptr native_code;
1.22 paf 350: //@}
1.17 paf 351:
352: Method(
353: Pool& apool,
354: const String& aname,
1.39 paf 355: Call_type call_type,
1.17 paf 356: int amin_numbered_params_count, int amax_numbered_params_count,
357: Array *aparams_names, Array *alocals_names,
358: const Array *aparser_code, Native_code_ptr anative_code) :
359:
360: Pooled(apool),
361: name(aname),
1.39 paf 362: call_type(call_type),
1.17 paf 363: min_numbered_params_count(amin_numbered_params_count),
364: max_numbered_params_count(amax_numbered_params_count),
365: params_names(aparams_names), locals_names(alocals_names),
366: parser_code(aparser_code), native_code(anative_code) {
367: }
368:
1.22 paf 369: /// call this before invoking to ensure proper actual numbered params count
1.75 parser 370: void check_actual_numbered_params(
1.17 paf 371: Value& self, const String& actual_name, Array *actual_numbered_params) const {
1.54 paf 372:
1.17 paf 373: int actual_count=actual_numbered_params?actual_numbered_params->size():0;
374: if(actual_count<min_numbered_params_count) // not proper count? bark
1.80 paf 375: throw Exception("parser.runtime",
1.17 paf 376: &actual_name,
1.47 paf 377: "native method of %s (%s) accepts minimum %d parameter(s) (%d present)",
1.17 paf 378: self.name().cstr(),
379: self.type(),
1.47 paf 380: min_numbered_params_count,
381: actual_count);
1.17 paf 382:
383: }
1.1 paf 384: };
385:
386: #endif
E-mail: