瀏覽代碼

Merge pull request #101 from bmx-ng/brl_enum

Added Enum implementation.
Brucey 6 年之前
父節點
當前提交
6972f5f425

+ 16 - 0
appstub.mod/debugger.stdio.glue.c

@@ -115,6 +115,22 @@ void bmx_debugger_DebugDecl_ArrayDeclFree(struct BBDebugDecl * decl) {
 	free(decl);
 }
 
+BBString * bmx_debugger_DebugEnumDeclValue(struct BBDebugDecl * decl, void * val) {
+	BBEnum * bbEnum = bbEnumGetInfo(decl->type_tag);
+
+	switch( bbEnum->type[0] ){
+		case 'b': return bbEnumToString_b(bbEnum, *((BBBYTE*)val));
+		case 's': return bbEnumToString_s(bbEnum, *((BBSHORT*)val));
+		case 'i': return bbEnumToString_i(bbEnum, *((BBINT*)val));
+		case 'u': return bbEnumToString_u(bbEnum, *((BBUINT*)val));
+		case 'l': return bbEnumToString_l(bbEnum, *((BBLONG*)val));
+		case 'y': return bbEnumToString_y(bbEnum, *((BBULONG*)val));
+		case 't': return bbEnumToString_t(bbEnum, *((BBSIZET*)val));
+	}
+
+	return &bbEmptyString;
+}
+
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 BBString * bmx_debugger_DebugStmFile(struct BBDebugStm * stmt) {

+ 4 - 1
appstub.mod/debugger_mt.stdio.bmx

@@ -76,6 +76,7 @@ Extern
 	Function bmx_debugger_ref_brl_blitz_NullFunctionError:Byte Ptr()
 	
 	Function bbObjectStructInfo:Byte Ptr(name:Byte Ptr)="BBDebugScope * bbObjectStructInfo( char * )!"
+	Function bmx_debugger_DebugEnumDeclValue:String(decl:Byte Ptr, val:Byte Ptr)
 End Extern
 
 ?Not ptr64
@@ -172,7 +173,7 @@ Function TypeName$( tag$ Var )
 		Return "WParam"
 	Case "X"
 		Return "LParam"
-	Case ":","?","#","@"
+	Case ":","?","#","@","/"
 		Local id$=Ident( tag )
 		While tag And tag[0]=Asc(".")
 			tag=tag[1..]
@@ -401,6 +402,8 @@ Function DebugDeclValue$( decl:Int Ptr,inst:Byte Ptr )
 		Return Float Ptr (Varptr p)[0] + "," + Float Ptr (Varptr p)[1] + "," + Float Ptr (Varptr p)[2] + "," + Float Ptr (Varptr p)[3]
 	Case Asc("m")
 		Return Double Ptr(Varptr p)[0] + "," + Double Ptr (Varptr p)[1]
+	Case Asc("/")
+		Return bmx_debugger_DebugEnumDeclValue(decl, p)
 	Default
 		DebugError "Invalid decl typetag:"+Chr(tag)
 	End Select

+ 11 - 0
blitz.mod/blitz.bmx

@@ -94,6 +94,7 @@ Import "blitz_thread.c"
 Import "blitz_ex.c"
 Import "blitz_gc.c"
 Import "blitz_unicode.c"
+Import "blitz_enum.c"
 
 '?Threaded
 'Import "blitz_gc_ms.c"
@@ -871,6 +872,16 @@ bbdoc: End a user defined structure declaration
 keyword: "EndStruct"
 End Rem
 
+Rem
+bbdoc: Begin an enumeration declaration
+keyword: "Enum"
+End Rem
+
+Rem
+bbdoc: End an enumeration declaration
+keyword: "EndEnum"
+End Rem
+
 Rem
 bbdoc: Specify supertype(s) of a user defined type
 keyword: "Extends"

+ 1 - 0
blitz.mod/blitz.h

@@ -38,6 +38,7 @@
 #include "blitz_array.h"
 #include "blitz_handle.h"
 #include "blitz_app.h" 
+#include "blitz_enum.h"
 
 #ifdef __cplusplus
 extern "C"{

+ 1 - 0
blitz.mod/blitz_array.c

@@ -92,6 +92,7 @@ static int arrayCellSize(const char * type, unsigned short data_size, int * flag
 		case 'm':size=sizeof(BBDOUBLE128);break;
 		#endif
 		case '@':size=data_size;*flags=0;break; // structs
+		case '/':size=data_size;*flags=0;break; // enums
 	}
 
 	return size;

+ 1 - 0
blitz.mod/blitz_debug.h

@@ -46,6 +46,7 @@ enum{
 	BBDEBUGSCOPE_LOCALBLOCK=3,
 	BBDEBUGSCOPE_USERINTERFACE=4,
 	BBDEBUGSCOPE_USERSTRUCT=5,
+	BBDEBUGSCOPE_USERENUM=6,
 };
 
 struct BBDebugScope{

+ 112 - 0
blitz.mod/blitz_enum.c

@@ -0,0 +1,112 @@
+
+#include "blitz.h"
+
+
+
+BBArray * bbEnumValues(BBEnum * bbEnum) {
+	BBArray * values = &bbEmptyArray;
+
+	int size = 4;
+	char t = bbEnum->type[0];
+	switch( t ) {
+		case 'b':size=1;break;
+		case 's':size=2;break;
+		case 'l':size=8;break;
+		case 'y':size=8;break;
+		case 'z':size=sizeof(BBSIZET);break;
+	}
+
+	values = bbArrayNew1DStruct(bbEnum->atype, bbEnum->length, size);
+
+	char * p = BBARRAYDATA(values, 0);
+
+	memcpy(p, bbEnum->values, size * bbEnum->length);
+	
+	return values;
+}
+
+static BBString * bbAppend(BBString * x, BBString * y) {
+	int n = x != &bbEmptyString;
+	int len=x->length+y->length + n;
+    BBString *t=bbStringNew(len);
+    memcpy( t->buf,x->buf,x->length*sizeof(BBChar) );
+	if (n) {
+		t->buf[x->length] = '|';
+	}
+    memcpy( t->buf+x->length+n,y->buf,y->length*sizeof(BBChar) );
+	return t;
+}
+
+#define ENUM_TO_STRING(type,chr)\
+BBString * bbEnumToString_##chr(BBEnum * bbEnum, type ordinal) {\
+	type * value = (type*)bbEnum->values;\
+	int flags = bbEnum->flags;\
+	BBString * val = &bbEmptyString;\
+	for (int i = 0; i < bbEnum->length; i++) {\
+		if (flags) {\
+			type v = *value++;\
+			if (v == ordinal || (v & ordinal && v == (v & ordinal))) {\
+				val = bbAppend(val, bbEnum->names[i]);\
+			}\
+		} else {\
+			if (*value++ == ordinal) {\
+				return bbEnum->names[i];\
+			}\
+		}\
+	}\
+	return val;\
+}
+
+ENUM_TO_STRING(BBBYTE,b)
+ENUM_TO_STRING(BBSHORT,s)
+ENUM_TO_STRING(BBINT,i)
+ENUM_TO_STRING(BBUINT,u)
+ENUM_TO_STRING(BBLONG,l)
+ENUM_TO_STRING(BBULONG,y)
+ENUM_TO_STRING(BBSIZET,t)
+
+struct enum_info_node {
+	struct avl_root link;
+	BBEnum * bbEnum;
+};
+
+static struct avl_root *enum_info_root = 0;
+
+static int enum_info_node_compare(const void *x, const void *y) {
+
+        struct enum_info_node * node_x = (struct enum_info_node *)x;
+        struct enum_info_node * node_y = (struct enum_info_node *)y;
+
+        return strcmp(node_x->bbEnum->atype, node_y->bbEnum->atype);
+}
+
+void bbEnumRegister( BBEnum *p, BBDebugScope *s ) {
+	bbObjectRegisterEnum(s);
+
+	struct enum_info_node * node = (struct enum_info_node *)malloc(sizeof(struct enum_info_node));
+	node->bbEnum = p;
+	
+	struct enum_info_node * old_node = (struct enum_info_node *)avl_map(&node->link, enum_info_node_compare, &enum_info_root);
+	if (&node->link != &old_node->link) {
+		// this object already exists here...
+		// delete the new node, since we don't need it
+		// note : should never happen as enums should only ever be registered once.
+		free(node);
+	}
+}
+
+BBEnum * bbEnumGetInfo( char * name ) {
+	// create something to look up
+	struct enum_info_node node;
+	BBEnum bbEnum;
+	bbEnum.atype = name;
+	node.bbEnum = &bbEnum;
+	
+	struct enum_info_node * found = (struct enum_info_node *)tree_search(&node, enum_info_node_compare, enum_info_root);
+
+	if (found) {
+		return found->bbEnum;
+	}
+	
+	return 0;
+}

+ 37 - 0
blitz.mod/blitz_enum.h

@@ -0,0 +1,37 @@
+
+#ifndef BLITZ_ENUM_H
+#define BLITZ_ENUM_H
+
+#include "blitz_types.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+struct BBEnum {
+	const char * name;
+	char * type; // the numeric type
+	char * atype; // array type
+	int flags; // 1 if a flags enum
+	int length; // number of values
+	void * values;
+	BBString * names[1]; // array of names
+};
+
+BBArray * bbEnumValues(BBEnum * bbEnum);
+BBString * bbEnumToString_b(BBEnum * bbEnum, BBBYTE ordinal);
+BBString * bbEnumToString_s(BBEnum * bbEnum, BBSHORT ordinal);
+BBString * bbEnumToString_i(BBEnum * bbEnum, BBINT ordinal);
+BBString * bbEnumToString_u(BBEnum * bbEnum, BBUINT ordinal);
+BBString * bbEnumToString_l(BBEnum * bbEnum, BBLONG ordinal);
+BBString * bbEnumToString_y(BBEnum * bbEnum, BBULONG ordinal);
+BBString * bbEnumToString_t(BBEnum * bbEnum, BBSIZET ordinal);
+
+void bbEnumRegister(BBEnum * bbEnum, BBDebugScope *p);
+BBEnum * bbEnumGetInfo( char * name );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 38 - 0
blitz.mod/blitz_object.c

@@ -233,3 +233,41 @@ BBObject * bbNullObjectTest( BBObject *o ) {
 	return o;
 }
 
+static struct avl_root *enum_root = 0;
+
+int enum_node_compare(const void *x, const void *y) {
+
+        struct enum_node * node_x = (struct enum_node *)x;
+        struct enum_node * node_y = (struct enum_node *)y;
+
+        return strcmp(node_x->scope->name, node_y->scope->name);
+}
+
+void bbObjectRegisterEnum( BBDebugScope *p ) {
+	struct enum_node * node = (struct enum_node *)malloc(sizeof(struct enum_node));
+	node->scope = p;
+	
+	struct enum_node * old_node = (struct enum_node *)avl_map(&node->link, enum_node_compare, &enum_root);
+	if (&node->link != &old_node->link) {
+		// this object already exists here...
+		// delete the new node, since we don't need it
+		// note : should never happen as structs should only ever be registered once.
+		free(node);
+	}
+}
+
+BBDebugScope * bbObjectEnumInfo( char * name ) {
+	// create something to look up
+	struct enum_node node;
+	BBDebugScope scope;
+	scope.name = name;
+	node.scope = &scope;
+	
+	struct enum_node * found = (struct enum_node *)tree_search(&node, enum_node_compare, enum_root);
+
+	if (found) {
+		return found->scope;
+	}
+	
+	return 0;
+}

+ 8 - 0
blitz.mod/blitz_object.h

@@ -95,6 +95,14 @@ BBDebugScope * bbObjectStructInfo( char * name );
 
 BBObject * bbNullObjectTest( BBObject *o );
 
+struct enum_node {
+	struct avl_root link;
+	BBDebugScope * scope;
+};
+
+void bbObjectRegisterEnum( BBDebugScope *p );
+BBDebugScope * bbObjectEnumInfo( char * name );
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 0
blitz.mod/blitz_types.h

@@ -23,6 +23,7 @@ typedef struct BBArray	BBArray;
 typedef struct BBInterfaceTable BBInterfaceTable;
 typedef struct BBInterface BBInterface;
 typedef struct BBInterfaceOffsets BBInterfaceOffsets;
+typedef struct BBEnum BBEnum;
 
 typedef unsigned char	BBBYTE;
 typedef unsigned short	BBSHORT;
@@ -62,6 +63,7 @@ extern const char *bbDoubleTypeTag;	//"d"
 extern const char *bbStringTypeTag;	//"$"
 extern const char *bbObjectTypeTag;	//":Object"
 extern const char *bbBytePtrTypeTag;//"*b"
+extern const char *bbEnumTypeTag;   //"/"
 
 struct bbDataDef { 
 	char * type; 

+ 7 - 7
json.mod/json.bmx

@@ -225,9 +225,9 @@ Type TJSONArray Extends TJSON
 	End Method
 
 	Method ObjectEnumerator:TJSONArrayEnum()
-		Local enum:TJSONArrayEnum =New TJSONArrayEnum
-		enum.array = Self
-		Return enum
+		Local enumeration:TJSONArrayEnum =New TJSONArrayEnum
+		enumeration.array = Self
+		Return enumeration
 	End Method
 
 End Type
@@ -429,10 +429,10 @@ Type TJSONObject Extends TJSON
 	End Method
 
 	Method ObjectEnumerator:TJSONObjectEnum()
-		Local enum:TJSONObjectEnum =New TJSONObjectEnum
-		enum.obj = Self
-		enum.objectIter = json_object_iter(jsonPtr)
-		Return enum
+		Local enumeration:TJSONObjectEnum =New TJSONObjectEnum
+		enumeration.obj = Self
+		enumeration.objectIter = json_object_iter(jsonPtr)
+		Return enumeration
 	End Method
 	
 	Rem

+ 6 - 6
linkedlist.mod/linkedlist.bmx

@@ -472,16 +472,16 @@ Type TList
 ?Threaded
 			LockMutex(TListEnum._mutex)
 ?
-		Local enum:TListEnum=TListEnum(TListEnum._pool.RemoveFirst())
+		Local enumeration:TListEnum=TListEnum(TListEnum._pool.RemoveFirst())
 ?Threaded
 			UnlockMutex(TListEnum._mutex)
 ?
-		If Not enum Then
-			enum = New TListEnum
+		If Not enumeration Then
+			enumeration = New TListEnum
 		End If
-		enum._link=_head._succ
-		enum._list = Self
-		Return enum
+		enumeration._link=_head._succ
+		enumeration._list = Self
+		Return enumeration
 	End Method
 
 	Rem

+ 4 - 4
stringbuilder.mod/stringbuilder.bmx

@@ -492,10 +492,10 @@ Type TSplitBuffer
 	End Method
 
 	Method ObjectEnumerator:TSplitBufferEnum()
-		Local enum:TSplitBufferEnum = New TSplitBufferEnum
-		enum.buffer = Self
-		enum.length = Length()
-		Return enum
+		Local enumeration:TSplitBufferEnum = New TSplitBufferEnum
+		enumeration.buffer = Self
+		enumeration.length = Length()
+		Return enumeration
 	End Method
 
 	Method Delete()