--- parser3/src/classes/op.C 2002/04/10 09:53:14 1.81 +++ parser3/src/classes/op.C 2002/04/15 10:35:21 1.83 @@ -4,7 +4,7 @@ Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) - $Id: op.C,v 1.81 2002/04/10 09:53:14 paf Exp $ + $Id: op.C,v 1.83 2002/04/15 10:35:21 paf Exp $ */ #include "classes.h" @@ -21,6 +21,7 @@ // defines #define OP_CLASS_NAME "OP" +#define CASE_DEFAULT_VALUE "DEFAULT" // class @@ -42,7 +43,7 @@ static void _if(Request& r, const String Value& condition_code=params->as_junction(0, "condition must be expression"); bool condition=r.process_to_value(condition_code, - 0/*no name*/, + /*0/*no name* /,*/ false/*don't intercept string*/).as_bool(); if(condition) r.write_pass_lang(r.process_to_value(params->as_junction(1, "'then' parameter must be code"))); @@ -165,7 +166,7 @@ static void _while(Request& r, const Str bool condition= r.process_to_value( vcondition, - 0/*no name*/, + /*0/*no name* /,*/ false/*don't intercept string*/).as_bool(); if(!condition) // ...condition is true break; @@ -214,7 +215,7 @@ static void _eval(Request& r, const Stri Value& expr=params->as_junction(0, "need expression"); // evaluate expresion Value *result=r.process_to_value(expr, - 0/*no name YET*/, + /*0/*no name YET* /,*/ true/*don't intercept string*/).as_expr_result(); if(params->size()>1) { Value& fmt=params->as_no_junction(1, "fmt must not be code"); @@ -269,19 +270,28 @@ r.sql_connect_time+=t[1]-t[0]; #ifndef DOXYGEN struct Switch_data { + Request *r; Value *searching; Value *found; Value *_default; }; #endif static void _switch(Request& r, const String&, MethodParams *params) { - Switch_data data={&r.process_to_value(params->get(0))}; + Switch_data data={&r, &r.process_to_value(params->get(0))}; Temp_hash_value switch_data_setter(r.classes_conf, *switch_data_name, &data); - r.process_to_string(params->as_junction(1, "switch cases must be code")); // and ignore result - - if(Value *code=data.found ? data.found : data._default) - r.write_pass_lang(r.process_to_value(*code)); + Value& cases_code=params->as_junction(1, "switch cases must be code"); + // execution of found ^case[...]{code} must be in context of ^switch[...]{code} + // because of stacked WWrapper used there as wcontext + r.process( + cases_code, + true/*intercept_string*/ + ); + if(Value *selected_code=data.found ? data.found : data._default) { + // setting code context, would execute in ^switch[...]{>>context<<} + selected_code->get_junction()->change_context(cases_code.get_junction()); + r.write_pass_lang(r.process_to_value(*selected_code)); + } } static void _case(Request& r, const String& method_name, MethodParams *params) { @@ -295,10 +305,15 @@ static void _case(Request& r, const Stri int count=params->size(); Value *code=¶ms->as_junction(--count, "case result must be code"); + + // killing context for safety, would execute in ^switch[...]{>>context<<} + // reason: context is stacked, and it would become invalid afterwards + code->get_junction()->change_context(0); + for(int i=0; iget(i)); - if(value.as_string() == *case_default_value) { + if(value.as_string() == CASE_DEFAULT_VALUE) { data->_default=code; break; } @@ -310,6 +325,11 @@ static void _case(Request& r, const Stri matches=data->searching->as_double() == value.as_double(); if(matches) { + if(data->found) + throw Exception("parser.runtime", + &method_name, + "duplicate found"); + data->found=code; break; }