View Issue Details

IDProjectCategoryView StatusLast Update
0000337LDMud 3.5LPC Languagepublic2009-01-08 05:41
ReporterGawain Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status newResolutionopen 
Summary0000337: bigint patch for 3.3
Descriptionthis is a patch i wrote some time ago to bring bigints to lpc.
unfortunately i have currently no time available to work on it.
perhaps someone want to take over.

the patch introduces a new datatype "bigint" to lpc.
the operations + and - are working, others have to be implemented.
TagsNo tags attached.
Attached Files
bigint.diff (26,199 bytes)   
diff -Naur 3-3/src/bigint.c 3-3-gawain/src/bigint.c
--- 3-3/src/bigint.c	1970-01-01 01:00:00.000000000 +0100
+++ 3-3-gawain/src/bigint.c	2003-08-15 09:23:14.000000000 +0200
@@ -0,0 +1,65 @@
+/*------------------------------------------------------------------
+ * Bigint Implementation
+ *
+ *------------------------------------------------------------------
+ *
+ *------------------------------------------------------------------
+ */
+
+#include "driver.h"
+
+#ifdef USE_BIGINT
+
+#include "bigint.h"
+#include "typedefs.h"
+
+/*=========================================================================*/
+/*                           GC SUPPORT                                    */
+
+#ifdef GC_SUPPORT
+
+/*-------------------------------------------------------------------------*/
+
+void
+clear_bigint_ref (bigint_t * pStruct)
+
+/* Clear all references held by bigint <pStruct>
+ */
+
+{
+} /* clear_bigint_ref() */
+
+/*-------------------------------------------------------------------------*/
+void
+count_bigint_ref (bigint_t * pStruct)
+
+/* Count all references held by bigint <pStruct>
+ */
+
+{
+} /* count_bigint_ref() */
+
+/*-------------------------------------------------------------------------*/
+void
+clear_tabled_bigint_refs (void)
+
+/* Clear all references held by the bigint types in the hash table.
+ */
+
+{
+} /* clear_tabled_bigint_refs() */
+
+/*-------------------------------------------------------------------------*/
+void
+remove_unreferenced_bigints (void)
+
+/* Free all bigints in the table which are not marked as referenced.
+ * This function must be called before freeing all unreferenced strings!
+ */
+
+{
+} /* remove_unreferenced_bigints() */
+
+#endif /* GC_SUPPORT */
+
+#endif /* USE_BIGINT */
diff -Naur 3-3/src/bigint.h 3-3-gawain/src/bigint.h
--- 3-3/src/bigint.h	1970-01-01 01:00:00.000000000 +0100
+++ 3-3-gawain/src/bigint.h	2003-08-15 22:22:39.000000000 +0200
@@ -0,0 +1,64 @@
+#ifndef BIGINT_H_
+#define BIGINT_H_ 1
+
+#include "driver.h"
+
+#ifdef USE_BIGINT
+
+#include <gmp.h>
+
+/* --- Types --- */
+
+/* --- struct bigint_s: a LPC long instance
+ *
+ */
+
+struct bigint_s
+{
+    mpz_t number;  /* The type object */
+//    p_int ref;     /* Number of references */
+};
+
+/* --- Macros --- */
+
+/* long_t *ref_long(long_t *t)
+ *   Add another ref to long <t> and return <t>.
+ */
+
+#define ref_bigint(t) ((t)->ref++, (t))
+
+
+/* void free_bigint(bigint_t *m)
+ *   Subtract one ref from bigint <t>, and free the bigint
+ *   fully if the refcount reaches zero.
+ */
+
+#define free_bigint(t) MACRO( if (--((t)->ref) <= 0) bigint_free(t); )
+
+
+/* p_int deref_bigint(bigint_t *t)
+ *   Subtract one ref from bigint <t>, but don't check if it needs to
+ *   be freed. Result is the number of refs left.
+ */
+
+#define deref_bigint(t) (--(t)->ref)
+
+#endif /* USE_BIGINT */
+
+
+/* --- Prototypes --- */
+
+// ...
+
+#ifdef GC_SUPPORT
+/*
+extern void clear_bigint_type_ref (bigint_type_t * pSType);
+extern void clear_bigint_ref (bigint_t * pStruct);
+extern void clear_tabled_bigint_refs (void);
+extern void count_bigint_type_ref (bigint_type_t * pSType);
+extern void count_bigint_ref (bigint_t * pStruct);
+extern void remove_unreferenced_bigints (void);
+*/
+#endif /* GC_SUPPORT */
+
+#endif /* BIGINT_H_ */
diff -Naur 3-3/src/exec.h 3-3-gawain/src/exec.h
--- 3-3/src/exec.h	2003-03-29 09:07:28.000000000 +0100
+++ 3-3-gawain/src/exec.h	2003-08-15 09:31:03.000000000 +0200
@@ -237,11 +237,21 @@
 #ifdef USE_STRUCTS
 #define TYPE_STRUCT        11   /* Secondary info is the struct id */
 
