changeset 136:fc3815b7462f

Javascript backend now produces working code for some simple examples, still more of the standard lib that needs to be ported.
author Mike Pavone <pavone@retrodev.com>
date Sun, 14 Nov 2010 23:07:55 -0500
parents 18a4403fe576
children daf1ffaf7c2c
files arrayjs.rhope backendutils_c.rhope cbackend_c.rhope compile_old_c.rhope jsbackend.rhope kernel.rhope kernelbase.rhope kerneljs.rhope number_c.rhope nworker_c.rhope parser_old_c.rhope string.rhope stringjs.rhope
diffstat 13 files changed, 754 insertions(+), 183 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arrayjs.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -0,0 +1,81 @@
+
+Blueprint Array
+{
+
+}
+
+Foreign Javascript:runtime
+{
+	_internal_js_length[array:out(Int32,Naked)]
+	_internal_array_set[array(Array,Boxed,Mutable),index(Int32,Naked),val:array]
+	_internal_array_get[array(Array),index(Int32,Naked):out]
+}
+
+Array[:out(Empty Array)]
+{
+	out <- Build[Array()]
+}
+
+First@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length]
+	{ out <- 0 }
+}
+
+
+Next@Array[array,current:out(Int32),empty]
+{
+	next <- [current]+[1]
+	,empty <- If[[next] < [[array]Length]]
+	{
+		out <- Val[next]
+	}
+}
+
+
+Last@Array[array:out(Int32),empty]
+{
+	,empty <- If[[array]Length]
+	{ out <-  [[array]Length] - [1] }
+}
+
+Append@Array[array,newval:out]
+{
+	out <- [array]Set[[array]Length, newval]
+}
+
+Index@Array[array,index(Int32):out,notfound]
+{
+	,notfound <- If[[index] >= [0]]
+	{
+		,notfound <- If[[index] < [[array]Length]]
+		{
+			out <- _internal_array_get[array, index]
+		}
+	}	
+}
+
+Set@Array[array,index(Int32),val:out,invalid]
+{
+	invalid <- If[[index]<[0]] {}
+	{
+		len <- [array]Length
+		If[[index]>[len]]
+		{
+			out <- [[array]Set[[index]-[1],val]]Set[index, val]
+		}{
+			out <- _internal_array_set[array,index,val]
+		}
+	}
+}
+
+Length@Array[arr:out]
+{
+	out <- _internal_js_length[arr]
+}
+
+Call@Array[arr,index(Int32):out,not found]
+{
+	out,not found <- [arr]Index[index]
+}
+
--- a/backendutils_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/backendutils_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -25,8 +25,7 @@
 
 Make Op@AddRef[addref,func:out]
 {
-	//TODO: Make me work with other backends
-	out <- [["add_ref((object *)"]Append[ [[addref]Value >>]Make Op[func] ]]Append[")"]
+	out <- [func]Make AddRef Op[[addref]Value >>]
 }
 
 Strip Addref@AddRef[op:out]
--- a/cbackend_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/cbackend_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -476,6 +476,11 @@
 	out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]]
 }
 
+Make AddRef Op@C Function[func,val:out]
+{
+	out <- [["add_ref((object *)"]Append[ [val]Make Op[func] ]]Append[")"]
+}
+
 Add@C Function[func,source1,source2,dest:out]
 {
 	out <- [func]Add Operator Statement[source1,source2,dest," + "]
@@ -1134,12 +1139,12 @@
 	out <- [[[[[[Build[C Program()]]Functions <<[Dictionary[]]]Method Registry <<[C Method Registry[]]]Type Registry <<[C Type Registry[p]]]Field Registry <<[C Field Registry[]]]Libraries <<[Dictionary[]]]Escape Pattern <<[p]
 }
 
-Supported Number Types@JS Program[program:out]
+Supported Number Types@C Program[program:out]
 {
 	out <- ("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")
 }
 
-Needed Specials@JS Program[program,typename,makespecial:out]
+Needed Specials@C Program[program,typename,makespecial:out]
 {
 	init name <- [" init "]Append[typename]
 	with init <- [()]Append[ [[()]Append[init name]]Append[[makespecial]Index["init"]] ]
@@ -1154,6 +1159,11 @@
 	}
 }
 
