changeset 34:df038cef648b

More work on supporting user defined types in the C backend
author Mike Pavone <pavone@retrodev.com>
date Wed, 30 Sep 2009 01:25:03 -0400
parents 3b47a8538df2
children 3498713c3dc9
files cbackend.rhope nworker.rhope runtime/object.c runtime/object.h
diffstat 4 files changed, 233 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.rhope	Mon Sep 28 22:08:40 2009 -0400
+++ b/cbackend.rhope	Wed Sep 30 01:25:03 2009 -0400
@@ -57,6 +57,35 @@
 	out,notfound <- [[reg]Lookup >>]Index[method]
 }
 
+Blueprint C Field Registry
+{
+	Lookup
+	Next ID
+}
+
+C Field Registry[:out]
+{
+	out <- [[Build["C Field Registry"]]Lookup <<[New@Dictionary[]]]Next ID<<[0]
+
+}
+
+Register Field@C Field Registry[reg,field:out]
+{
+	[[reg]Lookup >>]Index[field]
+	{
+		out <- reg
+	}{
+		field ID <- [reg]Next ID>>
+		new lookup <- [[reg]Lookup >>]Set[field, field ID]
+		out <- [[reg]Lookup <<[new lookup]]Next ID <<[[field ID]+[1]]
+	}
+}
+
+Field ID@C Field Registry[reg,field:out,notfound]
+{
+	out,notfound <- [[reg]Lookup >>]Index[field]
+}
+
 Blueprint C Type
 {
 	Name
@@ -79,16 +108,36 @@
 	out <- [ctype]Methods <<[ [[ctype]Methods >>]Append[name] ]
 }
 
+Register Methods@C Type[ctype,method reg:out]
+{
+	out <- Fold["Register Method", method reg, [ctype]Methods >>]
+}
+
+Register Fields@C Type[ctype,field reg:out]
+{
+	out <- Fold["Register Field", field reg, [ctype]Fields >>]
+}
+
+Rhope Type to C[typename,naked:out]
+{
+	If[[typename] = ["Any Type"]]
+	{
+		ctype <- "struct object"
+	}{
+		ctype <- ["t_"]Append[Escape Rhope Name[typename]]
+	}
+	If[naked]
+	{
+		out <- Val[ctype]
+	}{
+		out <- [ctype]Append[" * "]
+	}
+}
+
 _Type Def C Type[text,field:out]
 {
 	name <- [field]Index[0]
-	rawtype <- [field]Index[1]
-	If[[rawtype] = ["Any Type"]]
-	{
-		type <- "\n\tobject * "
-	}{
-		type <- [["\n\tt_"]Append[Escape Rhope Name[rawtype]]]Append[" * "]
-	}
+	type <- ["\n\t"]Append[Rhope Type to C[[field]Index[1], No]]
 	out <- [[[text]Append[type]]Append[Escape Rhope Name[name]]]Append[";"]
 }
 
@@ -140,8 +189,29 @@
 		]Next ID <<[0]
 }
 