+#ifdef USE_BIGINT
+#define TYPE_BIGINT        12
+#define TYPEMAP_SIZE       13
+#else
 #define TYPEMAP_SIZE       12   /* Number of types */
+#endif /* USE_BIGINT */
 
 #else
 
+#ifdef USE_BIGINT
+#define TYPE_BIGINT        11
+#define TYPEMAP_SIZE       12   /* Number of types */
+#else
 #define TYPEMAP_SIZE       11   /* Number of types */
+#endif /* USE_BIGINT */
 
 #endif /* USE_STRUCTS */
 
diff -Naur 3-3/src/func_spec 3-3-gawain/src/func_spec
--- 3-3/src/func_spec	2003-08-10 05:41:53.000000000 +0200
+++ 3-3-gawain/src/func_spec	2003-08-15 14:17:04.000000000 +0200
@@ -68,6 +68,9 @@
 #ifdef USE_PARSE_COMMAND
         parse_command
 #endif
+#ifdef USE_BIGINT
+        bigint
+#endif
         local
         catch
 "++"    inc
diff -Naur 3-3/src/interpret.c 3-3-gawain/src/interpret.c
--- 3-3/src/interpret.c	2003-07-21 23:40:58.000000000 +0200
+++ 3-3-gawain/src/interpret.c	2003-08-22 13:03:25.000000000 +0200
@@ -210,6 +210,9 @@
 #include "actions.h"
 #include "array.h"
 #include "backend.h"
+#ifdef USE_BIGINT
+#include "bigint.h"
+#endif
 #include "call_out.h"
 #include "closure.h"
 #include "comm.h"
@@ -436,6 +439,9 @@
    , /* T_SYMBOL  */  "symbol"
    , /* T_QUOTED_ARRAY */  "quoted-array"
    , /* T_STRUCT */  "struct"
+#ifdef USE_BIGINT
+   , /* T_BIGINT */  "bigint"
+#endif
    , /* T_CHAR_LVALUE */           "char-lvalue"
    , /* T_STRING_RANGE_LVALUE */   "string-range-lvalue"
    , /* T_POINTER_RANGE_LVALUE */  "array-range-lvalue"
@@ -1014,6 +1020,12 @@
         NOOP;
         break;
 
+#ifdef USE_BIGINT
+    case T_BIGINT:
+	mpz_clear(v->u.bigint.number);
+	break;
+#endif
+
     case T_STRING:
       {
         string_t *str = v->u.str;
@@ -1303,6 +1315,12 @@
     case T_MAPPING:
         (void)ref_mapping(to->u.map);
         break;
+
+#ifdef USE_BIGINT
+    case T_BIGINT:
+	mpz_init_set(to->u.bigint.number, from->u.bigint.number);
+	break;
+#endif
     }
 
     /* Protection against endless reference loops */
@@ -1438,6 +1456,12 @@
     }
     *to = *from;
 
+#ifdef USE_BIGINT
+    if(from->type == T_BIGINT) {
+	mpz_init_set(to->u.bigint.number, from->u.bigint.number);
+    }
+#endif
+
     /* Protection against endless reference loops */
     if (to->type == T_LVALUE || to->type == T_PROTECTED_LVALUE)
     {
@@ -1501,6 +1525,12 @@
     }
     *to = *from;
 
