1 #include "kernel/mod2.h"
2
3 #include "omalloc/omalloc.h"
4 #include "coeffs/coeffs.h"
5 #include "Singular/ipid.h"
6 #include "Singular/subexpr.h"
7 #include "Singular/tok.h"
8 #include "Singular/blackbox.h"
9 #include "Singular/ipshell.h"
10
11 #include "Singular/ipid.h"
12 // extern coeffs coeffs_BIGINT
13
14
15 #include "bigintm.h"
16
17
18 #define HAVE_BIGINTM 1
19
20 namespace
21 {
22
23 #ifdef HAVE_BIGINTM
24 STATIC_VAR int bigintm_type_id = -1;
25 #endif
26
27 #ifdef HAVE_BIGINTM
bigintm_String(blackbox *,void * d)28 static char * bigintm_String(blackbox */*b*/, void *d)
29 { if (d==NULL) return omStrDup("oo");
30 else
31 {
32 StringSetS("");
33 number n=(number)d; n_Write(n, coeffs_BIGINT); d=(void*)n;
34 return StringEndS();
35 }
36 }
bigintm_Copy(blackbox *,void * d)37 static void * bigintm_Copy(blackbox*/*b*/, void *d)
38 { number n=(number)d; return n_Copy(n, coeffs_BIGINT); }
39
bigintm_Assign(leftv l,leftv r)40 static BOOLEAN bigintm_Assign(leftv l, leftv r)
41 {
42 assume( l->Typ() == bigintm_type_id );
43
44 // blackbox *ll=getBlackboxStuff(l->Typ());
45
46 if (r->Typ()>MAX_TOK)
47 {
48 if (bigintm_type_id == r->Typ())
49 {
50 // blackbox *rr=getBlackboxStuff(r->Typ());
51
52 if (l->Data()!=NULL) { number n1=(number)l->Data(); n_Delete(&n1,coeffs_BIGINT); }
53 number n2=(number)r->CopyD();
54 if (l->rtyp==IDHDL)
55 {
56 IDDATA((idhdl)l->data)=(char *)n2;
57 }
58 else
59 {
60 l->data=(void *)n2;
61 }
62 return FALSE;
63 }
64 else
65 {
66 Werror("bigintm_Assign: assign %s (%d) = %s (%d)",
67 getBlackboxName(l->Typ()), l->Typ(),
68 getBlackboxName(r->Typ()), r->Typ());
69 return TRUE;
70 }
71 }
72 else if (r->Typ()==INT_CMD)
73 {
74 if (l->Data()!=NULL) { number n1=(number)l->Data(); n_Delete(&n1,coeffs_BIGINT); }
75 number n2=n_Init((int)(long)r->Data(),coeffs_BIGINT);
76 if (l->rtyp==IDHDL)
77 {
78 IDDATA((idhdl)l->data)=(char *)n2;
79 }
80 else
81 {
82 l->data=(void *)n2;
83 }
84 return FALSE;
85 }
86 else
87 Werror("assign %d = %d",l->Typ(),r->Typ());
88
89 return TRUE;
90 }
91
bigintm_Op1(int op,leftv l,leftv r)92 BOOLEAN bigintm_Op1(int op,leftv l, leftv r)
93 {
94 // interpreter: a1 is ist bigintm
95 assume( r->Typ() == bigintm_type_id );
96 /*
97 // "typeof( <blackbox> )" is handled by 'blackboxDefaultOp1'
98 if (op==TYPEOF_CMD)
99 {
100 l->data=omStrDup(getBlackboxName(r->Typ()));
101 l->rtyp=STRING_CMD;
102 return FALSE;
103 }
104 */
105
106 return blackboxDefaultOp1(op, l, r);
107 }
108
109
110 static BOOLEAN bigintm_OpM(int op, leftv res, leftv args);
111
112
bigintm_Op2(int op,leftv res,leftv a1,leftv a2)113 static BOOLEAN bigintm_Op2(int op, leftv res, leftv a1, leftv a2)
114 {
115 // interpreter: a1 is ist bigintm
116 assume( a1->Typ() == bigintm_type_id );
117
118 // blackbox *a=getBlackboxStuff(a1->Typ());
119 number n1=(number)a1->Data();
120 switch(op)
121 {
122 case '+':
123 {
124 if (a2->Typ()==INT_CMD)
125 {
126 number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
127 number n=n_Add(n1,n2, coeffs_BIGINT);
128 res->data=(void *)n;
129 res->rtyp=a1->Typ();
130 return FALSE;
131 }
132 else if (a2->Typ()==a1->Typ())
133 {
134 number n2=(number)a2->Data();
135 number n=n_Add(n1,n2, coeffs_BIGINT);
136 res->data=(void *)n;
137 res->rtyp=a1->Typ();
138 return FALSE;
139 }
140
141 Werror("bigintm_Op2: Op: '+': Sorry unsupported 2nd argument-type: %s in", Tok2Cmdname(a2->Typ()));
142 return TRUE;
143 }
144
145 case '-':
146 {
147 if (a2->Typ()==INT_CMD)
148 {
149 number n2=n_Init((int)(long)a2->Data(),coeffs_BIGINT);
150 number n=n_Sub(n1,n2, coeffs_BIGINT);
151 res->data=(void *)n;
152 res->rtyp=a1->Typ();
153 return FALSE;
154 }
155 else if (a2->Typ()==a1->Typ())
156 {
157 number n2=(number)a2->Data();
158 number n=n_Sub(n1,n2, coeffs_BIGINT);
159 res->data=(void *)n;
160 res->rtyp=a1->Typ();
161 return FALSE;
162 }
163
164 Werror("bigintm_Op2: Op: '-': Sorry unsupported 2nd argument-type: %s in", Tok2Cmdname(a2->Typ()));
165 return TRUE;
166 }
167
168
169 case '*':
170 {
171 if (a2->Typ()==INT_CMD)
172 {
173 number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
174 number n=n_Mult(n1,n2, coeffs_BIGINT);
175 res->data=(void *)n;
176 res->rtyp=a1->Typ();
177 return FALSE;
178 }
179 else if (a2->Typ()==a1->Typ())
180 {
181 number n2=(number)a2->Data();
182 number n=n_Mult(n1,n2, coeffs_BIGINT);
183 res->data=(void *)n;
184 res->rtyp=a1->Typ();
185 return FALSE;
186 }
187 Werror("bigintm_Op2: Op: '*': Sorry unsupported 2nd argument-type: '%s' in", Tok2Cmdname(a2->Typ()));
188 return TRUE;
189 }
190
191 case EQUAL_EQUAL:
192 {
193 if( a1 == a2)
194 {
195 res->data= (void *) (TRUE);
196 res->rtyp= INT_CMD;
197 return FALSE;
198 } else
199 if (a2->Typ()==INT_CMD)
200 {
201 number n2=n_Init((int)(long)a2->Data(), coeffs_BIGINT);
202 res->data=(void *) (long) n_Equal(n1,n2, coeffs_BIGINT);
203 res->rtyp= INT_CMD;
204 n_Delete(&n2,coeffs_BIGINT);
205 return FALSE;
206 }
207 else if (a2->Typ()==a1->Typ())
208 {
209 number n2=(number)a2->Data();
210 res->data=(void *) (long) n_Equal(n1,n2, coeffs_BIGINT);
211 res->rtyp= INT_CMD;
212 return FALSE;
213 }
214
215 Werror("bigintm_Op2: Op: '==': Sorry unsupported 2nd argument-type: '%s' in", Tok2Cmdname(a2->Typ()));
216 return TRUE;
217 }
218
219 case '.':
220 {
221
222 if (a2->name==NULL)
223 {
224 Werror("bigintm_Op2: Op: '.': 2nd argument-type: '%s'(%d) should be a NAME", Tok2Cmdname(a2->Typ()), a2->Typ());
225 return TRUE;
226 }
227
228 Werror("bigintm_Op2: Op: '.': 2nd argument-type: '%s'(%d) is called '%s' in ", Tok2Cmdname(a2->Typ()), a2->Typ(), a2->name);
229 return TRUE;
230 }
231
232 default:
233 return blackboxDefaultOp2(op,res,a1,a2);
234 }
235 }
236 // BOOLEAN opM(int op, leftv res, leftv args)
bigintm_OpM(int op,leftv res,leftv args)237 static BOOLEAN bigintm_OpM(int op, leftv res, leftv args)
238 {
239 // interpreter: args->1. arg is ist bigintm
240 assume( args->Typ() == bigintm_type_id );
241 blackbox *a=getBlackboxStuff(args->Typ());
242 switch(op)
243 {
244 case STRING_CMD:
245 {
246 res->data=(void *)a->blackbox_String(a,args->Data());
247 res->rtyp=STRING_CMD;
248 return FALSE;
249 }
250
251 default:
252 return blackboxDefaultOpM(op, res, args);
253 }
254 return blackboxDefaultOpM(op, res, args);
255 }
256
bigintm_destroy(blackbox *,void * d)257 static void bigintm_destroy(blackbox */*b*/, void *d)
258 {
259 if (d!=NULL)
260 {
261 number n=(number)d;
262 n_Delete(&n, coeffs_BIGINT);
263 }
264 }
265
266 #endif
267
268 }
269
270 // this is only a demo
bigintm_setup()271 BOOLEAN bigintm_setup()
272 {
273 #ifndef HAVE_BIGINTM
274 Werror("bigintm_setup: Sorry BIGINTM was not compiled in!");
275 return TRUE; // ok, TRUE = error!
276 #else
277
278 if( bigintm_type_id == -1 )
279 {
280 blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
281 // all undefined entries will be set to default in setBlackboxStuff
282 // the default Print is quite usefule,
283 // all other are simply error messages
284 b->blackbox_destroy=bigintm_destroy;
285 b->blackbox_String=bigintm_String;
286 //b->blackbox_Print=blackbox_default_Print;
287 //b->blackbox_Init=blackbox_default_Init;
288 b->blackbox_Copy=bigintm_Copy;
289 b->blackbox_Assign=bigintm_Assign;
290 b->blackbox_Op1=bigintm_Op1;
291 b->blackbox_Op2=bigintm_Op2;
292 //b->blackbox_Op3=blackboxDefaultOp3;
293 b->blackbox_OpM=bigintm_OpM;
294
295 bigintm_type_id = setBlackboxStuff(b,"bigintm");
296
297 Print("bigintm_setup: created a blackbox type [%d] '%s'",bigintm_type_id, getBlackboxName(bigintm_type_id));
298 PrintLn();
299
300 return FALSE; // ok, TRUE = error!
301 }
302 else
303 {
304 Werror("bigintm_setup: Sorry should NOT be run twice!");
305 return TRUE; // ok, TRUE = error!
306 }
307
308 #endif
309 }
310
311
312
313