changeset 52:079200bc3e75

String literals almost working. Print moved out of C runtime.
author Mike Pavone <pavone@retrodev.com>
date Wed, 28 Apr 2010 01:23:30 -0400
parents 7d6a6906b648
children 70af7fa155d0
files cbackend.rhope kernel.rhope number.rhope parser_old.rhope runtime/builtin.c runtime/context.c runtime/context.h string.rhope
diffstat 8 files changed, 95 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.rhope	Thu Apr 22 02:18:26 2010 -0400
+++ b/cbackend.rhope	Wed Apr 28 01:23:30 2010 -0400
@@ -1084,6 +1084,11 @@
 					
 					make <- [[[" = make_"]Append[s]]Append["nt"]]Append[[value]Size >>]
 					out <- [text]Append[ [[[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[make]]Append["("]]Append[[value]Value >>]]Append[");\n"] ]
+				}{
+					If[[valtype] = ["String"]]
+					{
+						out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name]]]Append[" = make_String(\""]]Append[ [[value]Replace["\n", "\\n"]]Replace["\\", "\\\\"]]]Append["\");\n"] ]
+					}
 				}
 			}
 		}
--- a/kernel.rhope	Thu Apr 22 02:18:26 2010 -0400
+++ b/kernel.rhope	Wed Apr 28 01:23:30 2010 -0400
@@ -35,6 +35,39 @@
 	yes,no <- If[[num]!=[0i32]]
 }
 
+Foreign C:libc
+{
+	write[filedes(Int32,Naked),buf(Array,Raw Pointer),nbyte(Int64,Naked):written(Int32,Naked)]
+}
+
+_Print Int32[n,buf:out]
+{
+	If[[n] < [10i32]]
+	{
+		byte <- [[n]Trunc Int8] + [48i8]
+		out <- [buf]Append[byte]
+	}{
+		next <- [n]/[10i32]
+		
+		byte <- [[[n]-[[next]*[10i32]]]Trunc Int8] + [48i8]
+		out <- [_Print Int32[next, buf]]Append[byte]
+	}
+}
+
+Print@Int32[n:out]
+{
+	If[[n] < [0i32]]
+	{
+		val <- [0i32]-[n]
+		buf <- [Array[1]]Append[45i8]
+	}{
+		val <- Val[n]
+		buf <- Array[1]
+	}
+	fbuf <- [_Print Int32[val, buf]]Append[10i8]
+	out <- write[1i32, fbuf, Int64[[fbuf]Length >>]]
+}
+
 Blueprint Int16
 {
 	Num(Int16,Naked)
--- a/number.rhope	Thu Apr 22 02:18:26 2010 -0400
+++ b/number.rhope	Wed Apr 28 01:23:30 2010 -0400
@@ -84,7 +84,7 @@
 	Fold[["Compile Number Method"]Set Input[2, type], backend, opmap]
 	{ Fold[["Compile Number Comp Method"]Set Input[2, type], ~, compops]
 	{ Fold[[["Compile Conversion Method"]Set Input[1, type]]Set Input[3, ""], ~, Legal Conversions[type]]
-	{ out <- Fold[[["Compile Conversion Method"]Set Input[1, type]]Set Input[3, "Trunc "], ~, Legal Conversions[type]] }}}
+	{ out <- Fold[[["Compile Conversion Method"]Set Input[1, type]]Set Input[3, "Trunc "], ~, Truncations[type]] }}}
 }
 		
 Generate Number Methods[backend:out]
@@ -156,7 +156,7 @@
 	Fold[[register]Set Input[3, type], program, methods]
 	{ Fold[[register]Set Input[3, "Boolean"], ~, compmethods]
  	{ Fold[[["Register Conversion Method"]Set Input[1, type]]Set Input[3, ""], ~, Legal Conversions[type]]
-	{ out <- Fold[[["Register Conversion Method"]Set Input[1, type]]Set Input[3, "Trunc ", ~, Truncations[type]]  }}}
+	{ out <- Fold[[["Register Conversion Method"]Set Input[1, type]]Set Input[3, "Trunc "], ~, Truncations[type]]  }}}
 }
 
 Register Number Methods[program:out]
--- a/parser_old.rhope	Thu Apr 22 02:18:26 2010 -0400
+++ b/parser_old.rhope	Wed Apr 28 01:23:30 2010 -0400
@@ -127,7 +127,7 @@
 {
 	out <- [[[Build["Parse Program"]
 	]Workers <<[Dictionary[]]
-	]Imports <<[[Dictionary[]]Set["kernel.rhope", Yes]]
+	]Imports <<[[[Dictionary[]]Set["kernel.rhope", Yes]]Set["string.rhope", Yes]]
 	]Blueprints <<[Dictionary[]]
 }
 
