rev 613 - trunk/src

SVN User <[email protected]> Sat, 12 Jun 2004 19:25:42 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-12 19:25:39 -0400 (Sat, 12 Jun 2004)
New Revision: 613

Modified:
   trunk/src/builtins-int.c
   trunk/src/builtins-string.c
   trunk/src/interp.c
   trunk/src/object.h
Log:
int.str_(spec) half-implemented

Modified: trunk/src/builtins-int.c
===================================================================
--- trunk/src/builtins-int.c	2004-06-12 21:39:00 UTC (rev 612)
+++ trunk/src/builtins-int.c	2004-06-12 23:25:39 UTC (rev 613)
@@ -122,7 +122,7 @@
 static long_p mul1(long_p, wdigit);
 static long_p muladd1(long_p, wdigit, wdigit);
 static long_p divrem1(long_p, digit, digit *);
-obj_p  long_format(long_p aa, int base, int addL);
+obj_p  long_format(long_p aa, int base, int uppercase);
 
 /* Long integer representation.
   The absolute value of a number is equal to
@@ -575,15 +575,20 @@
 /* Convert a long int object to a string, using a given conversion base.
   Return a string object.
   If base is 8 or 16, add the proper prefix '0' or '0x'. */
-obj_p long_format(long_p aa, int base, int addL) {
+obj_p long_format(long_p aa, int base, int uppercase) {
 	register long_p a = (long_p) aa;
 	obj_p str;
 	int i;
 	const int size_a = abs(a->dsize);
-	char *p, *strp;
+	char base_a, *p, *strp;
 	int bits;
 	char sign = '\0';
 
+	if (uppercase) 
+		base_a = 'A';
+	else 
+		base_a = 'a';
+
 	pr_assert(base >= 2 && base <= 36);
 
 	/* Compute a rough upper bound for the length of the string */
@@ -593,12 +598,10 @@
 		++bits;
 		i >>= 1;
 	}
-	i = 5 + (addL ? 1 : 0) + (size_a*SHIFT + bits-1) / bits;
+	i = 5 + (size_a*SHIFT + bits-1) / bits;
 	strp = pr_malloc(i+1);
 	strp[i] = 0;
 	p = strp + i;
-    if (addL)
-        *--p = 'L';
 	if (a->dsize < 0)
 		sign = '-';
 
@@ -620,7 +623,7 @@
 			pr_assert(accumbits >= basebits);
 			do {
 				char cdigit = (char)(accum & (base - 1));
-				cdigit += (cdigit < 10) ? '0' : 'A'-10;
+				cdigit += (cdigit < 10) ? '0' : base_a-10;
 				pr_assert(p > strp);
 				*--p = cdigit;
 				accumbits -= basebits;
@@ -674,7 +677,7 @@
 				digit nextrem = (digit)(rem / base);
 				char c = (char)(rem - nextrem * base);
 				pr_assert(p > strp);
-				c += (c < 10) ? '0' : 'A'-10;
+				c += (c < 10) ? '0' : base_a-10;
 				*--p = c;
 				rem = nextrem;
 				--ntostore;
@@ -686,7 +689,7 @@
 		pr_free(scratch);
 	}
 
-	if (base == 8) {
+/*	if (base == 8) {
 		if (size_a != 0)
 			*--p = '0';
 	}
@@ -699,7 +702,7 @@
 		*--p = '0' + base%10;
 		if (base > 10)
 			*--p = '0' + base/10;
-	}
+	} */
 	if (sign)
 		*--p = sign;
 	if (p != strp) {
@@ -2048,6 +2051,21 @@
 		return longp2int64(ist, self->data.ptr);
 }
 
+obj_p chr_ch3(isp ist, obj_p self) {
+	ch3_t ch3;
+	i32_t val;
+	val = int2i32t(ist, self);
+	if (val < 0 || val >= 0x10ffff) {
+		raise_exception( ist, OBJ(VALUE_EXC), 
+			             "integer value outside of unicode character range" );
+		return NULL;
+	}
+	ch3.b0 = val       & 0xff;
+	ch3.b1 = val >>  8 & 0xff;
+	ch3.b2 = val >> 16 & 0xff;
+	return NEW_STRING_CH3(&ch3, 1);
+}
+
 // ***************************** INT MODULE ***********************************
 
 #define	INT_DATA_SIZE		8
@@ -2097,15 +2115,73 @@
 	return OBJ(NONE);
 }
 
-DEF(Int, str_, NULL){
-	char str[24];
+DEF(Int, str_, FPARM1(spec, NEW_STRING(""))) {
+	obj_p self_str;
+	char *spec, *wid_p = NULL, *prec_p = NULL, *p;
+	int left_align = FALSE;
+	int num_flag   = FALSE;
+	int blnk_flag  = FALSE;
+	int sign_flag  = FALSE;
+	int chr_flag   = FALSE;
+	int oct_flag   = FALSE;
+	int hex_flag   = FALSE;
+	int heX_flag   = FALSE;
+	int self_len;
+	ch3_p self_ptr;
 	BIN_STR_CHK(Int);
-	if (self->data_type == DATA_TYPE_IMMDATA) {
-		apr_snprintf(str, sizeof(str), "%"APR_INT64_T_FMT, (i64_t)int_imm_value(self));
-		return NEW_STRING(str);
+	STRING_PARAM(1, spec);
+	for(p=spec; *p; p++) {
+		if      (!wid_p && !prec_p && *p == '-') left_align = TRUE;
+		else if (!wid_p && !prec_p && *p == '#')   num_flag = TRUE;
+		else if (!wid_p && !prec_p && *p == ' ')  blnk_flag = TRUE;
+		else if (!wid_p && !prec_p && *p == '+')  sign_flag = TRUE;
+		else if (!wid_p && !prec_p && *p > '0' && *p <= '9') wid_p = p;
+		else if (!prec_p && *p == '.') { prec_p = p+1; *p = 0; }
+		else if ( *p == 'd' || *p == 'D' || *p == 'i' || *p == 'I' || 
+			      *p == 'c' || *p == 'C' || *p == 'o' || *p == 'O' || 
+				  *p == 'x' || *p == 'X' ) {
+			if (*(p+1) != 0) {
+				raise_exception( ist, OBJ(TYPE_EXC), 
+					             "extra char(s) found at end of fmt spec: \"%s\"", spec );
+				return NULL;
+			}
+			if (*p == 'c' || *p == 'C') chr_flag = TRUE;
+			if (*p == 'o' || *p == 'O') oct_flag = TRUE;
+			if (*p == 'x') hex_flag = TRUE;	
+			if (*p == 'X') heX_flag = TRUE;
+			*p = 0; 
+			break; 
+		} else if (*p < '0' || *p > '9') {
+			raise_exception( ist, OBJ(VALUE_EXC), 
+				             "invalid fmt spec in str_ parameter: \"%s\"", spec );
+			return NULL;
+		}
+	}
+	if (chr_flag) {
+		self_str = chr_ch3(ist, self);
+	} else if (self->data_type == DATA_TYPE_IMMDATA) {
+		char str[32], *p, *pend;
+		i64_t val = int2i64t(ist, self);
+		int neg_flag = (val < 0);
+		str[0] = '-';
+		if (neg_flag) val = -val;
+		if (hex_flag || heX_flag)
+			apr_snprintf(str+1, sizeof(str)-1, "%"APR_UINT64_T_HEX_FMT, val);
+		else
+			apr_snprintf(str+1, sizeof(str)-1, "%"APR_INT64_T_FMT, val);
+		if (heX_flag) {
+			pend = str + strlen(str);
+			for (p=str; *p; p++)
+				*p = toupper(*p);
+		}
+		self_str = NEW_STRING(neg_flag ? str : str+1);
 	} else {
-		return long_format(self->data.ptr, 10, FALSE);
+		int base = ((hex_flag|heX_flag) ? 16 : (oct_flag ? 8 : 10));
+		self_str = long_format(self->data.ptr, base, heX_flag);
 	}
+	self_ptr = pr_ch3ptr(self_str);
+	self_len = pr_strlen(self_str);
+	return self_str;
 }
 
 DEF(Int, bool__QUES, NULL) {
@@ -2564,22 +2640,10 @@
 }
 
 DEF(Int, chr_, NULL) {
-	ch3_t ch3;
-	i32_t val;
 	BIN_CONTENT_CHK(Int);
-	val = int2i32t(ist, self);
-	if (val < 0 || val >= 0x10ffff) {
-		raise_exception( ist, OBJ(VALUE_EXC), 
-			             "integer value outside of unicode character range" );
-		return NULL;
-	}
-	ch3.b0 = val       & 0xff;
-	ch3.b1 = val >>  8 & 0xff;
-	ch3.b2 = val >> 16 & 0xff;
-	return NEW_STRING_CH3(&ch3, 1);
+	return chr_ch3(ist, self);
 }
 
-
 MODULE_START(IntGen)
 {
 	IntGen_OBJ = NEW_OBJ(OBJ(INT_PROTO));

Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-06-12 21:39:00 UTC (rev 612)
+++ trunk/src/builtins-string.c	2004-06-12 23:25:39 UTC (rev 613)
@@ -428,7 +428,7 @@
 			*p = 0; 
 			break; 
 		} else if (*p < '0' || *p > '9') {
-			raise_exception(ist, OBJ(VALUE_EXC), "ivalid fmt spec in str_ parameter: \"%s\"", spec);
+			raise_exception(ist, OBJ(VALUE_EXC), "invalid fmt spec in str_ parameter: \"%s\"", spec);
 			return NULL;
 		}
 	}

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-06-12 21:39:00 UTC (rev 612)
+++ trunk/src/interp.c	2004-06-12 23:25:39 UTC (rev 613)
@@ -879,8 +879,6 @@
 			printf("Internal fatal error: frame stack overflow\n");
 			pr_exit(1);
 		}
-		if (fr_pc == 133)
-			op = op;
 		switch (op) {
 			case OP_NOP: 
 				break;

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-12 21:39:00 UTC (rev 612)
+++ trunk/src/object.h	2004-06-12 23:25:39 UTC (rev 613)
@@ -145,7 +145,7 @@
 obj_p new_int_obj(isp ist, i64_t num);
 obj_p new_int_long_obj(isp ist, long_p longp);
 long_p cstr2longp(isp ist, char *str, char **pend, int base);
-obj_p long_format(long_p aa, int base, int addL);\
+obj_p long_format(long_p aa, int base, int uppercase);
 long_p new_longp(i64_t ival);
 int int_is_zero(obj_p obj);
 u8_t* bytes_ptr(obj_p obj);