+Set Stdlib Imports@C Program[program,parser:out]
+{
+	out <- [parser]Imports <<[ [[parser]Imports >>]Set["kernel.rhope", Yes] ]
+}
+
 Link@C Program[program,language,library:out]
 {
 	If[[library] = ["runtime"]]
--- a/compile_old_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/compile_old_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -71,40 +71,43 @@
 Main[args]
 {
 
-        fname,options <- Parse Args[args,1,[Dictionary[]]Set["b", "backend"],Dictionary[]]
-        {
-                file <- [File[~]]Open["r"]
-                text <- String[[file]Read[[file]Length]]
-                params <- Parser[]
-                Print[["Parsing "]Append[fname]]
-                Null[text, params, Parse Program[], 0]
-                {
-                        Print["Parsing imports"]
-                        Process Imports[~, params]
-                        {
-                                tree <- [~]Workers << [ Map[[~]Workers >>, Check Worker Literals[?, ~]] ]
-                                { Print["Compiling"] }
-                        }
-                        backmap <- [[Dictionary[]
-                        	]Set["javascript", JS Program[?]]
-                        	]Set["c", C Program[?]]
-                        sel <- [options]Index["backend"]
-                        {
-	                    	backend <- [backmap]Index[~]{}
-	                    	{
-	                    		Print[[["Unknown backend '"]Append[sel]]Append["' selected. Defaulting to C backend."]]
-	                    		backend <- C Program[?]
-	                    	}
-                        }{ backend <- C Program[?] }
-                        compiled <- [Tree to Program Native[tree]]Compile Program[Call[backend]]
-                        { Print["Compiled program to backend"] }
-                        outfname <- [compiled]Text Filename[fname]
-                        outfile <- [File[outfname]]Truncate
-                        [[compiled]Text]Write to File[outfile] 
-                        { Print[["Wrote output to "]Append[outfname]] }
-                }
-        }{}{}{
-                Print["You must provide a file name to compile"]
-        }
+	fname,options <- Parse Args[args,1,[Dictionary[]]Set["b", "backend"],Dictionary[]]
+	{
+		backmap <- [[Dictionary[]
+			]Set["javascript", JS Program[?]]
+			]Set["c", C Program[?]]
+		sel <- [options]Index["backend"]
+		{
+			makeback <- [backmap]Index[~]{}
+			{
+				Print[[["Unknown backend '"]Append[sel]]Append["' selected. Defaulting to C backend."]]
+				makeback <- C Program[?]
+			}
+		}{ makeback <- C Program[?] }
+		backend <- Call[makeback]
+		
+		file <- [File[~]]Open["r"]
+		text <- String[[file]Read[[file]Length]]
+		params <- Parser[]
+		Print[["Parsing "]Append[fname]]
+		Null[text, params, [backend]Set Stdlib Imports[Parse Program[]], 0]
+		{
+			Print["Parsing imports"]
+			Process Imports[~, params]
+			{
+				tree <- [~]Workers << [ Map[[~]Workers >>, Check Worker Literals[?, ~]] ]
+				{ Print["Compiling"] }
+			}
+
+			compiled <- [Tree to Program Native[tree, [backend]Supported Number Types]]Compile Program[backend]
+			{ Print["Compiled program to backend"] }
+			outfname <- [compiled]Text Filename[fname]
+			outfile <- [File[outfname]]Truncate
+			[[compiled]Text]Write to File[outfile] 
+			{ Print[["Wrote output to "]Append[outfname]] }
+		}
+	}{}{}{
+		Print["You must provide a file name to compile"]
+	}
 }
 
--- a/jsbackend.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/jsbackend.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -123,7 +123,7 @@
 	{
 		constructor <- [[[["var t_"]Append[ename]]Append[" = "]]Append[ [("Array","Function")]Index[~] ]]Append[";\n"]
 	}{
-		constructor <- [["function t_"]Append[ename]]Append["\n{}\n"]
+		constructor <- [["function t_"]Append[ename]]Append["()\n{}\n"]
 	}
 	out <- [[[[[constructor
 		]Append[ [[[["t_"]Append[ename]]Append[".prototype.type_id = "]]Append[id]]Append[";\n"] ]
@@ -300,6 +300,11 @@
 	out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]]
 }
 
+Make AddRef Op@JS Function[func,val:out]
+{
+	out <- [val]Make Op[func]
+}
+
 Add@JS Function[func,source1,source2,dest:out]
 {
 	out <- [func]Add Operator Statement[source1,source2,dest," + "]
@@ -445,7 +450,7 @@
 Set Null@JS Function[func,pdest:out]
 {
 	dest <- [pdest]Make Op[func]
-	out <- [func]Add Statement[[dest]Append[" = NULL"]]
+	out <- [func]Add Statement[[dest]Append[" = null"]]
 }
 
 Lookup Constant@JS Function[func,const,doaddref:out]
@@ -473,7 +478,7 @@
 
 Set Field Null@JS Function[func,var,field:out]
 {
-	out <- [func]Add Statement[ [[func]Field Result[var,field]]Append[" = NULL"] ]
+	out <- [func]Add Statement[ [[func]Field Result[var,field]]Append[" = null"] ]
 }
 
 Copy@JS Function[func,pdest:out]
@@ -484,12 +489,27 @@
 
 Box@JS Function[func,psource,pdest,type:out]
 {
-	out <- func
+	dest <- [pdest]Make Op[func]
+	source <- [psource]Make Op[func]
+	typename <- [type]Name >>
+	[("Int32","UInt32","UInt8")]Find[=[typename,?]]
+	{
+		out <- [func]Add Statement[ [[[[dest]Append[[" = make_"]Append[typename]]]Append["("]]Append[source]]Append[")"] ]
+	}{
+		If[[typename]=["Boolean"]]
+		{
+			out <- [func]Add Statement[ [[[[dest]Append[" = make_Bool"]]Append["("]]Append[source]]Append[")"] ]
+		}{
+			out <- [func]Move[psource,pdest]
+		}
+	}
 }
 
 Unbox@JS Function[func,psource,pdest:out]
 {
-	out <- func
+	dest <- [pdest]Make Op[func]
+	source <- [psource]Make Op[func]
+	out <- [func]Add Statement[ [[[dest]Append[" = "]]Append[source]]Append[".unbox()"] ]
 }
 
 Get Raw Pointer@JS Function[func,psource,pdest:out]
@@ -604,17 +624,13 @@
 Get Field Call@JS Function[func,field,source:out]
 {
 	//This will need to change later when I add support for "Field Missing"
-	[func]Escape Pattern >>
-	{
-		esource <- Escape Rhope Name[Make Op[source,func], ~]
-		efield <- Escape Rhope Name[field, ~]
-	}
-	out <- [func]Add Statement[[[["res = "]Append[esource]]Append[".p_"]]Append[efield]]
+	efield <- Escape Rhope Name[field, [func]Escape Pattern >>]
+	out <- [func]Add Statement[[[[["res = ["]Append[Make Op[source,func]]]Append[".p_"]]Append[efield]]Append["]"]]
 }
 
 Set Field Call@JS Function[func,field,object,value:out]
 {
-	out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"],[func]Escape Pattern >>], [[()]Append[object]]Append[value], "Call"]
+	out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"],[func]Escape Pattern >>], [[()]Append[object]]Append[value], "MCall"]
 }
 
 Tail Method Call@JS Function[func,method,args:out]
@@ -667,10 +683,15 @@
 Do If@JS Function[func,condition,stream:out]
 {
 	cond <- [condition]Make Op[func]
-	out <- [Fold[_If JS[?], [[func
-		]Add Raw Line[ [["if("]Append[cond]]Append[")"] ]
-		]Add Raw Line["{"], [stream]Statements >>]
-		]Add Raw Line["}"]
+	If[[[stream]Statements >>]Length]
+	{
+		out <- [Fold[_If JS[?], [[func
+			]Add Raw Line[ [["if("]Append[cond]]Append[")"] ]
+			]Add Raw Line["{"], [stream]Statements >>]
+			]Add Raw Line["}"]
+	}{
+		out <- func
+	}
 }
 
 Discard Outputs@JS Function[func,first to discard:out]
@@ -707,7 +728,7 @@
 {
 	If[[[func]Convention >>] = ["rhope"]]
 	{
-		out <- [["\treturn ["]Append[ [Map[[func]Outputs >>, Escape Rhope Name[?, [func]Escape Pattern >>]]]Join[","] ]]Append["];\n"]
+		out <- [["\treturn ["]Append[ [ Map[Map[[func]Outputs >>, Escape Rhope Name[?, [func]Escape Pattern >>]], ["lv_"]Append[?]] ]Join[","] ]]Append["];\n"]
 	}{
 		[[func]Outputs >>]Index[0]
 		{
@@ -746,17 +767,27 @@
 	If[ [[func]Convention >>] = ["rhope"] ]
 	{
 		
-		before <- [[func]Name >>]Partition["@"] {} {}
+		before,,after <- [[func]Name >>]Partition["@"]
 		{
-			ivars <- Tail[[func]Inputs >>, 1]
-			cname <- [["t_"]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]
-				]Append[[".f_"]Append[Escape Rhope Name[before,[func]Escape Pattern >>]]]
-			[[func]Inputs >>]Index[0]
-			{ move this <- ["\tlv_"]Append[[Escape Rhope Name[~, [func]Escape Pattern >>]]Append[" = this;"]] }
-			{ move this <- "" }
-		}{
+			If[[after]=[""]] 
+			{
+				norm name <- Val[before]
+			} {
+				ivars <- Tail[[func]Inputs >>, 1]
+				cname <- [[["t_"]Append[Escape Rhope Name[after,[func]Escape Pattern >>]]
+					]Append[[".prototype.f_"]Append[Escape Rhope Name[before,[func]Escape Pattern >>]]]
+					]Append[" = function"]
+				[[func]Inputs >>]Index[0]
+				{ move this <- ["\tlv_"]Append[[Escape Rhope Name[~, [func]Escape Pattern >>]]Append[" = this;"]] }
+				{ move this <- "" }
+			}
+		} {} {} {
+			norm name <- Name >>[func]
+		}
+		Val[norm name]
+		{
 			ivars <- [func]Inputs >>
-			fname <- Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]
+			fname <- ["f_"]Append[Escape Rhope Name[norm name,[func]Escape Pattern >>]]
 			move this <- ""
 		}
 		inproc <- Val[Map[?, _Add Prefix[?]]]
@@ -766,16 +797,24 @@
 		move this <- ""
 		inproc <- Val[Val[?]]
 	}
-	cname <- ["var "]Append[fname]
+	cname <- ["function "]Append[fname]
 	param check <- Fold[Check Param Type JS[?, ?, ?, func], "", [func]Input Types >>]
+	
+	allvars <- Concatenate[[func]Outputs >>, Keys[[func]Variables >>]]
+	If[[allvars]Length]
+	{
+		vardec <- [["\tvar "]Append[ [ [inproc]Call[Map[allvars, Escape Rhope Name[?, [func]Escape Pattern >>]]] ]Join[","] ]]Append[";\n"]
+	}{
+		vardec <- ""
+	}
 
 	out <- [[[[[[[[[cname
-		]Append[" = function("]
+		]Append["("]
 		]Append[ [[inproc]Call[Map[ivars, Escape Rhope Name[?, [func]Escape Pattern >>]]]]Join[","] ]
 		]Append[")\n{\n"]
 		]Append[move this]
 		]Append[param check]
-		]Append[ [["\tvar "]Append[ [ [inproc]Call[Concatenate[[func]Outputs >>, Keys[[func]Variables >>]]] ]Join[","] ]]Append[";\n"] ]
+		]Append[vardec]
 		]Append[ [[func]Statements >>]Join[""] ]
 		]Append[[func]Set Outputs]
 		]Append["}"]
@@ -808,6 +847,12 @@
 	out <- ()
 }
 
+Set Stdlib Imports@JS Program[program,parser:out]
+{
+	out <- [parser]Imports <<[ [[parser]Imports >>]Set["kerneljs.rhope", Yes] ]
+}
+
+
 Link@JS Program[program,language,library:out]
 {
 	If[[library] = ["runtime"]]
@@ -1018,6 +1063,11 @@
 var TYPE_WORKER = i++;
 var TYPE_FIRST_USER = i;
 
+Object.prototype.unbox = function()
+{
+	return this;	
+}
+
 registered_types = new Array();
 
 function t_Blueprint()
@@ -1032,29 +1082,49 @@
 registered_types[TYPE_BLUEPRINT] = t;\n\n"
 		]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
 		]Append["
+		
+t_Int32.prototype.unbox = function()
+{
+	return this.p_Num;
+}
+
+t_UInt32.prototype.unbox = function()
+{
+	return this.p_Num;
+}
+
+t_UInt8.prototype.unbox = function()
+{
+	return this.p_Num;
+}
+
+t_Boolean.prototype.unbox = function()
+{
+	return this.p_Val;
+}
 
 function make_Int32(val)
 {
 	var out = new t_Int32;
-	out.p_Val = val;
+	out.p_Num = val;
 	return out;
 }
 
 function make_UInt8(val)
 {
 	var out = new t_UInt8;
-	out.p_Val = val & 255;
+	out.p_Num = val & 255;
 	return out;
 }
 
 function make_UInt32(val)
 {
 	var out = new t_UInt32;
-	out.p_Val = val;
+	out.p_Num = val;
 	return out;
 }
 
-function make_Boolean(val)
+function make_Bool(val)
 {
 	var out = new t_Boolean;
 	out.p_Val = val;
@@ -1064,7 +1134,14 @@
 function make_Float64(val)
 {
 	var out = new t_Float64;
-	out.p_Val = val;
+	out.p_Num = val;
+	return out;
+}
+
+function make_String(string)
+{
+	var out = new t_String;
+	out.p_Buffer = string;
 	return out;
 }
 
@@ -1085,6 +1162,40 @@
 	throw new Error(\"Conversion needed\");
 }
 
+function copy_object(obj)
+{
+	if (obj.type_id == TYPE_ARRAY) {
+		return obj.slice(0);
+	}
+	var dest = new registered_types[obj.type_id].construct;
+	for (var prop in obj) {
+		if (obj.hasOwnProperty(prop)) {
+			dest[prop] = obj[prop];
+		}
+	}
+	return dest;
+}
+
+function _internal_js_length(arr)
+{
+	return arr.length;
+}
+
+function _internal_js_eq(left,right)
+{
+	return left == right;
+}
+
+function _internal_array_set(arr,index,val)
+{
+	arr[index] = val;
+}
+
+function _internal_array_get(arr,index)
+{
+	return arr[index]
+}
+
 function f_Build(type)
 {
 	type = check_type(type, TYPE_BLUEPRINT);
@@ -1105,8 +1216,8 @@
 function f_BlueprintSP_FromSP_ID(id)
 {
 	id = check_type(id, TYPE_UINT32);
-	if (id.p_Val > 0 && registered_types[id.p_Val] != null) {
-		return [registered_types[id.p_Val], null];
+	if (id.p_Num > 0 && registered_types[id.p_Num] != null) {
+		return [registered_types[id.p_Num], null];
 	} else {
 		return [null,id];
 	}
@@ -1115,11 +1226,19 @@
 		]Append[Fold[_Set Consts JS Program[?, ?, ?, [program]Type Registry >>], "", constants]]
 		]Append[Fold[_Set Late Consts JS[?, ?, ?, [program]Type Registry >>], "", constants]]
 		]Append["
-var args = f_List()[0];
-for (var i in arguments) {
-	args = args.f_Append(make_String(arguments[i]))[0];
+try {
+	var args = f_List()[0];
+	for (var i in arguments) {
+		args = args.f_Append(make_String(arguments[i]))[0];
+	}
+	res = f_Main(args);
+} catch(e) {
+	res = f_Main();
 }
-f_Main(args);"]
+if (res[0] != null && res[0].type_id == TYPE_INT32) {
+	print(res[0].p_Num);
+}
+"]
 
 }
 
--- a/kernel.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/kernel.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -1,3 +1,4 @@
+Import kernelbase.rhope
 Import array.rhope
 Import string.rhope
 Import list.rhope
@@ -6,11 +7,6 @@
 Import dict.rhope
 Import range.rhope
 
-Val[in:out]
-{
-	out <- in
-}
-
 Blueprint Boolean
 {
 	Val(Int32,Naked)
@@ -39,27 +35,12 @@
 	yes,no <- If[[num]!=[0i64]]
 }
 
-Blueprint Int32
-{
-	Num(Int32,Naked)
-}
-
-If@Int32[num:yes,no]
-{
-	yes,no <- If[[num]!=[0i32]]
-}
-
 Foreign C:libc
 {
 	write[filedes(Int32,Naked),buf(Array,Raw Pointer),nbyte(Int64,Naked):written(Int32,Naked)]
 	read[filedes(Int32,Naked),buf(Array,Raw Pointer,Mutable),nbyte(Int64,Naked):read(Int64,Naked),buf]
 }
 
-Trunc UInt8@UInt8[in:out]
-{
-	out <- in
-}
-
 __String Int[n,buf,ten:out]
 {
 	If[[n] < [ten]]
@@ -168,16 +149,6 @@
 	yes,no <- If[[num]!=[0u64]]
 }
 
-Blueprint UInt32
-{
-	Num(UInt32,Naked)
-}
-
-If@UInt32[num:yes,no]
-{
-	yes,no <- If[[num]!=[0u32]]
-}
-
 Blueprint UInt16
 {
 	Num(UInt16,Naked)
@@ -188,16 +159,6 @@
 	yes,no <- If[[num]!=[0u16]]
 }
 
-Blueprint UInt8
-{
-	Num(UInt8,Naked)
-}
-
-If@UInt8[num:yes,no]
-{
-	yes,no <- If[[num]!=[0u8]]
-}
-
 Abs@Int64[num:out]
 {
 	If[[num]<[0i64]]
@@ -205,13 +166,6 @@
 	{ out <- num }
 }
 
-Abs@Int32[num:out]
-{
-	If[[num]<[0i32]]
-	{ out <- [0i32]-[num] }
-	{ out <- num }
-}
-
 Abs@Int16[num:out]
 {
 	If[[num]<[0i16]]
@@ -226,11 +180,6 @@
 	{ out <- num }
 }
 
-Mod[a,b:out]
-{
-	out <- [a]-[[[a]/[b]]*[b]]
-}
-
 Foreign C:runtime
 {
 	_internal_blueprint_eq[left(Blueprint),right(Blueprint):out(Int32,Naked)]
@@ -299,42 +248,6 @@
 	out <- [_internal_blueprint_eq[left,right]]!=[0]
 }
 
-And[left,right:out]
-{
-	,out <- If[left]
-	{
-		out,out <- If[right]
-	}
-}
-
-Or[left,right:out]
-{
-	out <- If[left] {}
-	{
-		out <- right
-	}
-}
-
-Min[a,b:out]
-{
-	If[[a]<[b]]
-	{
-		out <- a
-	}{
-		out <- b
-	}
-}
-
-Max[a,b:out]
-{
-	If[[a]>[b]]
-	{
-		out <- a
-	}{
-		out <- b
-	}
-}
-
 _Keys[list,val,key:out]
 {
 	out <- [list]Append[key]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernelbase.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -0,0 +1,89 @@
+
+Val[in:out]
+{
+	out <- in
+}
+
+Blueprint Int32
+{
+	Num(Int32,Naked)
+}
+
+If@Int32[num:yes,no]
+{
+	yes,no <- If[[num]!=[0i32]]
+}
+
+Trunc UInt8@UInt8[in:out]
+{
+	out <- in
+}
+
+Blueprint UInt32
+{
+	Num(UInt32,Naked)
+}
+
+If@UInt32[num:yes,no]
+{
+	yes,no <- If[[num]!=[0u32]]
+}
+
+Blueprint UInt8
+{
+	Num(UInt8,Naked)
+}
+
+If@UInt8[num:yes,no]
+{
+	yes,no <- If[[num]!=[0u8]]
+}
+
+Abs@Int32[num:out]
+{
+	If[[num]<[0i32]]
+	{ out <- [0i32]-[num] }
+	{ out <- num }
+}
+
+Mod[a,b:out]
+{
+	out <- [a]-[[[a]/[b]]*[b]]
+}
+
+And[left,right:out]
+{
+	,out <- If[left]
+	{
+		out,out <- If[right]
+	}
+}
+
+Or[left,right:out]
+{
+	out <- If[left] {}
+	{
+		out <- right
+	}
+}
+
+Min[a,b:out]
+{
+	If[[a]<[b]]
+	{
+		out <- a
+	}{
+		out <- b
+	}
+}
+
+Max[a,b:out]
+{
+	If[[a]>[b]]
+	{
+		out <- a
+	}{
+		out <- b
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneljs.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -0,0 +1,10 @@
+Import kernelbase.rhope
+Import arrayjs.rhope
+Import stringjs.rhope
+
+Blueprint Boolean
+{
+	Val(Boolean,Naked)
+}
+
+
--- a/number_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/number_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -81,6 +81,13 @@
 	out <- [backend]Store Function[ffunc]
 }
 
+Supports Type?[backend,type:out]
+{
+	[[backend]Supported Number Types]Find[=[type,?]]
+	{ out <- Yes }
+	{ out <- No }
+}
+
 _Generate Number Methods[backend, type:out]
 {
 	//Old crappy parser doesn't like Worker literals in List literals, work around for now
@@ -105,9 +112,9 @@
 	
 	Fold[Compile Number Method[?, ?, type], backend, opmap]
 	{ Fold[Compile Number Comp Method[?, ?, type], ~, compops]
-	{ Fold[Compile Conversion Method[?, type, ?, ""], ~, Legal Conversions[type]]
+	{ Fold[Compile Conversion Method[?, type, ?, ""], ~, Filter[Legal Conversions[type], [backend]Supports Type?[?]]]
 	{ 
-		almost <- Fold[Compile Conversion Method[?, type, ?, "Trunc "], ~, Truncations[type]] 
+		almost <- Fold[Compile Conversion Method[?, type, ?, "Trunc "], ~, Filter[Truncations[type], [backend]Supports Type?[?]]]
 		If[[type]Starts With["I"]]
 		{
 			out <- Compile Abs UInt Method[almost,type]
@@ -203,7 +210,6 @@
 
 Register Number Methods[program:out]
 {
-	numtypes <- ("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")
-	out <- Fold[_Register Number Methods[?], program, numtypes]
+	out <- Fold[_Register Number Methods[?], program, [program]Supported Number Types]
 }
 
--- a/nworker_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/nworker_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -1449,22 +1449,37 @@
 	Blueprints
 	Workers
 	Worker Refs
+	Numtypes
 }
 
 NProgram[:out]
 {
-	out <- [[[Build[NProgram()]]Blueprints <<[Dictionary[]]]Workers <<[Dictionary[]]]Worker Refs <<[Dictionary[]]
+	out <- [[[[Build[NProgram()]
+		]Blueprints <<[Dictionary[]]
+		]Workers <<[Dictionary[]]
+		]Worker Refs <<[Dictionary[]]
+		]Numtypes << [("Int8","Int16","Int32","Int64","UInt8","UInt16","UInt32","UInt64")]
+}
+
+Supported Number Types@NProgram[program:out]
+{
+	out <- [program]Numtypes >>
 }
 
 Bind Worker@NProgram[prog,name,worker:out]
 {	
 	after bind <- [prog]Workers << [ [[prog]Workers >>]Set[name, [worker]Name <<[name]] ]
 	parts <- [name]Split["@"]
-	[parts]Index[1]
+	bpname <- [parts]Index[1]
 	{
-		orig bp <- [[after bind]Blueprints >>]Index[~] {}
-		{ orig bp <- NBlueprint[] }
-		out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[~, [orig bp]Add Method[[parts]Index[0]] ] ]
+		If[[~]=[""]]
+		{
+			out <- Val[after bind]
+		}{
+			orig bp <- [[after bind]Blueprints >>]Index[bpname] {}
+			{ orig bp <- NBlueprint[] }
+			out <- [after bind]Blueprints <<[ [[after bind]Blueprints >>]Set[bpname, [orig bp]Add Method[[parts]Index[0]] ] ]
+		}
 	}{
 		out <- Val[after bind]
 	}
@@ -1529,7 +1544,12 @@
 	parts <- [name]Split["@"]
 	[parts]Index[1]
 	{
-		out <- [after reg]Register Method@NProgram[[parts]Index[0], convention, inputs, outputs]
+		If[[~]=[""]]
+		{
+			out <- [after reg]Register Worker[[parts]Index[0], convention, inputs, outputs]
+		}{
+			out <- [after reg]Register Method@NProgram[[parts]Index[0], convention, inputs, outputs]
+		}
 	}{
 		out <- Val[after reg]
 	}
--- a/parser_old_c.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/parser_old_c.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -31,7 +31,6 @@
 	List End
 	List Delim
 	In Out Delim
-	Do Worker
 	Index Begin
 	Index End
 	Previous
@@ -49,7 +48,7 @@
 
 Parser[:out]
 {
-	out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build[Parser()]
+	out <- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Build[Parser()]
 	]Arg Begin << ["["]
 	]Arg End <<["]"]
 	]Line Comment <<["//"]
@@ -68,7 +67,6 @@
 	]List End <<[")"]
 	]List Delim <<[","]
 	]In Out Delim <<[":"]
-	]Do Worker <<["$"]
 	]Index Begin <<["("]
 	]Index End <<[")"]
 	]Previous <<["@"]
@@ -138,7 +136,7 @@
 {
 	out <- [[[[Build[Parse Program()]
 	]Workers <<[Dictionary[]]
-	]Imports <<[[Dictionary[]]Set["kernel.rhope", Yes]]
+	]Imports <<[Dictionary[]]
 	]Blueprints <<[Dictionary[]]
 	]Errors <<[()]
 }