+#ifdef USE_BIGINT
+    if(from->type == T_BIGINT) {
+	mpz_init_set(to->u.bigint.number, from->u.bigint.number);
+    }
+#endif
+
     /* Protection against endless reference loops */
     if (to->type == T_LVALUE || to->type == T_PROTECTED_LVALUE)
     {
@@ -1595,6 +1625,13 @@
     case T_LVALUE:
         to->u.lvalue = from;
         break;
+
+#ifdef USE_BIGINT
+    case T_BIGINT:
+	mpz_init_set(to->u.bigint.number, from->u.bigint.number);
+	break;
+#endif
+
     }
 
     /* Protection against endless reference loops */
@@ -1694,6 +1731,12 @@
          * Note that 'dest' in some cases points to a protector structure.
          */
 
+#ifdef USE_BIGINT
+	case T_BIGINT:
+	    mpz_clear(dest->u.bigint.number);
+	    break;
+#endif
+
         case T_CHAR_LVALUE:
             if (v->type == T_NUMBER)
                 *dest->u.charp = (char)v->u.number;
@@ -1855,6 +1898,12 @@
             free_mapping(dest->u.map);
             break;
 
+#ifdef USE_BIGINT
+	case T_BIGINT:
+	    mpz_clear(dest->u.bigint.number);
+	    break;
+#endif
+
         /* If the final svalue in dest is one of these lvalues,
          * the assignment is done right here and now.
          * Note that 'dest' in some cases points to a protector structure.
@@ -2332,6 +2381,8 @@
 static void
 add_number_to_lvalue (svalue_t *dest, int i, svalue_t *pre, svalue_t *post)
 
+// GAWAIN ??
+
 /* Add the number <i> to the (PROTECTED_)LVALUE <dest>.
  * If <pre> is not null, the <dest> value before the addition is copied
  * into it.
@@ -7808,6 +7859,16 @@
         break;
     }
 
+    CASE(F_BIGINT);
+    {
+	/* Push the bigint <number> onto the stack. */
+	sp++;
+	sp->type = T_BIGINT;
+	memcpy(&sp->u.bigint, pc, sizeof(bigint_t));
+	pc += sizeof(bigint_t);
+	break;
+    }
+
     CASE(F_CONST0);                 /* --- const0              --- */
         /* Push the number 0 onto the stack.
          */
@@ -9415,9 +9476,38 @@
                 put_string(sp, res);
                 break;
               }
+#ifdef USE_BIGINT
+            case T_BIGINT:
+              {
+                string_t *left, *res;
+                char *buff;
+                size_t len;
 
+                left = (sp-1)->u.str;
+		buff = mpz_get_str(0, 10, sp->u.bigint.number);
+                if (!buff)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) mpz_sizeinbase(sp->u.bigint.number, 10)
+                           ));
+                len = mstrsize(left)+strlen(buff);
+                DYN_STRING_COST(len)
+                res = mstr_add_txt(left, buff, strlen(buff));
+		free(buff);
+                if (!res)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) len
+                           ));
+                pop_n_elems(2);
+                push_string(sp, res);
+                break;
+              }
+#endif
             default:
-                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER, sp->type);
+                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER
+#ifdef USE_BIGINT
+		|TF_BIGINT
+#endif
+		, sp->type);
                 /* NOTREACHED */
             }
             break;
@@ -9487,8 +9577,26 @@
                 break;
               }
 
+#ifdef USE_BIGINT
+            case T_BIGINT:
+	      {
+	        bigint_t tmp;
+		mpz_init(tmp.number);
+		mpz_add_ui(tmp.number, sp->u.bigint.number, (unsigned long)(sp-1)->u.number);
+		mpz_clear(sp->u.bigint.number);
+		sp--;
+		mpz_init_set(sp->u.bigint.number, tmp.number);
+		sp->type = T_BIGINT;
+	        break;
+	      }
+#endif
+
             default:
-                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER, sp->type);
+                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER
+#ifdef USE_BIGINT
+                |TF_BIGINT
+#endif
+		, sp->type);
                 /* NOTREACHED */
             }
             break;
@@ -9584,9 +9692,71 @@
             }
             break;
           }