--- a/runtime/builtin.c	Thu Apr 22 02:18:26 2010 -0400
+++ b/runtime/builtin.c	Wed Apr 28 01:23:30 2010 -0400
@@ -3,7 +3,8 @@
 #include "integer.h"
 #include "bool.h"
 #include <stddef.h>
-#include <stdio.h>
+#include <stdio.h>
+#include <string.h>
 
 void register_builtin_type(uint32_t type)
 {
@@ -21,22 +22,7 @@
 	uint32_t i;
 	for(i = 0; i < TYPE_FIRST_USER; ++i)
 		register_builtin_type(i);
-}
-
-//TODO: Remove this when it's possible to write Print in Rhope
-FuncNoLocals(Print,
-	NumParams 1,
-	CallSpace 0)
-	
-	if(get_blueprint(cdata->params[0]) == get_blueprint_byid(TYPE_INT32))
-	{
-		printf("%d\n", ((t_Int32 *)(cdata->params[0]))->Num);
-	} else {
-		puts("Don't know how to print this type");
-	}
-	release_ref(cdata->params[0]);
-	Ret(0, make_Int32(0))
-EndFunc
+}
 
 object * make_Int64(int64_t val)
 {
@@ -111,6 +97,35 @@
 	return ret;
 }
 
+object * make_String(char * text)
+{
+	returntype ret;
+	context * ct;
+	calldata * cdata;
+	object * retobj;
+	t_Array * arr = (t_Array *)_internal_array_allocnaked(strlen(text), make_Blueprint(TYPE_UINT8));
+	arr->payload.Length = arr->payload.Storage;
+	memcpy(((char *)arr) + sizeof(t_Array), text, arr->payload.Length);
+	
+	//This is really ugly, but I don't see a good way around it at the moment
+	ct = new_context();
+	cdata = alloc_cdata(ct, 1);
+	cdata->params[0] = (object *)arr;
+	cdata->num_params = 1;
+	cdata->resume = 0;
+	ret = f_String(cdata);
+	while(ret == TAIL_RETURN)
+		ret = cdata->tail_func(cdata);
+	if(ret == EXCEPTION_RETURN)
+	{
+		puts("Exception while building string literal!");
+		exit(-1);
+	}
+	retobj = cdata->params[0];
+	free_context(ct);
+	return retobj;
+}
+
 #define lval ((t_Boolean *)(cdata->params[0]))->Val
 
 MethodNoLocals(If,Boolean,
--- a/runtime/context.c	Thu Apr 22 02:18:26 2010 -0400
+++ b/runtime/context.c	Wed Apr 28 01:23:30 2010 -0400
@@ -20,6 +20,18 @@
 	c->current_stack = c->stack_begin;
 	c->unwind = NULL;
 	return c;
+}
+
+void free_context(context * c)
+{
+	stackchunk *next,*current = c->stack_begin;
+	while(current)
+	{
+		next = current->next;
+		free(current);
+		current = next;
+	}
+	free(c);
 }
 
 void * alloc_stack(context * ct, uint32_t size)
--- a/runtime/context.h	Thu Apr 22 02:18:26 2010 -0400
+++ b/runtime/context.h	Wed Apr 28 01:23:30 2010 -0400
@@ -29,5 +29,6 @@
 context * new_context();
 void * alloc_stack(context * ct, uint32_t size);
 struct calldata * alloc_cdata(context * ct, uint32_t num_params);
-void free_stack(context * ct, void * data);
+void free_stack(context * ct, void * data);
+void free_context(context * c);
 #endif //_CONTEXT_H_
--- a/string.rhope	Thu Apr 22 02:18:26 2010 -0400
+++ b/string.rhope	Wed Apr 28 01:23:30 2010 -0400
@@ -19,6 +19,13 @@
 	Length(Int32,Naked)
 }
 
+Print@Base String[string:out]
+{	
+	//TODO: Sanitize string (remove terminal escapes and replace invalid UTF)
+	write[1i32, [string]Buffer >>, Int64[[[string]Buffer >>]Length >>]]
+	{ out <- write[1i32, [Array[1]]Append[10u8], 1i64] }
+}
+
 UTF8 Expect[num,arr,index,count,consumed:out]
 {
 	byte <- [arr]Index[index]
@@ -113,22 +120,5 @@
 	out <- [[Build[Base String()]]Buffer <<[in]]Length <<[Count UTF8[in, 0, 0]]
 }
 
-Main[]
-{
-	text <- [[[[[[[[[[[[[Array[1]
-		]Append[36u8]
-		]Append[194u8]
-		]Append[162u8]
-		]Append[236u8]
-		]Append[130u8]
-		]Append[172u8]
-		]Append[240u8]
-		]Append[164u8]
-		]Append[173u8]
-		]Append[162u8]
-		]Append[194u8]
-		]Append[36u8]
-		]Append[162u8]
-	Print[Count UTF8[text, 0, 0]]
-}
 
+