@@ -1483,9 +1481,9 @@
 	out <- [prog]Bind Blueprint[[def]Name >>, Fold[Add Blueprint Field[?], NBlueprint[], [def]Fields >>]]
 }
 
-Tree to Program Native[parse tree:out]
+Tree to Program Native[parse tree,number types:out]
 {
-	registered <- Fold[Register Workers Compile[?], [Fold[Add Blueprint Compile[?], NProgram[], [parse tree]Blueprints >>]]Register Builtins, [parse tree]Workers >>]
+	registered <- Fold[Register Workers Compile[?], [Fold[Add Blueprint Compile[?], [NProgram[]]Numtypes <<[number types], [parse tree]Blueprints >>]]Register Builtins, [parse tree]Workers >>]
 	out <- Fold[Add Workers Compile[?], registered, [parse tree]Workers >>]
 	{ Print["Transformed AST to dataflow graph "] }
 }
--- a/string.rhope	Sun Nov 14 03:09:49 2010 -0500
+++ b/string.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -94,6 +94,11 @@
 	out <- [[Build[String()]]Buffer <<[in]]Length <<[len]
 }
 
+String@Empty Array[in:out(String)]
+{
+	out <- ""
+}
+
 Print@String[string:out]
 {	
 	//TODO: Sanitize string (remove terminal escapes and replace invalid UTF)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stringjs.rhope	Sun Nov 14 23:07:55 2010 -0500
@@ -0,0 +1,318 @@
+
+
+Blueprint String
+{
+	Buffer
+}
+
+Foreign Javascript:builtin
+{
+	print[val]
+	parseInt[string,base(Int32,Naked):out(Int32,Naked)]
+	_internal_js_eq[left,right:out(Boolean,Naked)]
+	slice@[string,start(Int32,Naked),end(Int32,Naked):out]
+	concat@[left,right:out]
+}
+
+Print@String[string:out]
+{	
+	print[[string]Buffer >>]
+	out <- Yes
+}
+
+Int32@String[string:out]
+{
+	out <- parseInt[[string]Buffer >>, 10]
+}
+
+Hex Int32[str:out]
+{
+	out <- parseInt[[str]Buffer >>, 16]
+}
+
+Flatten@String[string:out]
+{
+	out <- string
+}
+
+Slice@String[string,slicepoint:left,right]
+{
+	If[[slicepoint]>=[[string]Length]]
+	{
+		left <- string
+		right <- ""
+	}{
+		If[[slicepoint]<=[0]]
+		{
+			left <- ""
+			right <- string
+		}{
+			[string]Buffer >>
+			{
+				left <- [Build[String()]]Buffer <<[[~]slice[0,slicepoint]]
+				right <- [Build[String()]]Buffer <<[[~]slice[slicepoint,_internal_js_length[~]]]
+			}
+		}
+	}
+}
+/*
+Byte@String[string,index:out,invalid]
+{
+	out,invalid <- [[string]Buffer >>]Index[index]
+}
+*/
+Length@String[string:out]
+{
+	out <- _internal_js_length[[string]Buffer >>]
+}
+
+Append@String[left,right(String):out]
+{
+	out <- [Build[String()]]Buffer <<[[[left]Buffer >>]concat[[right]Buffer >>]]
+}
+
+=@String[left,right(String):out]
+{
+	out <- [[left]Buffer >>]_internal_js_eq[[right]Buffer >>]
+}
+
+/*
+=Delim[string,delims,index:outindex,after,nomatch]
+{
+	delim <- [delims]Index[index]
+	If[[[string]Length]<[[delim]Length]]
+	{
+		try next <- Yes
+	}{
+		check,mafter <- [string]Slice[[delim]Length]
+		,try next <- If[[check]=[delim]]
+		{
+			outindex <- index
+			after <- Val[mafter]
+		}
+	}
+	Val[try next]
+	{
+		,nomatch <- [delims]Next[index]
+		{
+			outindex,after,nomatch <- =Delim[string,delims,~]
+		}
+	}
+}
+
+Pattern@String[string:out]
+{
+	out <- string
+}
+
+Match@String[string,cmp:num,no match,idx]
+{
+	n <- [string]Length
+	,no match <- If[[string]=[[cmp]Slice[n]]]
+	{
+		num <- Val[n]
+		idx <- 0
+	}
+}
+
+_Partition[string,delims:matched,after,not found]
+{
+	not found <- If[[string]=[""]] {}
+	{
+		[delims]Match[string]
+		{
+			matched,after <- [string]Slice[~]
+		}{
+			[string]Slice[1] {}
+			{ matched,after,not found <- _Partition[~,delims] }
+		}
+	}
+}
+
+Partition[string,delims:before,matched,after,not found]
+{
+	matched,after,not found <- _Partition[string,Pattern[delims]]
+	{ dlen <- Length[~] }
+	{ alen <- Length[~] }
+	before <- [string]Slice[ [[string]Length]-[[dlen]+[alen]] ]
+}
+
+
+Dict Type ID@String[string:out]
+{
+	out <- ID[String()]
+}
+
+Dict Bits@String[string,index:out,invalid]
+{
+	,invalid <- [string]Byte[index]
+	{ out <- UInt32[~] }
+}
+
+_From Dict String[arr,el:out]
+{
+	out <- [arr]Append[Trunc UInt8[el]]
+}
+
+From Dict Key@String[string,data:out]
+{
+	out <- String[Fold[_From Dict String[?], Array[], data]]
+}
+*/
+
+String@String[string:out]
+{
+	out <- string
+}
+
+/*
+Replace[string,otoreplace,with:out]
+{
+	toreplace <- Pattern[otoreplace]
+	,delim,after <-[string]Partition[toreplace]
+	{
+		wt <- Blueprint Of[with]
+		If[ [[[wt]=[String()]] Or [[wt]=[String Slice()]]] Or [[wt]=[String Cat()]] ]
+		{
+			replacement <- with
+		}{
+			,,idx <- [toreplace]Match[delim]
+			replacement <- [with]Index[idx]
+		}
+		out <- [[~]Append[replacement]]Append[Replace[after,toreplace,with]]
+	} {} {} {
+		out <- string
+	}
+}
+
+_Join[list,delim,current,index:out]
+{
+	[list]Next[index]
+	{
+		out <- _Join[list, delim, [[current]Append[delim]]Append[String[[list]Index[~]]], ~]
+	}{
+		out <- current
+	}
+}
+
+Join[list,delim:out]
+{
+	[list]First
+	{
+		out <- _Join[list, delim, String[[list]Index[~]], ~]
+	}{
+		out <- ""
+	}
+}
+
+*/
+
+Starts With[thing,starts with:out]
+{
+	out <- [[thing]Slice[[starts with]Length]] = [starts with]
+}
+
+Ends With[thing,ends with:out]
+{
+	,compare <- [thing]Slice[ [[thing]Length] - [[ends with]Length] ]
+	out <- [compare] = [ends with]
+}
+
+If@String[str:yes,no]
+{
+	yes,no <- If[[str]Length]
+}
+
+/*
+_Split[list,string,delim:out]
+{
+	,,rest <- [string]Partition[delim]
+	{
+		out <- _Split[[list]Append[~], rest, delim]
+	} {} {} {
+		out <- [list]Append[string]
+	}
+}
+
+Split[string,delim:out]
+{
+	If[string]
+	{ out <- _Split[(),string,delim] }
+	{ out <- () }
+}
+*/
+
+In[needle,haystack:out]
+{
+	If[haystack]
+	{
+		out <- If[[[haystack]Slice[Length[needle]]]=[needle]] {}
+		{
+			[haystack]Slice[1] {}
+			{ out <- [needle]In[~] }
+		}
+	}{
+		out <- No
+	}
+}
+
+Left Trim[string,trim:trimmed]
+{
+	If[ [[string]Length] > [0] ]
+	{
+		first,rest <- [string]Slice[1]
+		If[ [first]In[trim] ]
+		{
+			trimmed <- Left Trim[rest, trim]
+		}{
+			trimmed <- string
+		}
+	}{
+		trimmed <- string
+	}
+}
+
+Right Trim[string,trim:trimmed]
+{
+	If[ [[string]Length] > [0] ]
+	{
+		rest,last <- [string]Slice[ [[string]Length] - [1]]
+		If[ [last]In[trim] ]
+		{
+			trimmed <- Right Trim[rest, trim]
+		}{
+			trimmed <- string
+		}
+	}{
+		trimmed <- string
+	}
+}
+
+Trim[string,trim:trimmed]
+{
+	left <- Left Trim[string, trim]
+	trimmed <- Right Trim[left, trim]
+}
+
+/*
+Contains[haystack,needle:out]
+{
+	[haystack]Partition[needle]
+	{
+		out <- Yes	
+	} {} {} {
+		out <- No
+	}
+}
+*/
+
+After[text,prefix:after,not found]
+{
+	If[[text]Starts With[prefix]]
+	{
+		,after <- [text]Slice[[prefix]Length]
+	}{
+		not found <- text
+	}
+}
+