diff options
Diffstat (limited to 'src/lang/ops.cc')
| -rw-r--r-- | src/lang/ops.cc | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/lang/ops.cc b/src/lang/ops.cc new file mode 100644 index 0000000..7916d96 --- /dev/null +++ b/src/lang/ops.cc | |||
| @@ -0,0 +1,150 @@ | |||
| 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 | |||
| 22 | ////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | struct xop_t : public op_t { | ||
| 25 | typedef void (*xop1_t)(mstream&,Env&,const sref&); | ||
| 26 | typedef void (*xop2_t)(mstream&,Env&,const sref&,const sref&); | ||
| 27 | xop_t(const mstring& s,int p1,int p2,int l,int r, | ||
| 28 | xop1_t op1,xop2_t op2,const mstring& d): | ||
| 29 | op_t(s,p1,p2,l,r,(op1_t)op1,(op2_t)op2,d) {} | ||
| 30 | }; | ||
| 31 | |||
| 32 | ////////////////////////////////////////////////////// | ||
| 33 | |||
| 34 | #define X1_IMPL(name) \ | ||
| 35 | static void impl_##name(mstream& out,Env& env,const sref& a) throw(merror_t) | ||
| 36 | #define X2_IMPL(name) \ | ||
| 37 | static void impl_##name(mstream& out,Env& env,const sref& L,const sref& R) throw(merror_t) | ||
| 38 | |||
| 39 | #define X1_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,p,0,l,r,impl_##f,0,d)) | ||
| 40 | #define X2_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,0,p,l,r,0,impl_##f,d)) | ||
| 41 | |||
| 42 | ////////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | X1_IMPL(exist) { | ||
| 45 | mstring name; | ||
| 46 | swrite sw(name); | ||
| 47 | env.eval(sw,a,0); | ||
| 48 | out<<env.gloc_find(name); | ||
| 49 | } | ||
| 50 | |||
| 51 | X2_IMPL(new) { | ||
| 52 | mstring name; | ||
| 53 | swrite sw(name); | ||
| 54 | env.eval(sw,L,0); | ||
| 55 | env.aloc(name,R); | ||
| 56 | } | ||
| 57 | |||
| 58 | X2_IMPL(assign) { | ||
| 59 | mstring name; | ||
| 60 | swrite sw(name); | ||
| 61 | env.eval(sw,L,0); | ||
| 62 | env.sloc(name,R); | ||
| 63 | } | ||
| 64 | |||
| 65 | X2_IMPL(incr) { | ||
| 66 | mstring name; | ||
| 67 | swrite sw(name); | ||
| 68 | env.eval(sw,L,0); | ||
| 69 | env.sloc(name,ftoa(atof(env.gloc(name))+atof(R))); | ||
| 70 | } | ||
| 71 | |||
| 72 | X2_IMPL(decr) { | ||
| 73 | mstring name; | ||
| 74 | swrite sw(name); | ||
| 75 | env.eval(sw,L,0); | ||
| 76 | env.sloc(name,ftoa(atof(env.gloc(name))-atof(R))); | ||
| 77 | } | ||
| 78 | |||
| 79 | ////////////////////////////////////////////////////// | ||
| 80 | |||
| 81 | X2_IMPL(new_rec) { | ||
| 82 | if(*L=='@') env.gloc_adb(L.popf(),R); | ||
| 83 | else { | ||
| 84 | rpile list; env.gloc_list(list,R); | ||
| 85 | int n=*R=='@'?R.size()-1:R.size(); | ||
| 86 | for(int i=0;i<list.size();i++) env.aloc(L+list[i].right(n),env.gloc(list[i])); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | X2_IMPL(copy_rec) { | ||
| 91 | rpile list; env.gloc_list(list,L); | ||
| 92 | int n=*L=='@'?L.size()-1:L.size(); | ||
| 93 | for(int i=0;i<list.size();i++) env.sloc(R+list[i].right(n),env.gloc(list[i])); | ||
| 94 | } | ||
| 95 | |||
| 96 | ////////////////////////////////////////////////////// | ||
| 97 | |||
| 98 | void envAddOps(opmap& M,tokmap& T) | ||
| 99 | { | ||
| 100 | opAddHEXP(M); | ||
| 101 | X1_ADDN(40,0,1,exist,?, | ||
| 102 | "True if a exist\n" | ||
| 103 | "Syntax: ? (varname)\n" | ||
| 104 | "Returns: (int)\n" | ||
| 105 | ); | ||
| 106 | X2_ADDN(4,1,2,new,:=, | ||
| 107 | "New assignment\n" | ||
| 108 | "Syntax: (varname) := (expr)\n" | ||
| 109 | "Returns: nothing\n" | ||
| 110 | ); | ||
| 111 | X2_ADDN(4,1,2,assign,=, | ||
| 112 | "Assignment to existing variable\n" | ||
| 113 | "Syntax: (varname) = (expr)\n" | ||
| 114 | "Returns: nothing\n" | ||
| 115 | ); | ||
| 116 | X2_ADDN(4,1,2,incr,+=, | ||
| 117 | "Increment operator\n" | ||
| 118 | "Syntax: (varname) += (real)\n" | ||
| 119 | "Returns: nothing\n" | ||
| 120 | ); | ||
| 121 | X2_ADDN(4,1,2,decr,-=, | ||
| 122 | "Decrement operator\n" | ||
| 123 | "Syntax: (varname) -= (real)\n" | ||
| 124 | "Returns: nothing\n" | ||
| 125 | ); | ||
| 126 | |||
| 127 | X2_ADDN(4,1,1,new_rec,<-, | ||
| 128 | "New local record\n" | ||
| 129 | "Syntax: (partial name) <- (partial name)\n" | ||
| 130 | "Returns: nothing\n" | ||
| 131 | "\n" | ||
| 132 | "If the partial name @ is given as the left argument,\n" | ||
| 133 | "a new record is created or silently updated, depending\n" | ||
| 134 | "on whether it is unique or not according to the default order.\n" | ||
| 135 | "The index table must however exist in the right argument.\n" | ||
| 136 | "\n" | ||
| 137 | "The default order may only be set at creation or when saving\n" | ||
| 138 | "a database to disk.\n" | ||
| 139 | ); | ||
| 140 | X2_ADDN(4,1,1,copy_rec,->, | ||
| 141 | "Copy local record\n" | ||
| 142 | "Syntax: (partial name) -> (partial name)\n" | ||
| 143 | "Returns: nothing\n" | ||
| 144 | "\n" | ||
| 145 | "The partial name @ for data base records works in both arguments.\n" | ||
| 146 | "\n" | ||
| 147 | "Generates an error if any of the expanded names of the right\n" | ||
| 148 | "partial argument does not exist.\n" | ||
| 149 | ); | ||
| 150 | } | ||