+#ifdef USE_BIGINT
+	case T_BIGINT:
+	  switch(sp->type) {
+	    case T_STRING:
+	      {
+                char *buff;
+                string_t *right, *res;
+                size_t len;
 
+                right = sp->u.str;
+                buff = mpz_get_str(0, 10, (sp-1)->u.bigint.number);
+                if (!buff)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) mpz_sizeinbase((sp-1)->u.bigint.number, 10)
+                           ));
+                len = mstrsize(right)+strlen(buff);
+                DYN_STRING_COST(len)
+                res = mstr_add_to_txt(buff, strlen(buff), right);
+		free(buff);
+                if (!res)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) len
+                           ));
+                free_string_svalue(sp);
+                sp--;
+                /* Overwrite the number at sp */
+                put_string(sp, res);
+                break;
+	      }
+	      
+	    case T_NUMBER:
+	      {
+	        bigint_t tmp;
+		mpz_init(tmp.number);
+		mpz_add_ui(tmp.number, (sp-1)->u.bigint.number, (unsigned long)sp->u.number);
+		sp--;
+		mpz_set(sp->u.bigint.number, tmp.number);
+		mpz_clear(tmp.number);
+	        break;
+	      }
+
+	    case T_BIGINT:
+	      {
+	        bigint_t tmp;
+		mpz_init(tmp.number);
+		mpz_add(tmp.number, (sp-1)->u.bigint.number, sp->u.bigint.number);
+		mpz_clear(sp->u.bigint.number);
+		sp--;
+		mpz_set(sp->u.bigint.number, tmp.number);
+		mpz_clear(tmp.number);
+	        break;
+	      }
+
+	    default:
+        	OP_ARG_ERROR(2, TF_STRING|TF_NUMBER|TF_BIGINT, sp->type);
+        	/* NOTREACHED */
+	    }
+	    break;
+	    /* End of case T_BIGINT */
+#endif
         default:
             OP_ARG_ERROR(1, TF_POINTER|TF_MAPPING|TF_STRING|TF_FLOAT|TF_NUMBER
+#ifdef USE_BIGINT
+			    |TF_BIGINT
+#endif
                           , sp[-1].type);
             /* NOTREACHED */
         }
@@ -11047,6 +11217,28 @@
                            ));
                 sp -= 2;
             }
+#ifdef USE_BIGINT
+            else if (type2 == T_BIGINT)
+            {
+                char *buff;
+                size_t len;
+
+		buff = mpz_get_str(0, 10, u.bigint.number);
+                if (!buff)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) mpz_sizeinbase(u.bigint.number)
+                           ));
+                len = mstrsize(argp->u.str)+strlen(buff);
+                DYN_STRING_COST(len)
+                new_string = mstr_add_txt(argp->u.str, buff, strlen(buff));
+		free(buff);
+                if (!new_string)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) len
+                           ));
+                sp -= 2;
+            }
+#endif
             else if (type2 == T_FLOAT)
             {
                 char buff[160];
@@ -11065,7 +11257,11 @@
             }
             else
             {
-                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER, type2);
+                OP_ARG_ERROR(2, TF_STRING|TF_FLOAT|TF_NUMBER
+#ifdef USE_BIGINT
+		|TF_BIGINT
+#endif
+		, type2);
                 /* NOTREACHED */
             }
 
@@ -11163,6 +11359,66 @@
             }
             break;
 
