changeset 37:640f541e9116

Added support for type declarations on user defined workers and added a few more methods to Int32 in the runtime for the C backend
author Mike Pavone <pavone@retrodev.com>
date Mon, 05 Oct 2009 23:12:43 -0400
parents 495dddadd058
children 7f05bbe82f24
files backendutils.rhope cbackend.rhope nworker.rhope parser.vistxt parser_old.rhope runtime/builtin.c runtime/context.c runtime/integer.c runtime/integer.h runtime/object.c
diffstat 10 files changed, 284 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/backendutils.rhope	Sat Oct 03 03:18:15 2009 -0400
+++ b/backendutils.rhope	Mon Oct 05 23:12:43 2009 -0400
@@ -123,7 +123,7 @@
 
 Make Op@OrCond[cond,func:out]
 {
-	out <- ["("]Append[[[[cond]Condition1 >>]Append[" || "]]Append[[[cond]Condition2 >>]Append[")"]]]
+	out <- ["("]Append[[[ [[cond]Condition1 >>]Make Op[func] ]Append[" || "]]Append[[ [[cond]Condition2 >>]Make Op[func] ]Append[")"]]]
 }
 
 Blueprint AndCond
@@ -139,7 +139,7 @@
 
 Make Op@AndCond[cond,func:out]
 {
-	out <- ["("]Append[[[[cond]Condition1 >>]Append[" && "]]Append[[[cond]Condition2 >>]Append[")"]]]
+	out <- ["("]Append[[[ [[cond]Condition1 >>]Make Op[func] ]Append[" && "]]Append[[ [[cond]Condition2 >>]Make Op[func] ]Append[")"]]]
 }
 
 Blueprint Field Ref
@@ -157,3 +157,31 @@
 {
 	out <- [func]Field Result[[ref]Variable >>,[ref]Field >>]
 }
+
+Blueprint Type Instance
+{
+	Name
+	Params
+	Variant
+}
+
+Type Instance[raw name:out]
+{
+	If[[raw name]=[""]]
+	{
+		name <- "Any Type"
+	}{
+		name <- raw name
+	}
+	out <- [[[Build["Type Instance"]]Name <<[name]]Params <<[()]]Variant <<["Boxed"]
+}
+
+Set Variant[type,variant:out,invalid]
+{
+	[("Boxed","Naked","Pointer","Raw Pointer")]Find[variant]
+	{
+		out <- [type]Variant <<[variant]
+	}{
+		invalid <- type
+	}
+}
--- a/cbackend.rhope	Sat Oct 03 03:18:15 2009 -0400
+++ b/cbackend.rhope	Mon Oct 05 23:12:43 2009 -0400
@@ -128,13 +128,35 @@
 	out <- Fold["_Register Field C", field reg, [ctype]Fields >>]
 }
 
-Rhope Type to C[typename:out]
+Rhope Type to C[type:out]
 {
+	If[[Type Of[type]]=["Type Instance"]]
+	{
+		typename <- [type]Name >>
+		variant <- [type]Variant >>
+	}{
+		typename <- type
+		variant <- "boxed"
+	}
 	If[[typename] = ["Any Type"]]
 	{
 		out <- "struct object *"
 	}{
-		out <- [["t_"]Append[Escape Rhope Name[typename]]]Append[" *"]
+		[("Naked","Raw Pointer")]Find[variant]
+		{
+			prefix <- "nt_"
+		}{
+			prefix <- "t_"
+		}
+		
+		If[[variant]=["Naked"]]
+		{
+			postfix <- ""
+		}{
+			postfix <- " *"
+		}
+		
+		out <- [[prefix]Append[Escape Rhope Name[typename]]]Append[postfix]
 	}
 }
 
@@ -289,12 +311,12 @@
 		]Output Types <<[ Fold[["Append"]Set Input[1, "Any Type"], (), outputs] ]
 }
 
-Set Input Type@C Function[func,input num,type:out]
+Set Input Type@C Function[func,type,input num:out]
 {
 	out <- [func]Input Types <<[ [[func]Input Types >>]Set[input num, type] ]
 }
 
-Set Output Type@C Function[func,output num,type:out]
+Set Output Type@C Function[func,type,output num:out]
 {
 	out <- [func]Output Types <<[ [[func]Output Types >>]Set[output num, type] ]
 }
