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