+#ifdef USE_BIGINT
+	case T_BIGINT: /* Add to a bigint */
+	  switch(type2) {
+	    case T_STRING:
+	      {
+                char *buff;
+                string_t *right, *res;
+                size_t len;
+// GAWAIN
+                right = sp->u.str;
+                buff = mpz_get_str(0, 10, (sp-1)->u.bigint.number);
+                if (!buff)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) mpz_sizeinbase((sp-1)->u.bigint.number, 10)
+                           ));
+                len = mstrsize(right)+strlen(buff);
+                DYN_STRING_COST(len)
+                res = mstr_add_to_txt(buff, strlen(buff), right);
+		free(buff);
+                if (!res)
+                    ERRORF(("Out of memory (%lu bytes)\n"
+                           , (unsigned long) len
+                           ));
+                free_string_svalue(sp);
+                sp--;
+                /* Overwrite the number at sp */
+                put_string(sp, res);
+                break;
+	      }
+	      
+	    case T_NUMBER:
+	      {
+	        bigint_t tmp;
+		mpz_init(tmp.number);
+		mpz_add_ui(tmp.number, (sp-1)->u.bigint.number, (unsigned long)sp->u.number);
+		sp--;
+		mpz_set(sp->u.bigint.number, tmp.number);
+		mpz_clear(tmp.number);
+	        break;
+	      }
+
+	    case T_BIGINT:
+	      {
+	        bigint_t tmp;
+		mpz_init(tmp.number);
+		mpz_add(tmp.number, (sp-1)->u.bigint.number, sp->u.bigint.number);
+		mpz_clear(sp->u.bigint.number);
+		sp--;
+		mpz_set(sp->u.bigint.number, tmp.number);
+		mpz_clear(tmp.number);
+	        break;
+	      }
+
+	    default:
+        	OP_ARG_ERROR(2, TF_STRING|TF_NUMBER|TF_BIGINT, sp->type);
+        	/* NOTREACHED */
+	    }
+	    break;
+	    /* End of case T_BIGINT */
+#endif
         case T_CHAR_LVALUE:  /* Add to a character in a string */
             if (type2 == T_NUMBER)
             {
@@ -15334,7 +15590,7 @@
     CASE(F_NEGATE);                 /* --- negate              --- */
         /* EFUN negate()
          *
-         *   int|float negate(int|float arg)
+         *   int|bigint|float negate(int|float arg)
          *
          * Negate the value <arg> and leave it on the stack.
          * Calls to this efun are mainly generated by the compiler when
@@ -15359,6 +15615,13 @@
             STORE_DOUBLE(sp,d);
             break;
         }
+#ifdef USE_BIGINT
+	else if (sp->type == T_BIGINT)
+	{
+	    mpz_neg(sp->u.bigint.number, sp->u.bigint.number);
+	    break;
+	}
+#endif
         ERRORF(("Bad arg to unary minus: got %s, expected number/float\n"
                , typename(sp->type)
                ));
diff -Naur 3-3/src/lex.c 3-3-gawain/src/lex.c
--- 3-3/src/lex.c	2003-08-08 19:53:47.000000000 +0200
+++ 3-3-gawain/src/lex.c	2003-08-15 15:12:35.000000000 +0200
@@ -39,6 +39,7 @@
 
 #include "array.h"
 #include "backend.h"
+#include "bigint.h"
 #include "closure.h"
 #include "comm.h"
 #include "exec.h"
@@ -461,6 +462,9 @@
 #endif
    , { "inherit",        L_INHERIT       }
    , { "int",            L_INT           }
+#ifdef USE_BIGINT
+   , { "bigint",         L_BIGINT_DECL   }
+#endif
    , { "mapping",        L_MAPPING       }
    , { "mixed",          L_MIXED         }
    , { "nomask",         L_NO_MASK       }
@@ -3625,7 +3629,7 @@
 
     /* Parse a normal number from here */
 
-    l = c - '0';
+    l = c - '0'; 
     while (lexdigit(c = *cp++) && c < '0'+base) l = l * base + (c - '0');
 
     *p_num = l;
@@ -5347,6 +5351,21 @@
                 return L_FLOAT;
             }
 
+	    /* This constant is an bigint */
+	    if ('L' == c) {
+		p_int len = yyp-numstart-1; // should be -2 but +1 for \0 makes -1
+		// to save the number make a \0 terminated string
+		char *tmp = malloc(len);
+		strncpy(tmp, numstart, len);
+		tmp[len] = 0;
+
+		// convert the string into a mpz_t
+		mpz_init_set_str(yylval.bigint.number, tmp, 0);
+
+		outp = yyp;
+		return L_BIGINT;
+	    }
+
             /* Nope, normal number */
             yyp = parse_number(numstart, &l);
 
diff -Naur 3-3/src/prolang.y 3-3-gawain/src/prolang.y
--- 3-3/src/prolang.y	2003-07-29 07:05:42.000000000 +0200
+++ 3-3-gawain/src/prolang.y	2003-08-19 12:26:21.000000000 +0200
@@ -93,6 +93,9 @@
 
 #include "array.h"
 #include "backend.h"
+#ifdef USE_BIGINT
+#include "bigint.h"
+#endif
 #include "closure.h"
 #include "exec.h"
 #include "gcollect.h"
