From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/lang/flow.cc | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/lang/flow.cc (limited to 'src/lang/flow.cc') diff --git a/src/lang/flow.cc b/src/lang/flow.cc new file mode 100644 index 0000000..c7c70a0 --- /dev/null +++ b/src/lang/flow.cc @@ -0,0 +1,198 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +TOK_IMPL(branch) { + int index=atoi(env[0]); + if(index<0) index+=env.args; + if(index>0&&index=env.args) THROW("htc: bad branching index "<status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod); + return atob(out.str()); +} + +TOK_IMPL(for) { + expr_t* x[4]={env.arg(0),env.arg(1),env.arg(2),env.arg(3)}; + Env nenv(env); + for(eval(nenv,x[0],OP_ALL); + env.req->is_running()&&eval(nenv,x[1],OP_LOCAL); + eval(nenv,x[2],OP_LOCAL)) + nenv.parse(out,x[3]); +} + +TOK_IMPL(while) { + expr_t* x[2]={env.arg(0),env.arg(1)}; + Env nenv(env); + while(env.req->is_running()&&eval(nenv,x[0],OP_ALL)) nenv.parse(out,x[1]); +} + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(forall) { + mstring sep; env.parg(sep,-1); + sref s=env[0]; + sref p,e=env[1]; + expr_t* x=env.arg(2); + Env nenv(env); + if(sep.nempty()) { + charset seps(sep.c_str()); + while(Split(p,e,seps)) { + nenv.aloc(s,p); + nenv.parse(out,x); + } + } + else { + while(Split(p,e)) { + nenv.aloc(s,p); + nenv.parse(out,x); + } + } +} + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(on_arg) { + if(env.up&&env.up->onarg(atoi(env[0])-1)) env.parg(out,1); else env.parg(out,2); +} +TOK_IMPL(on_glob) { if(env.onglob(env[0])) env.parg(out,1); else env.parg(out,2); } +TOK_IMPL(on_loc) { if(env.onloc(env[0])) env.parg(out,1); else env.parg(out,2); } + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(setlang) { + env.req->lang=Language(env[0]); if(env.req->lang<0) env.req->lang=0; +} + +TOK_IMPL(lang) { + env.parg(out,env.req->lang); +} + +///////////////////////////////////////////////////////////////////// + +void envAddFlow(tokmap& T) +{ + TOK_ADD(branch,"x*",tok_t::PUBLIC, + "%Multiple branch\n" + "%Syntax: \\branch{x}..\n" + "%\n" + "%x==0 means nothing is executed, the first body for x==1, etc\n" + "%Negative values wrap to end\n" + ); + TOK_ADD(if,"xr?",tok_t::PUBLIC, + "%if - logical branch\n" + "%Syntax: \\if{x}{body}\n" + "%\n" + "%if x is non-zero, evaluates body, otherwise else if exist\n" + ); + TOK_ADD(nif,"xr?",tok_t::PUBLIC, + "%nif - logical branch\n" + "%Syntax: \\nif{x}{body}\n" + "%\n" + "%if x is zero, evaluates body, otherwise else if exist\n" + ); + TOK_ADD(switch,"x*",tok_t::PUBLIC, + "%Multiple switch\n" + "%Syntax: \\switch{x}....\n" + "%\n" + "%A sequence of pairs follows x\n" + "%x==val means body is executed\n" + "%\n" + "%An unpaired body at the end is treated as default\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(for,"rrrr",tok_t::PRIVATE, + "%C style\n" + "%Syntax: \\for{start}{test}{next}{body}\n" + "%\n" + "%Note that test and next are evaluated with optimization: only\n" + "%local variables are updated. Hence, you cannot use a function\n" + "%as the whole test, only as a part of the test, as in i<\\function.\n" + ); + TOK_ADD(while,"rr",tok_t::PRIVATE, + "%C style\n" + "%Syntax: \\while{test}{body}\n" + "%\n" + "%There is no optimization on test - globals are re-evaluated in each step\n" + ); + TOK_ADD(forall,"xx?r",tok_t::PUBLIC, + "%Loop through elements\n" + "%Syntax: \\forall{varname}{list}{body}\n" + "%\n" + "%Default whitespace are ( \\t\\r\\n). Optional whitespace characters\n" + "%may be given. This enables the design of special lists.\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(on_arg,"xr?",tok_t::PUBLIC, + "%Do if arg exist and is non-empty\n" + "%Syntax: \\on.arg{number}{body}\n" + ); + TOK_ADD(on_glob,"xr?",tok_t::PUBLIC, + "%Do if global variable exist and is non-empty\n" + "%Syntax: \\on.glob{varname}{body}\n" + ); + TOK_ADD(on_loc,"xr?",tok_t::PUBLIC, + "%Do if local variable exist and is non-empty\n" + "%Syntax: \\on.loc{varname}{body}\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(lang,"r*",tok_t::PUBLIC, + "%Branch on global language\n" + "%Syntax: \\lang{en}{sv}..\n" + "%\n" + "%Currently English (en) and Swedish (sv) are supported\n" + ); + TOK_ADD(setlang,"x",tok_t::PUBLIC, + "%Set global language\n" + "%Syntax: \\setlang{language code list}\n" + "%\n" + "%The language actually set is a negotitation -\n" + "%the first code in the list recognized is set.\n" + "%If not found, the default language English (en) is set.\n" + ); +} -- cgit v1.2.3