-Register Type@C Type Registry[reg,name,def:out]
+_Type Defs C[text,def:out]
+{
+	out <- [[text]Append["\n\n"]]Append[[def]Type Def]
+}
+
+Type Defs@C Type Registry[reg:out]
+{
+	out <- Fold["_Type Defs C", "", [reg]Definitions >>]
+}
+
+_Type Inits C[reg,method reg,field reg,text,def,name:out]
 {
+	out <- [[text]Append["\n\n"]]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg] ]
+}
+
+Type Inits@C Type Registry[reg,method reg,field reg:out]
+{
+	out <- Fold[[[["_Type Inits C"]Set Input[0, reg]]Set Input[1, method reg]]Set Input[2, field reg], "", [reg]Definitions >>]
+}
+
+Register Type@C Type Registry[reg,def:out]
+{
+	name <- [def]Name >>
 	[[reg]Lookup >>]Index[name]
 	{
 		out <- reg
@@ -418,26 +488,32 @@
 Text@C Function[func:out]
 {
 	cname <- Escape Rhope Name[[func]Name >>]
-	If[ [[[func]Variables >>]Length] = [0] ]
+	If[ [[func]Convention >>] = ["rhope"] ]
 	{
-		out <- [[[[[["FuncNoLocals("
-			]Append[cname]
-			]Append[",\n\tNumParams "]
-			]Append[ [[func]Inputs >>]Length ]
-			]Append[",\n\tCallSpace 32)\n\n"]//TODO: Fill in with calculated callspace value
-			]Append[ [[func]Statements >>]Join[""] ]
-			]Append["EndFunc"]
+		If[ [[[func]Variables >>]Length] = [0] ]
+		{
+			out <- [[[[[["FuncNoLocals("
+				]Append[cname]
+				]Append[",\n\tNumParams "]
+				]Append[ [[func]Inputs >>]Length ]
+				]Append[",\n\tCallSpace 32)\n\n"]//TODO: Fill in with calculated callspace value
+				]Append[ [[func]Statements >>]Join[""] ]
+				]Append["EndFunc"]
+		}{
+			out <- [[[[[[[[["Func("
+				]Append[cname]
+				]Append[",\n\tNumParams "]
+				]Append[ [[func]Inputs >>]Length ]
+				]Append[",\n\tCallSpace 32,\n\t"]//TODO: Fill in with calculated callspace value
+				]Append[["l_"]Append[cname]]
+				]Append[")\n\n"]
+				]Append[ [[func]Statements >>]Join[""] ]
+				]Append[[func]Set Outputs]
+				]Append["EndFunc"]
+		}
 	}{
-		out <- [[[[[[[[["Func("
-			]Append[cname]
-			]Append[",\n\tNumParams "]
-			]Append[ [[func]Inputs >>]Length ]
-			]Append[",\n\tCallSpace 32,\n\t"]//TODO: Fill in with calculated callspace value
-			]Append[["l_"]Append[cname]]
-			]Append[")\n\n"]
-			]Append[ [[func]Statements >>]Join[""] ]
-			]Append[[func]Set Outputs]
-			]Append["EndFunc"]
+		//TODO: We need to store input and output types somewhere so we can reference them here
+		out <- "oops"
 	}
 }
 
@@ -445,11 +521,25 @@
 {
 	Functions
 	Method Registry
+	Field Registry
+	Type Registry
 }
 
 C Program[:out]
 {
-	out <- [[Build["C Program"]]Functions <<[New@Dictionary[]]]Method Registry <<[C Method Registry[]]
+	out <- [[[[Build["C Program"]]Functions <<[New@Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[]]]Field Registry <<[C Field Registry[]]
+}
+
+Register Type@C Program[program,def:out]
+{
+	out <- [[[program]Type Registry <<[ [[program]Type Registry >>]Register Type[def] ]
+		]Method Registry <<[ [def]Register Methods[[program]Method Registry >>] ]
+		]Field Registry <<[ [def]Register Fields[[program]Field Registry >>] ]
+}
+
+Create Type@C Program[program,name:out]
+{
+	out <- C Type[name]
 }
 
 Create Function@C Program[program,name,inputs,outputs,convention:out]
@@ -508,7 +598,9 @@
 #include \"context.h\"
 #include \"func.h\"
 #include \"integer.h\"\n\n"
-	out <- [[[[headers]Append[Fold["_Text C Program", 
+	out <- [[[[[[headers
+		]Append[[[program]Type Registry >>]Type Defs]
+		]Append[Fold["_Text C Program", 
 				Fold["_Consts C Program", 
 					Fold["_Defs C Program", "", [program]Functions >>], 
 					constants
@@ -519,6 +611,7 @@
 	calldata *cdata;
 	context * ct;
 	register_builtin_types();\n\n"]
+		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
 		]Append[Fold["_Set Consts C Program", "", constants]]
 		]Append["
 	ct = new_context();
--- a/nworker.rhope	Mon Sep 28 22:08:40 2009 -0400
+++ b/nworker.rhope	Wed Sep 30 01:25:03 2009 -0400
@@ -654,9 +654,9 @@
 
 Test[:out]
 {
-	ref+ <- Worker Ref["+","cdecl",2,1]
-	ref* <- Worker Ref["*","cdecl",2,1]
-	,a <- [NWorker["cdecl"]
+	ref+ <- Worker Ref["+","rhope",2,1]
+	ref* <- Worker Ref["*","rhope",2,1]
+	,a <- [NWorker["rhope"]
 	]Add Input["a", 0] {
 		,b <- [~]Add Input["b", 1] {
 		,c <- [~]Add Input["c", 2] {
@@ -716,15 +716,15 @@
 
 Register Builtins@NProgram[prog:out]
 {
-	out <- [[[[[[[[[prog]Register Worker["+", "cdecl", 2, 1]
-	]Register Worker["-", "cdecl", 2, 1]
-	]Register Worker["*", "cdecl", 2, 1]
-	]Register Worker["/", "cdecl", 2, 1]
-	]Register Worker["Print", "cdecl", 1, 1]
-	]Register Worker["Index", "cdecl", 2, 1]
-	]Register Worker["If", "cdecl", 1, 2]
-	]Register Worker["<", "cdecl", 2, 1]
-	]Register Worker["<String@Whole Number", "cdecl", 1, 1]
+	out <- [[[[[[[[[prog]Register Worker["+", "rhope", 2, 1]
+	]Register Worker["-", "rhope", 2, 1]
+	]Register Worker["*", "rhope", 2, 1]
+	]Register Worker["/", "rhope", 2, 1]
+	]Register Worker["Print", "rhope", 1, 1]
+	]Register Worker["Index", "rhope", 2, 1]
+	]Register Worker["If", "rhope", 1, 2]
+	]Register Worker["<", "rhope", 2, 1]
+	]Register Worker[">", "rhope", 1, 1]
 }
 
 Find Worker@NProgram[prog, name:out,notfound]
--- a/runtime/object.c	Mon Sep 28 22:08:40 2009 -0400
+++ b/runtime/object.c	Wed Sep 30 01:25:03 2009 -0400
@@ -342,6 +342,104 @@
 	bp->method_lookup[methodid-bp->first_methodid] = impl;
 }
 
+void add_getter(blueprint * bp, uint32_t getfieldid, rhope_func impl)
+{
+	rhope_func * temp;
+	if(getfieldid < 1) {
+		fputs("Attempt to add a method with an ID < 1\n", stderr);
+		exit(-1);
+	}
+	if (!bp->getter_lookup)
+	{
+		bp->getter_lookup = malloc(sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+		if(!bp->getter_lookup) {
+			fprintf(stderr, "Couldn't allocate %d bytes for getter lookup table\n", sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+			exit(-1);
+		}
+		if(BELOW_INITIAL_METHOD > getfieldid) {
+			bp->first_getfieldid = 1;
+			bp->last_getfieldid = 1+INITIAL_METHOD_LOOKUP;
+		} else {
+			bp->first_getfieldid = getfieldid - BELOW_INITIAL_METHOD;
+			bp->last_getfieldid = bp->first_getfieldid + INITIAL_METHOD_LOOKUP;
+		}
+		memset(bp->getter_lookup, '\0', sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+	} else {
+		if (getfieldid < bp->first_getfieldid) {
+			temp = bp->getter_lookup;
+			//Note: if this gets changed to generating an exception on failure, we need to restore the original buffer
+			bp->getter_lookup = malloc(sizeof(rhope_func) * (bp->last_getfieldid-getfieldid));
+			if(!bp->getter_lookup) {
+				fprintf(stderr, "Couldn't allocate %d bytes for getter lookup table\n", sizeof(rhope_func) * (bp->last_getfieldid-getfieldid));
+				exit(-1);
+			}
+			memset(bp->getter_lookup, '\0', (bp->first_getfieldid-getfieldid) * sizeof(rhope_func));
+			memcpy(bp->getter_lookup + bp->first_getfieldid-getfieldid, temp, (bp->last_getfieldid-bp->first_getfieldid)*sizeof(rhope_func));
+			free(temp);
+			bp->first_getfieldid = getfieldid;
+		} else if(getfieldid >= bp->last_getfieldid) {
+			//Note: if this gets changed to generating an exception on failure, we need to restore the original buffer
+			bp->getter_lookup = realloc(bp->getter_lookup, (getfieldid+1-bp->first_getfieldid) * sizeof(rhope_func));
+			if(!bp->getter_lookup) {
+				fprintf(stderr, "Couldn't resize getter lookup table to %d bytes\n", (getfieldid+1-bp->first_getfieldid) * sizeof(rhope_func));
+				exit(-1);
+			}
+			memset(bp->getter_lookup+bp->last_getfieldid, '\0', (getfieldid+1)-bp->last_getfieldid);
+			bp->last_getfieldid = getfieldid+1;
+		}
+	}
+	bp->getter_lookup[getfieldid-bp->first_getfieldid] = impl;
+}
+
+void add_setter(blueprint * bp, uint32_t setfieldid, rhope_func impl)
+{
+	rhope_func * temp;
+	if(setfieldid < 1) {
+		fputs("Attempt to add a method with an ID < 1\n", stderr);
+		exit(-1);
+	}
+	if (!bp->setter_lookup)
+	{
+		bp->setter_lookup = malloc(sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+		if(!bp->setter_lookup) {
+			fprintf(stderr, "Couldn't allocate %d bytes for setter lookup table\n", sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+			exit(-1);
+		}
+		if(BELOW_INITIAL_METHOD > setfieldid) {
+			bp->first_setfieldid = 1;
+			bp->last_setfieldid = 1+INITIAL_METHOD_LOOKUP;
+		} else {
+			bp->first_setfieldid = setfieldid - BELOW_INITIAL_METHOD;
+			bp->last_setfieldid = bp->first_setfieldid + INITIAL_METHOD_LOOKUP;
+		}
+		memset(bp->setter_lookup, '\0', sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+	} else {
+		if (setfieldid < bp->first_setfieldid) {
+			temp = bp->setter_lookup;
+			//Note: if this sets changed to generating an exception on failure, we need to restore the original buffer
+			bp->setter_lookup = malloc(sizeof(rhope_func) * (bp->last_setfieldid-setfieldid));
+			if(!bp->setter_lookup) {
+				fprintf(stderr, "Couldn't allocate %d bytes for setter lookup table\n", sizeof(rhope_func) * (bp->last_setfieldid-setfieldid));
+				exit(-1);
+			}
+			memset(bp->setter_lookup, '\0', (bp->first_setfieldid-setfieldid) * sizeof(rhope_func));
+			memcpy(bp->setter_lookup + bp->first_setfieldid-setfieldid, temp, (bp->last_setfieldid-bp->first_setfieldid)*sizeof(rhope_func));
+			free(temp);
+			bp->first_setfieldid = setfieldid;
+		} else if(setfieldid >= bp->last_setfieldid) {
+			//Note: if this sets changed to generating an exception on failure, we need to restore the original buffer
+			bp->setter_lookup = realloc(bp->setter_lookup, (setfieldid+1-bp->first_setfieldid) * sizeof(rhope_func));
+			if(!bp->setter_lookup) {
+				fprintf(stderr, "Couldn't resize setter lookup table to %d bytes\n", (setfieldid+1-bp->first_setfieldid) * sizeof(rhope_func));
+				exit(-1);
+			}
+			memset(bp->setter_lookup+bp->last_setfieldid, '\0', (setfieldid+1)-bp->last_setfieldid);
+			bp->last_setfieldid = setfieldid+1;
+		}
+	}
+	bp->setter_lookup[setfieldid-bp->first_setfieldid] = impl;
+}
+
 blueprint * get_blueprint_byid(uint32_t type)
 {
 	if(type >= max_registered_type)
--- a/runtime/object.h	Mon Sep 28 22:08:40 2009 -0400
+++ b/runtime/object.h	Wed Sep 30 01:25:03 2009 -0400
@@ -71,6 +71,8 @@
 blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);
 blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);
 void add_method(blueprint * bp, uint32_t methodid, rhope_func impl);
+void add_getter(blueprint * bp, uint32_t fieldid, rhope_func impl);
+void add_setter(blueprint * bp, uint32_t fieldid, rhope_func impl);
 returntype convert_to(uint32_t convertto, calldata * params);
 returntype convert_from(uint32_t convertfrom, calldata * params);
 object * copy_object(object * tocopy);