@@ -948,6 +951,7 @@
 static const fulltype_t Type_Unknown = { TYPE_UNKNOWN, NULL };
 static const vartype_t  VType_Unknown = { TYPE_UNKNOWN, NULL };
 static const fulltype_t Type_Number  = { TYPE_NUMBER, NULL };
+static const fulltype_t Type_Bigint  = { TYPE_BIGINT, NULL };
 static const fulltype_t Type_Float   = { TYPE_FLOAT, NULL };
 static const fulltype_t Type_String  = { TYPE_STRING, NULL };
 static const fulltype_t Type_Object  = { TYPE_OBJECT, NULL };
@@ -964,6 +968,7 @@
 static const fulltype_t Type_Unknown = { TYPE_UNKNOWN };
 static const vartype_t  VType_Unknown = { TYPE_UNKNOWN };
 static const fulltype_t Type_Number  = { TYPE_NUMBER };
+static const fulltype_t Type_Bigint  = { TYPE_BIGINT };
 static const fulltype_t Type_Float   = { TYPE_FLOAT };
 static const fulltype_t Type_String  = { TYPE_STRING };
 static const fulltype_t Type_Object  = { TYPE_OBJECT };
@@ -1476,7 +1481,7 @@
     static char buff[100];
     static char *type_name[] = { "unknown", "int", "string", "void", "object",
                                  "mapping", "float", "mixed", "closure",
-                                 "symbol", "quoted_array", "struct" };
+                                 "symbol", "quoted_array", "struct", "bigint" };
 
     Bool pointer = MY_FALSE, reference = MY_FALSE;
 
@@ -1628,6 +1633,7 @@
 {
     t1.typeflags &= TYPEID_MASK;
     t2.typeflags &= TYPEID_MASK;
+
     if (t1.typeflags == TYPE_UNKNOWN || t2.typeflags == TYPE_UNKNOWN)
         return MY_FALSE;
     if (t1.typeflags == TYPE_ANY || t2.typeflags == TYPE_ANY)
@@ -5035,6 +5041,10 @@
 
 %token L_ASSIGN
 %token L_ARROW
+%ifdef USE_BIGINT
+%token L_BIGINT
+%token L_BIGINT_DECL
+%endif
 %token L_BREAK
 %token L_CASE
 %token L_CATCH
@@ -5128,6 +5138,11 @@
     double float_number;
       /* Literal floats */
 
+%ifdef USE_BIGINT
+    bigint_t bigint; 
+      /* a bigint value */
+%endif
+
     struct {
         p_int number;
     } closure;
@@ -5300,6 +5315,9 @@
 /*-------------------------------------------------------------------------*/
 
 %type <number>       L_NUMBER constant
+%ifdef USE_BIGINT
+%type <bigint>       L_BIGINT
+%endif
 %type <float_number> L_FLOAT
 %type <closure>      L_CLOSURE
 %type <symbol>       L_SYMBOL
@@ -6270,8 +6288,11 @@
 
 
 basic_non_void_type:
-      L_STATUS       { $$ = Type_Number; current_type = $$; }
+      L_STATUS       { $$ = Type_Number;  current_type = $$; }
     | L_INT          { $$ = Type_Number;  current_type = $$; }
+%ifdef USE_BIGINT
+    | L_BIGINT_DECL  { $$ = Type_Bigint;  current_type = $$; }
+%endif
     | L_STRING_DECL  { $$ = Type_String;  current_type = $$; }
     | L_OBJECT       { $$ = Type_Object;  current_type = $$; }
     | L_CLOSURE_DECL { $$ = Type_Closure; current_type = $$; }
@@ -9014,7 +9035,11 @@
                   $$.type = $1.type;
               else if ($1.type.typeflags == TYPE_STRING)
                   $$.type = Type_String;
-              else if (($1.type.typeflags == TYPE_NUMBER || $1.type.typeflags == TYPE_FLOAT)
+              else if (($1.type.typeflags == TYPE_NUMBER || $1.type.typeflags == TYPE_FLOAT 
+#ifdef USE_BIGINT
+	    	     || $1.type.typeflags == TYPE_BIGINT
+#endif
+		     )
                      && $4.type.typeflags == TYPE_STRING)
                   $$.type = Type_String;
               else if ($1.type.typeflags == TYPE_FLOAT
@@ -9684,7 +9709,11 @@
           type = $2.type;
           if (exact_types.typeflags
            && !BASIC_TYPE(type, Type_Number)
-           && type.typeflags != TYPE_FLOAT )
+           && type.typeflags != TYPE_FLOAT 
+%ifdef USE_BIGINT
+	   && type.typeflags != TYPE_BIGINT
+%endif
+	   )
               type_error("Bad argument to unary '-'", type);
       }
 
@@ -9852,6 +9881,26 @@
       }
 
     /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