@@ -426,7 +448,7 @@
 
 Set Field Null@C Function[func,var,field:out]
 {
-	out <- [func]Add Statement[ [[[var]Append["->"]]Append[field]]Append[" = NULL"] ]
+	out <- [func]Add Statement[ [[func]Field Result[var,field]]Append[" = NULL"] ]
 }
 
 Copy@C Function[func,pdest:out]
@@ -632,28 +654,47 @@
 	}
 }
 
+Check Param Type C[text,type,input num,func:out]
+{
+	If[[Type Of[type]] = ["String"]]
+	{
+		typename <- type
+	}{
+		typename <- [type]Name >>
+	}
+	If[[typename] = ["Any Type"]]
+	{
+		out <- text
+	}{
+		out <- [text]Append[[[["\tParam("]Append[input num]]Append[ [","]Append[ [[func]Type Registry >>]Type ID[typename] ] ]]Append[")\n"]]
+	}
+}
+
 Text@C Function[func:out]
 {	
 	If[ [[func]Convention >>] = ["rhope"] ]
 	{
 		cname <- Escape Rhope Name[[func]Name >>]
+		param check <- Fold[["Check Param Type C"]Set Input[3, func], "", [func]Input Types >>]
 		If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
 		{
-			out <- [[[[[["FuncNoLocals("
+			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[param check]
 				]Append[ [[func]Statements >>]Join[""] ]
 				]Append["EndFunc"]
 		}{
-			out <- [[[[[[[[["Func("
+			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[param check]
 				]Append[ [[func]Statements >>]Join[""] ]
 				]Append[[func]Set Outputs]
 				]Append["EndFunc"]
@@ -743,11 +784,21 @@
 	{
 		out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Int32("]]Append[value]]Append[");\n"]]
 	}{
-		If[[valtype] = ["Type Literal"]]
+		If[[valtype] = ["Type Instance"]]
 		{
 			//TODO: Support parametric types
 			typeid <- [type reg]Type ID[[value]Name >>]
 			out <- [text]Append[[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_Blueprint("]]Append[typeid]]Append[");\n"]]
+		}{
+			If[[valtype] = ["Yes No"]]
+			{
+				If[value]
+				{
+					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_yes;\n"]]
+				}{
+					out <- [text]Append[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = (object *)val_no;\n"]]
+				}
+			}
 		}
 	}
 }
@@ -762,7 +813,8 @@
 #include \"context.h\"
 #include \"func.h\"
 #include \"integer.h\"
-#include \"blueprint.h\"\n\n"
+#include \"blueprint.h\"
+#include \"bool.h\"\n\n"
 	out <- [[[[[[headers
 		]Append[[[program]Type Registry >>]Type Defs]
 		]Append[Fold[["_Text C Program"]Set Input[2, [program]Type Registry >>], 
--- a/nworker.rhope	Sat Oct 03 03:18:15 2009 -0400
+++ b/nworker.rhope	Mon Oct 05 23:12:43 2009 -0400
@@ -258,7 +258,9 @@
 	Convention
 	Nodes
 	Inputs
+	Input Types
 	Outputs
+	Output Types
 	Uses
 	NodeResults
 	Free Temps
@@ -266,7 +268,7 @@
 
 NWorker[convention:out]
 {
-	out <- [[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]
+	out <- [[[[[[Build["NWorker"]]Convention <<[convention]]Nodes <<[()]]Inputs <<[()]]Outputs <<[()]]Input Types <<[()]]Output Types <<[()]
 }
 
 Add Node@NWorker[worker,type,data,inputs,outputs:out,node index]
@@ -287,14 +289,30 @@
 
 Add Input@NWorker[worker,name,number:out,node index]
 {
+	out,node index <- [worker]Add Typed Input[name,number,Type Instance["Any Type"]]
+}
+
+Add Typed Input@NWorker[worker,name,number,type:out,node index]
+{
 	,node index <- [worker]Add Node["input",number,0,1]
-	{ out <- [~]Inputs <<[[[~]Inputs >>]Set[number,name]] }
+	{ 
+		out <- [[~]Inputs <<[[[~]Inputs >>]Set[number,name]]
+		]Input Types <<[[[~]Input Types >>]Set[number,type]]
+	}
 }
 
 Add Output@NWorker[worker,name,number:out,node index]
 {
+	out,node index <- [worker]Add Typed Output[name,number,Type Instance["Any Type"]]
+}
+
+Add Typed Output@NWorker[worker,name,number,type:out,node index]
+{
 	,node index <- [worker]Add Node["output",number,1,0]
-	{ out <- [~]Outputs <<[[[~]Outputs >>]Set[number,name]] }
+	{ 
+		out <- [[~]Outputs <<[[[~]Outputs >>]Set[number,name]]
+		]Output Types <<[[[~]Output Types >>]Set[number,type]]
+	}
 }
 
 Add Object Get@NWorker[worker,fieldname:out,node index]
@@ -441,7 +459,7 @@
 		}{
 			If[[[node]Type >>] = ["const"]]
 			{
-				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				If[[Type Of[[node]Data >>]] = ["Type Instance"]]
 				{
 					//TODO: Support parametric types
 					datstring <- [[node]Data >>]Name >>
@@ -578,7 +596,7 @@
 			If[[[node]Type >>] = ["const"]]
 			{
 				//TODO: Handle list constants
-				If[[Type Of[[node]Data >>]] = ["Type Literal"]]
+				If[[Type Of[[node]Data >>]] = ["Type Instance"]]
 				{
 					//TODO: Support parametric types
 					datstring <- [[node]Data >>]Name >>
@@ -672,7 +690,7 @@
 {
 	Print[["Compiling: "]Append[name]]
 	{
-	ifunc <- [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>]
+	ifunc <- Fold["Set Output Type", Fold["Set Input Type", [program]Create Function[name,[worker]Inputs >>, [worker]Outputs >>, [worker]Convention >>], [worker]Input Types >>], [worker]Output Types >>]
 	
 	res vars <- [worker]Result Vars
 	func <- Fold["Set Null", Fold["Set Null", Fold[["Allocate Var"]Set Input[2, "Any Type"], ifunc, res vars], res vars], [worker]Outputs >>]
@@ -684,7 +702,7 @@
 	}{
 		final func <- Val[func]
 	}
-	out <- [program]Store Function[Fold[["Release Var"]Set Input[0, worker], final func, res vars]]
+	out <- [program]Store Function[Fold["Release", Fold[["Release Var"]Set Input[0, worker], final func, res vars], [worker]Inputs >>]]
 	}
 }
 
@@ -776,7 +794,7 @@
 Make Special@NBlueprint[bp,backend,func name,bp name,pop worker:out]
 {
 	func <- [[backend]Create Function[func name,("obj"),(),"cdecl"]
-		]Set Input Type[0, bp name]
+		]Set Input Type[bp name, 0]
 	out <- [backend]Store Function[Fold[pop worker, func, [bp]Fields >>]]
 }
 
@@ -787,16 +805,16 @@
 	name <- [field]Index[0]
 	type <- [field]Index[1]
 	,getref <- [[[[backend]Create Function[ [[[name]Append[" >>"]]Append["@"]]Append[type name], ("obj"), ("out"), "rhope"]
-		]Set Input Type[0, type name]
-		]Set Output Type[0, type]
+		]Set Input Type[type name, 0]
+		]Set Output Type[type, 0]
 		]Read Field["obj", name]
-	{ getter <- [~]Do AddRef[getref, "out"]
+	{ getter <- [[~]Do AddRef[getref, "out"]]Release["obj"]
 	{ Print["Got getter"] } }
 		
 	,origref <- [[[[[[backend]Create Function[ [[[name]Append[" <<"]]Append["@"]]Append[type name], ("obj","newval"), ("out"), "rhope"]
-		]Set Input Type[0, type name]
-		]Set Input Type[1, type]
-		]Set Output Type[0, type name]
+		]Set Input Type[type name, 0]
+		]Set Input Type[type, 1]
+		]Set Output Type[type name, 0]
 		]Copy["obj"]
 		]Read Field["obj", name]
 	{ 
@@ -895,14 +913,16 @@
 
 Register Builtins@NProgram[prog:out]
 {
-	out <- [[[[[[[[[prog]Register Worker["+@Int32", "rhope", 2, 1]
+	out <- [[[[[[[[[[[prog]Register Worker["+@Int32", "rhope", 2, 1]
 	]Register Worker["-@Int32", "rhope", 2, 1]
 	]Register Worker["*@Int32", "rhope", 2, 1]
 	]Register Worker["/@Int32", "rhope", 2, 1]
+	]Register Worker["LShift@Int32", "rhope", 2, 1]
+	]Register Worker["RShift@Int32", "rhope", 2, 1]
 	]Register Worker["Print", "rhope", 1, 1]
 	]Register Worker["If@Yes No", "rhope", 1, 2]
 	]Register Worker["<@Int32", "rhope", 2, 1]
-	]Register Worker[">@Int32", "rhope", 1, 1]
+	]Register Worker[">@Int32", "rhope", 2, 1]
 	]Register Worker["Build", "rhope", 1, 1]
 }
 
--- a/parser.vistxt	Sat Oct 03 03:18:15 2009 -0400
+++ b/parser.vistxt	Mon Oct 05 23:12:43 2009 -0400
@@ -225,7 +225,7 @@
 			:|
 		:|
 	:||:
-		Print[["Error: Could not find a worker named "]Append[[node(0)]Name >>]]
+		Print[[[["Error: Could not find a worker named "]Append[[node(0)]Name >>]]Append[" in worker "]]Append[ [parse worker(3)]Name >> ]]
 	:|
 :|
 
--- a/parser_old.rhope	Sat Oct 03 03:18:15 2009 -0400
+++ b/parser_old.rhope	Mon Oct 05 23:12:43 2009 -0400
@@ -135,11 +135,13 @@
 	Line Number
 	Trees
 	Uses Stores
+	Input Types
+	Output Types
 }
 
-New@Parse Worker[name,inputs,outputs,line:out]
+New@Parse Worker[name,inputs,outputs,intypes,outtypes,line:out]
 {
-	out <- [[[[[[Build["Parse Worker"]]Name <<[name]]Inputs <<[inputs]]Outputs <<[outputs]]Line Number <<[line]]Trees <<[New@List[]]]Uses Stores <<[New@List[]]
+	out <- [[[[[[[[Build["Parse Worker"]]Name <<[name]]Inputs <<[inputs]]Outputs <<[outputs]]Line Number <<[line]]Trees <<[New@List[]]]Uses Stores <<[New@List[]]]Input Types <<[intypes]]Output Types <<[outtypes]
 }
 
 Blueprint Worker Node
@@ -300,7 +302,7 @@
 	{
 	[[parse worker]Outputs >>]Find[assignment]
 	{
-		,output index <- [worker]Add Output[assignment, ~]
+		,output index <- [worker]Add Typed Output[assignment, ~, [[parse worker]Output Types >>]Index[~]]
 		{
 			Print[
 				[[[[[[["Wire: "
@@ -479,7 +481,7 @@
 {
 	[[parse worker]Inputs >>]Find[[node]Name >>]
 	{
-		after add <- [worker]Add Input[[node]Name >>, ~] {}
+		after add <- [worker]Add Typed Input[[node]Name >>, ~, [[parse worker]Input Types>>]Index[~]] {}
 		{
 			Print[["Added input, node:"]Append[~]]
 			assign refs <- Fold[[["Assignment Save Reference"]Set Input[3, parse worker]]Set Input[4, ~], refs, [node]Assignments >>]
@@ -908,21 +910,8 @@
 	}
 }
 
-Blueprint Type Literal
-{
-	Name
-	Params
-}
-
-Type Literal[name:out]
+Parse Params@Type Instance[literal,params,string:out,after]
 {
-	Print["Type Literal"]
-	out <- [[Build["Type Literal"]]Name <<[name]]Params <<[()]
-}
-
-Parse Params@Type Literal[literal,params,string:out,after]
-{
-	Print[["Parse Params: "]Append[ [string]Slice[10] ]]
 	plist,after <- Parse List[string,params,()]
 	out <- [literal]Params <<[plist]
 }
@@ -950,7 +939,7 @@
 				before <- Trim[raw before, "\r\n\t "]
 				If[[delim] = [[params]List Begin >>]]
 				{
-					value,after <- [Type Literal[before]]Parse Params[params,afterdelim]
+					value,after <- [Type Instance[before]]Parse Params[params,afterdelim]
 				}{
 					Val[afterdelim]
 					{
@@ -1144,11 +1133,82 @@
 	}
 }
 
+Remove Named Pipe Node[element:out]
+{
+	If[[Type Of[element]] = ["Named Pipe Node"]]
+	{
+		out <- [element]Name >>
+	}{
+		If[[Type Of[element]] = ["Type Instance"]]
+		{
+			out <- [element]Params <<[ Map[[element]Params >>, "Remove Named Pipe Node"] ]
+		}{
+			out <- element
+		}
+	}
+}
+
+Parse Param List[text,paramlist,typelist,params:out params,out types]
+{
+	delims <- [[()]Append[[params]List Begin >>]]Append[[params]List Delim >>]
+	after,param name <-[text]Get DString[delims] {}
+	{
+		nextlist <- [paramlist]Append[Trim[~, "\r\n\t "]]
+		next types <-  [typelist]Append[paramtype]
+	}{
+		If[[~] = [[params]List Begin >>]]
+		{
+			type info,after type <- Parse List[after,params,()]
+			type <- [type info]Index[0]
+			{
+				If[[Type Of[~]] = ["Named Pipe Node"]]
+				{
+					before variant <- Type Instance[[type]Name >>]
+				}{
+					before variant <- <- [type]Params <<[ Map[[type]Params >>, "Remove Named Pipe Node"] ]
+				}
+				variant <- [type info]Index[1]
+				{
+					,warn <- If[[Type Of[~]] = ["Named Pipe Node"]]
+					{
+						paramtype,warn <- [before variant]Set Variant[[variant]Name >>]
+					}
+					Val[warn]
+					{
+						Print[[[["Warning: Invalid variant for type "]Append[[before variant]Name >>]]Append[" on input "]]Append[param name]]
+						paramtype <- Val[before variant]
+					}
+				}{
+					paramtype <- Val[before variant]
+				}
+			}{
+				paramtype <- Type Instance["Any Type"]
+			}
+			[after type]Get DString[","]
+			{
+				out params,out types <- Parse Param List[~,nextlist,next types,params]
+			} {} {} {
+				out params <- Val[nextlist]
+				out types <- Val[next types]
+			}
+		}{
+			paramtype <- Type Instance["Any Type"]
+			out params,out types <- Parse Param List[after,nextlist,next types,params]
+		}
+		
+	}{
+		paramtype <- Type Instance["Any Type"]
+		out params <- Val[nextlist]
+		out types <- Val[next types]
+	}
+}
+
 Worker Name[string,params,tree,lines:out]
 {
 	,whitespace name <- [string]Get Comment DString[[params]Arg Begin >>, params]
 	{
 		worker name <- Trim[whitespace name, "\n\r\t "]
+		Print[["Parsing worker: "]Append[worker name]]
 		in out <- [params]In Out Delim >>
 		arg end <- [params]Arg End >>
 		delims <- [[New@List[]]Append[in out]]Append[arg end]
@@ -1162,17 +1222,25 @@
 			{
 				after arglist <- [after]Get Comment DString[arg end, params] {}
 				{
-					output string <- Trim[~,"\n\r\t "]
+					outputs,output types <- Parse Param List[~, (), (), params]
+					{ Print["got outputs"] }
+					{ Print["got output types"] }
 				}
 			}{
 				after arglist <- Val[after]
-				output string <- ""
+				outputs <- ()
+				output types <- ()
 			}
-			inputs <- Map[[arglist]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
-			outputs <- Map[[output string]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
+			inputs,input types <- Parse Param List[arglist, (), (), params]
+			{ Print["got inputs"] }
+			{ Print["got input types"] }
+			
+			//inputs <- Map[[arglist]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
+			//outputs <- Map[[output string]Split[[params]List Delim >>], ["Trim"]Set Input[1,"\n\r\t "]]
 
-			New@Parse Worker[worker name, inputs, outputs, 0]
+			New@Parse Worker[worker name, inputs, outputs, input types, output types, 0]
 			{
+				Print["Got parse worker"]
 				body text, modifiers <- [after arglist]Get Comment DString[[params]Block Begin >>, params]
 				modified <- Process Modifiers[~, params, modifiers]
 				expression trees, after body <- Worker Body[body text, params, New@List[]]
--- a/runtime/builtin.c	Sat Oct 03 03:18:15 2009 -0400
+++ b/runtime/builtin.c	Mon Oct 05 23:12:43 2009 -0400
@@ -14,6 +14,10 @@
 		bp = register_type_byid(TYPE_INT32, sizeof(int32_t), NULL, NULL, NULL);
 		add_method(bp, METHOD_ADD, MethodName(_PL_,Int32));
 		add_method(bp, METHOD_SUB, MethodName(_MN_,Int32));
+		add_method(bp, METHOD_MUL, MethodName(_TM_,Int32));
+		add_method(bp, METHOD_DIV, MethodName(_DV_,Int32));
+		add_method(bp, METHOD_LSHIFT, MethodName(LShift,Int32));
+		add_method(bp, METHOD_RSHIFT, MethodName(RShift,Int32));
 		add_method(bp, METHOD_LESS, MethodName(_LT_,Int32));
 		add_method(bp, METHOD_GREATER, MethodName(_GT_,Int32));
 		break;
--- a/runtime/context.c	Sat Oct 03 03:18:15 2009 -0400
+++ b/runtime/context.c	Mon Oct 05 23:12:43 2009 -0400
@@ -27,7 +27,10 @@
 	void * ret;
 	stackchunk * current = ct->current_stack;
 	if(size > STACK_CHUNK_SIZE)
+	{
+		fprintf(stderr, "%d is bigger than stack chunk size of %d\n", size, STACK_CHUNK_SIZE);
 		return NULL;
+	}
 	while(current && STACK_CHUNK_SIZE - current->used < size)
 	{
 		if(!current->next)
@@ -38,7 +41,10 @@
 		current = current->next;
 	}
 	if(!current)
+	{
+		fprintf(stderr, "Failed to allocate stack chunk");
 		return NULL;
+	}
 	ct->current_stack = current;
 	ret = current->data + current->used;
 	current->used += size;
--- a/runtime/integer.c	Sat Oct 03 03:18:15 2009 -0400
+++ b/runtime/integer.c	Mon Oct 05 23:12:43 2009 -0400
@@ -30,6 +30,54 @@
 	release_ref((object *)right);
 EndFunc
 
+MethodNoLocals(_TM_,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
+	CopiedParam(0, TYPE_INT32)
+	Param(1, TYPE_INT32)
+	
+	left->num *= right->num;
+	
+	release_ref((object *)right);
+EndFunc
+
+MethodNoLocals(_DV_,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
+	CopiedParam(0, TYPE_INT32)
+	Param(1, TYPE_INT32)
+	
+	left->num /= right->num;
+	
+	release_ref((object *)right);
+EndFunc
+
+MethodNoLocals(LShift,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
+	CopiedParam(0, TYPE_INT32)
+	Param(1, TYPE_INT32)
+	
+	left->num <<= right->num;
+	
+	release_ref((object *)right);
+EndFunc
+
+MethodNoLocals(RShift,Int32,
+    NumParams 2,
+    CallSpace 1)
+    
+	CopiedParam(0, TYPE_INT32)
+	Param(1, TYPE_INT32)
+	
+	left->num <<= right->num;
+	
+	release_ref((object *)right);
+EndFunc
+
 MethodNoLocals(_LT_,Int32,
 	NumParams 2,
 	CallSpace 1)
--- a/runtime/integer.h	Sat Oct 03 03:18:15 2009 -0400
+++ b/runtime/integer.h	Mon Oct 05 23:12:43 2009 -0400
@@ -10,6 +10,10 @@
 
 MethodDef(_PL_,Int32)
 MethodDef(_MN_,Int32)
+MethodDef(_TM_,Int32)
+MethodDef(_DV_,Int32)
+MethodDef(LShift,Int32)
+MethodDef(RShift,Int32)
 MethodDef(_LT_,Int32)
 MethodDef(_GT_,Int32)
 
--- a/runtime/object.c	Sat Oct 03 03:18:15 2009 -0400
+++ b/runtime/object.c	Mon Oct 05 23:12:43 2009 -0400
@@ -160,6 +160,8 @@
 		rh_atomic_set(ret, refcount, 1);
 		memset(((char *)ret) + sizeof(object), '\0', bp->size);
 		bp->init(ret);
+	} else {
+		fprintf(stderr, "Could not allocate new object with size %d\n", bp->boxed_size);
 	}
 	return ret;
 }