summaryrefslogtreecommitdiff
path: root/src/lang/flow.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/lang/flow.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/lang/flow.cc')
-rw-r--r--src/lang/flow.cc198
1 files changed, 198 insertions, 0 deletions
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 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <lang/env.h>
21#include <mt/dates.h>
22using namespace std;
23
24TOK_IMPL(branch) {
25 int index=atoi(env[0]);
26 if(index<0) index+=env.args;
27 if(index>0&&index<env.args) env.parg(out,index);
28 else if(index<0||index>=env.args) THROW("htc: bad branching index "<<index);
29}
30
31TOK_IMPL(if) {
32 if(atob(env[0])) env.parg(out,1); else env.parg(out,2);
33}
34
35TOK_IMPL(nif) {
36 if(!atob(env[0])) env.parg(out,1); else env.parg(out,2);
37}
38
39TOK_IMPL(switch) {
40 sref s=env[0];
41 int i;
42 for(i=1;i+1<env.args;i+=2) if(env.parg(i)==s) { env.parg(out,i+1); return; }
43 if(i<env.args) env.parg(out,i);
44}
45
46/////////////////////////////////////////////////////////////////////
47
48static int eval(Env& env,expr_t* x,int mod) {
49 mswrite out;
50 if(x->status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod);
51 return atob(out.str());
52}
53
54TOK_IMPL(for) {
55 expr_t* x[4]={env.arg(0),env.arg(1),env.arg(2),env.arg(3)};
56 Env nenv(env);
57 for(eval(nenv,x[0],OP_ALL);
58 env.req->is_running()&&eval(nenv,x[1],OP_LOCAL);
59 eval(nenv,x[2],OP_LOCAL))
60 nenv.parse(out,x[3]);
61}
62
63TOK_IMPL(while) {
64 expr_t* x[2]={env.arg(0),env.arg(1)};
65 Env nenv(env);
66 while(env.req->is_running()&&eval(nenv,x[0],OP_ALL)) nenv.parse(out,x[1]);
67}
68
69/////////////////////////////////////////////////////////////////////
70
71TOK_IMPL(forall) {
72 mstring sep; env.parg(sep,-1);
73 sref s=env[0];
74 sref p,e=env[1];
75 expr_t* x=env.arg(2);
76 Env nenv(env);
77 if(sep.nempty()) {
78 charset seps(sep.c_str());
79 while(Split(p,e,seps)) {
80 nenv.aloc(s,p);
81 nenv.parse(out,x);
82 }
83 }
84 else {
85 while(Split(p,e)) {
86 nenv.aloc(s,p);
87 nenv.parse(out,x);
88 }
89 }
90}
91
92/////////////////////////////////////////////////////////////////////
93
94TOK_IMPL(on_arg) {
95 if(env.up&&env.up->onarg(atoi(env[0])-1)) env.parg(out,1); else env.parg(out,2);
96}
97TOK_IMPL(on_glob) { if(env.onglob(env[0])) env.parg(out,1); else env.parg(out,2); }
98TOK_IMPL(on_loc) { if(env.onloc(env[0])) env.parg(out,1); else env.parg(out,2); }
99
100/////////////////////////////////////////////////////////////////////
101
102TOK_IMPL(setlang) {
103 env.req->lang=Language(env[0]); if(env.req->lang<0) env.req->lang=0;
104}
105
106TOK_IMPL(lang) {
107 env.parg(out,env.req->lang);
108}
109
110/////////////////////////////////////////////////////////////////////
111
112void envAddFlow(tokmap& T)
113{
114 TOK_ADD(branch,"x*",tok_t::PUBLIC,
115 "%Multiple branch\n"
116 "%Syntax: \\branch{x}<body>..<body>\n"
117 "%\n"
118 "%x==0 means nothing is executed, the first body for x==1, etc\n"
119 "%Negative values wrap to end\n"
120 );
121 TOK_ADD(if,"xr?",tok_t::PUBLIC,
122 "%if - logical branch\n"
123 "%Syntax: \\if{x}{body}<else>\n"
124 "%\n"
125 "%if x is non-zero, evaluates body, otherwise else if exist\n"
126 );
127 TOK_ADD(nif,"xr?",tok_t::PUBLIC,
128 "%nif - logical branch\n"
129 "%Syntax: \\nif{x}{body}<else>\n"
130 "%\n"
131 "%if x is zero, evaluates body, otherwise else if exist\n"
132 );
133 TOK_ADD(switch,"x*",tok_t::PUBLIC,
134 "%Multiple switch\n"
135 "%Syntax: \\switch{x}<val><body>..<val><body>..<default>\n"
136 "%\n"
137 "%A sequence of pairs <val><body> follows x\n"
138 "%x==val means body is executed\n"
139 "%\n"
140 "%An unpaired body at the end is treated as default\n"
141 );
142
143 /////////////////////////////////////////////////////////////////////
144
145 TOK_ADD(for,"rrrr",tok_t::PRIVATE,
146 "%C style\n"
147 "%Syntax: \\for{start}{test}{next}{body}\n"
148 "%\n"
149 "%Note that test and next are evaluated with optimization: only\n"
150 "%local variables are updated. Hence, you cannot use a function\n"
151 "%as the whole test, only as a part of the test, as in i<\\function.\n"
152 );
153 TOK_ADD(while,"rr",tok_t::PRIVATE,
154 "%C style\n"
155 "%Syntax: \\while{test}{body}\n"
156 "%\n"
157 "%There is no optimization on test - globals are re-evaluated in each step\n"
158 );
159 TOK_ADD(forall,"xx?r",tok_t::PUBLIC,
160 "%Loop through elements\n"
161 "%Syntax: \\forall{varname}{list}<additional whitespace>{body}\n"
162 "%\n"
163 "%Default whitespace are ( \\t\\r\\n). Optional whitespace characters\n"
164 "%may be given. This enables the design of special lists.\n"
165 );
166
167 /////////////////////////////////////////////////////////////////////
168
169 TOK_ADD(on_arg,"xr?",tok_t::PUBLIC,
170 "%Do if arg exist and is non-empty\n"
171 "%Syntax: \\on.arg{number}{body}<else>\n"
172 );
173 TOK_ADD(on_glob,"xr?",tok_t::PUBLIC,
174 "%Do if global variable exist and is non-empty\n"
175 "%Syntax: \\on.glob{varname}{body}<else>\n"
176 );
177 TOK_ADD(on_loc,"xr?",tok_t::PUBLIC,
178 "%Do if local variable exist and is non-empty\n"
179 "%Syntax: \\on.loc{varname}{body}<else>\n"
180 );
181
182 /////////////////////////////////////////////////////////////////////
183
184 TOK_ADD(lang,"r*",tok_t::PUBLIC,
185 "%Branch on global language\n"
186 "%Syntax: \\lang{en}{sv}..\n"
187 "%\n"
188 "%Currently English (en) and Swedish (sv) are supported\n"
189 );
190 TOK_ADD(setlang,"x",tok_t::PUBLIC,
191 "%Set global language\n"
192 "%Syntax: \\setlang{language code list}\n"
193 "%\n"
194 "%The language actually set is a negotitation -\n"
195 "%the first code in the list recognized is set.\n"
196 "%If not found, the default language English (en) is set.\n"
197 );
198}