+
+    | L_BIGINT
+      {
+          /* Store a bigint */
+
+          p_int current;
+          PREPARE_INSERT(1 + sizeof (bigint_t))
+
+          $$.start = last_expression = current = CURRENT_PROGRAM_SIZE;
+          $$.code = -1;
+
+          add_f_code(F_BIGINT);
+          memcpy(__PREPARE_INSERT__p, &$1.number, sizeof ($1.number));
+          current += 1 + sizeof (bigint_t);
+          $$.type = Type_Bigint;
+
+          CURRENT_PROGRAM_SIZE = current;
+      }
+
+    /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
     | L_CLOSURE
       {
           int ix;
diff -Naur 3-3/src/simulate.c 3-3-gawain/src/simulate.c
--- 3-3/src/simulate.c	2003-08-08 19:53:47.000000000 +0200
+++ 3-3-gawain/src/simulate.c	2003-08-22 09:57:36.000000000 +0200
@@ -4030,6 +4030,17 @@
         add_message("<MAPPING>");
     else if (arg->type == T_CLOSURE)
         add_message("<CLOSURE>");
+#ifdef USE_BIGINT
+    else if (arg->type == T_BIGINT) {
+//	char txt[10000];
+//	mpz_get_str(txt, 10, arg->u.bigint.number);
+	char *txt = mpz_get_str(0, 10, arg->u.bigint.number);
+	if(txt) {
+	    add_message(txt);
+	    free(txt);
+	}
+    }
+#endif
     else
         add_message("<OTHER:%d>", arg->type);
 } /* print_svalue() */
diff -Naur 3-3/src/svalue.h 3-3-gawain/src/svalue.h
--- 3-3/src/svalue.h	2003-01-27 05:27:52.000000000 +0100
+++ 3-3-gawain/src/svalue.h	2003-08-15 22:07:05.000000000 +0200
@@ -11,7 +11,7 @@
 
 #include "driver.h"
 #include "typedefs.h"
-
+#include "bigint.h"
 /* --- Types --- */
 
 /* --- union u: the hold-all type ---
@@ -37,6 +37,12 @@
     p_int number;
       /* T_NUMBER: the number.
        */
+
+#ifdef USE_BIGINT
+    bigint_t bigint;
+      /* T_BIGINT: the gmp representation of a bigint
+       */
+#endif
     object_t *ob;
       /* T_OBJECT: pointer to the object structure.
        * T_CLOSURE: efun-, simul_efun-, operator closures: the object
@@ -181,38 +187,39 @@
 #ifdef USE_STRUCTS
 #define T_STRUCT        0xb  /* a struct */
 #endif /* USE_STRUCTS */
+#define T_BIGINT        0xc  /* a bigint */
 
-#define T_CHAR_LVALUE                     0xc
+#define T_CHAR_LVALUE                     0xd
   /* .u.string points to the referenced character in a string */
 
   /* The following types must be used only in svalues referenced
    * by a T_LVALUE svalue.
    */
-#define T_STRING_RANGE_LVALUE             0x0d /* TODO: ??? */
-#define T_POINTER_RANGE_LVALUE            0x0e /* TODO: ??? */
-#define T_PROTECTED_CHAR_LVALUE           0x0f
+#define T_STRING_RANGE_LVALUE             0x0e /* TODO: ??? */
+#define T_POINTER_RANGE_LVALUE            0x0f /* TODO: ??? */
+#define T_PROTECTED_CHAR_LVALUE           0x10
   /* A protected character lvalue */
-#define T_PROTECTED_STRING_RANGE_LVALUE   0x10
+#define T_PROTECTED_STRING_RANGE_LVALUE   0x11
   /* A protected string range lvalue */
-#define T_PROTECTED_POINTER_RANGE_LVALUE  0x11
+#define T_PROTECTED_POINTER_RANGE_LVALUE  0x12
   /* A protected pointer/mapping range lvalue */
-#define T_PROTECTED_LVALUE                0x12
+#define T_PROTECTED_LVALUE                0x13
   /* A protected lvalue */
-#define T_PROTECTOR_MAPPING               0x13 /* TODO: ??? */
+#define T_PROTECTOR_MAPPING               0x14 /* TODO: ??? */
 
-#define T_CALLBACK                        0x14
+#define T_CALLBACK                        0x15
   /* A callback structure referenced from the stack to allow
    * proper cleanup during error recoveries. The interpreter
    * knows how to free it, but that's all.
    */
 
-#define T_ERROR_HANDLER                   0x15
+#define T_ERROR_HANDLER                   0x16
   /* Not an actual value, this is used internally for cleanup
    * operations. See the description of the error_handler() member
    * for details.
    */
 
-#define T_NULL                            0x16
+#define T_NULL                            0x17
   /* Not an actual type, this is used in the efun_lpc_types[] table
    * to encode the acceptance of '0' instead of the real datatype.
    */
@@ -316,6 +323,7 @@
 #ifdef USE_STRUCTS
 #define TF_STRUCT        (1 << T_STRUCT)
 #endif /* USE_STRUCTS */
+#define TF_BIGINT        (1 << T_BIGINT)
 
 #define TF_ANYTYPE       (~0)
   /* This is used in the efun_lpc_types[]
diff -Naur 3-3/src/typedefs.h 3-3-gawain/src/typedefs.h
--- 3-3/src/typedefs.h	2003-01-03 01:33:15.000000000 +0100
+++ 3-3-gawain/src/typedefs.h	2003-08-15 09:25:30.000000000 +0200
@@ -47,5 +47,8 @@
 typedef struct variable_s         variable_t;         /* exec.h */
 typedef struct vector_s           vector_t;           /* array.h */
 typedef struct wiz_list_s         wiz_list_t;         /* wiz_list.h */
+#ifdef USE_BIGINT
+typedef struct bigint_s           bigint_t;           /* bigint.h */
+#endif
 
 #endif /* TYPEDEFS_H__ */
bigint.diff (26,199 bytes)   
bigint_test.c (704 bytes)   
#pragma strict_types

bigint i = 4000L;
bigint j;

void create() {
    j = 3999L;

    // Zuweisungen
    write(i); write("; 4000\n");
    write(j); write("; 3999\n");

    // Additionen
    write(i+j); write("; 7999\n");

    write(i+10); write("; 4010\n");
    write(10+i); write("; 4010\n");

    write(i+"teststring"); write("; 4000teststring\n");
    write("teststring"+i); write("; teststring4000\n");

    i += j; write(i); write("; 7999\n");

    // Subtraktionen
    i -= j; write(i); write("; 4000\n");
    write(i+(-j)); write(", 1\n");


//	write("test"*2L); write("; testtest\n");

}
/* DONE:
=
+
*/

/* TODO:
+ (int,string,bigint)
*
%
/
-
&
|
^
~
sin()
cos()
tan()
bigintp()
to_bigint()
*/
bigint_test.c (704 bytes)   

Relationships

related to 0000195 feedback LDMud New datatype 'long' 

Activities

Gawain

2005-01-06 16:48

reporter   ~0000289

this is a small object to test compilation and functionality.

zesstra

2009-01-08 05:41

administrator   ~0000861

I would suggest to postpone this to 3.5 and do some cleanup of the type stuff before (non-optional structs) to limit the number of #ifdefs there.

Issue History

Date Modified Username Field Change
2005-01-06 16:45 Gawain New Issue
2005-01-06 16:45 Gawain File Added: bigint.diff
2005-01-06 16:48 Gawain Note Added: 0000289
2005-01-06 16:49 Gawain File Added: bigint_test.c
2009-01-08 05:37 zesstra Project LDMud 3.3 => LDMud 3.5
2009-01-08 05:41 zesstra Note Added: 0000861
2009-09-30 16:11 zesstra Relationship added related to 0000195