changeset 294:d1dc2d70bdfd

Move OS module out of backend Javascript into a proper module file. Add normal bytearray to bytearray module. Add read:to method to os module for reading into a bytearray.
author Michael Pavone <pavone@retrodev.com>
date Thu, 24 Jul 2014 21:58:26 -0700
parents 2b045d5b673b
children 9a30510f6e52
files cbackend.js ilbackend.js modules/bytearray.tp modules/os.tp samples/osmod.tp
diffstat 5 files changed, 207 insertions(+), 305 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Thu Jul 24 09:43:18 2014 -0700
+++ b/cbackend.js	Thu Jul 24 21:58:26 2014 -0700
@@ -964,157 +964,6 @@
 	        makeFloat(32), makeFloat(64), makeArray(), makeString(), makelambda(), makeCPointer()];
 }
 
-function addBuiltinModules(toplevel)
-{
-	var os = new cObject('mod_obj_os');
-	os.addInclude('<sys/stat.h>');
-	os.addInclude('<fcntl.h>');
-	os.addInclude('<stdlib.h>');
-	os.addInclude('<time.h>');
-	os.addInclude('<unistd.h>');
-	os.addMessage('write', {
-		vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'str = va_arg(args, string *);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = write(filedes->num, str->data, str->bytes);',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('read', {
-		vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'size = va_arg(args, obj_int32 *);',
-			'str = (string *)make_object(&string_meta, NULL, 0);',
-			'str->data = GC_MALLOC_ATOMIC(size->num + 1);',
-			'str->len = str->bytes = read(filedes->num, str->data, size->num);',
-			'if (str->bytes < 0) { str->bytes = str->len = 0; }',
-			'str->data[str->bytes] = 0;',
-			'return &(str->header);'
-		]
-	});
-	os.addMessage('open', {
-		vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *', perm: 'obj_int32 *'},
-		lines: [
-			'str = va_arg(args, string *);',
-			'flags = va_arg(args, obj_int32 *);',
-			'filedes = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'if (num_params == 3) {',
-			'	filedes->num = open(str->data, flags->num);',
-			'} else if (num_params == 4) {',
-			'	perm = va_arg(args, obj_int32 *);',
-			'	filedes->num = open(str->data, flags->num, perm->num);',
-			'} else {',
-			'	filedes->num = -1;',
-			'}',
-			'return &(filedes->header);'
-		]
-	});
-	os.addMessage('close', {
-		vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = close(filedes->num);',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_RDONLY', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_RDONLY;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_WRONLY', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_WRONLY;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_RDWR', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_RDWR;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_CREAT', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_CREAT;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_APPEND', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_APPEND;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_TRUNC', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_TRUNC;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('rand', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = rand();',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('rand64', {
-		vars: {intret64: 'obj_int64 *'},
-		lines: [
-			'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);',
-			'intret64->num = (((int64_t)rand()) << 32 ) | rand();',
-			'return &(intret64->header);'
-		]
-	});
-	os.addMessage('srand', {
-		vars: {oseed: 'object *', seed: 'obj_int32 *'},
-		lines: [
-			'oseed = va_arg(args, object *);',
-			'seed = mcall(' + getMethodId("int32") + ', 1, oseed);',
-			'srand(seed->num);',
-			'return &(seed->header);'
-		]
-	});
-	os.addMessage('time', {
-		vars: {intret64: 'obj_int64 *'},
-		lines: [
-			'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);',
-			'intret64->num = time(NULL);',
-			'return &(intret64->header);'
-		]
-	});
-	os.addMessage('sleep', {
-		vars: {osecs: 'object *', secs: 'obj_int32 *', intret: 'obj_int32 *'},
-		lines: [
-			'osecs = va_arg(args, object *);',
-			'secs = mcall(' + getMethodId("int32") + ', 1, osecs);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = sleep(secs->num);',
-			'return &(intret->header);'
-		]
-	});
-	toplevel.names['os'] = os;
-}
-
 modulefile.prototype.toC = function(){
 	return this.ast.toCModuleInstance();
 };
@@ -1177,7 +1026,6 @@
 		forwarddec += builtins[i].toEarlyCDef();
 		toplevelcode += builtins[i].toCDef();
 	}
-	addBuiltinModules(toplevel);
 	debugprint('//------POPULATING SYMBOLS-----');
 	obj.populateSymbols(toplevel);
 	var moduleinit = processUsedToplevel(toplevel);
--- a/ilbackend.js	Thu Jul 24 09:43:18 2014 -0700
+++ b/ilbackend.js	Thu Jul 24 21:58:26 2014 -0700
@@ -973,157 +973,6 @@
 	        makeArray(), makeString(), makelambda()];
 }
 
-function addBuiltinModules(toplevel)
-{
-	var os = new cObject('mod_obj_os');
-	os.addInclude('<sys/stat.h>');
-	os.addInclude('<fcntl.h>');
-	os.addInclude('<stdlib.h>');
-	os.addInclude('<time.h>');
-	os.addInclude('<unistd.h>');
-	os.addMessage('write', {
-		vars: {str: 'string *', intret: 'obj_int32 *', filedes: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'str = va_arg(args, string *);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = write(filedes->num, str->data, str->bytes);',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('read', {
-		vars: {str: 'string *', size: 'obj_int32 *', filedes: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'size = va_arg(args, obj_int32 *);',
-			'str = (string *)make_object(&string_meta, NULL, 0);',
-			'str->data = GC_MALLOC_ATOMIC(size->num + 1);',
-			'str->len = str->bytes = read(filedes->num, str->data, size->num);',
-			'if (str->bytes < 0) { str->bytes = str->len = 0; }',
-			'str->data[str->bytes] = 0;',
-			'return &(str->header);'
-		]
-	});
-	os.addMessage('open', {
-		vars: {str: 'string *', flags: 'obj_int32 *', filedes: 'obj_int32 *', perm: 'obj_int32 *'},
-		lines: [
-			'str = va_arg(args, string *);',
-			'flags = va_arg(args, obj_int32 *);',
-			'filedes = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'if (num_params == 3) {',
-			'	filedes->num = open(str->data, flags->num);',
-			'} else if (num_params == 4) {',
-			'	perm = va_arg(args, obj_int32 *);',
-			'	filedes->num = open(str->data, flags->num, perm->num);',
-			'} else {',
-			'	filedes->num = -1;',
-			'}',
-			'return &(filedes->header);'
-		]
-	});
-	os.addMessage('close', {
-		vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'},
-		lines: [
-			'filedes = va_arg(args, obj_int32 *);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = close(filedes->num);',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_RDONLY', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_RDONLY;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_WRONLY', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_WRONLY;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_RDWR', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_RDWR;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_CREAT', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_CREAT;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_APPEND', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_APPEND;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('O_TRUNC', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = O_TRUNC;',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('rand', {
-		vars: {intret: 'obj_int32 *'},
-		lines: [
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = rand();',
-			'return &(intret->header);'
-		]
-	});
-	os.addMessage('rand64', {
-		vars: {intret64: 'obj_int64 *'},
-		lines: [
-			'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);',
-			'intret64->num = (((int64_t)rand()) << 32 ) | rand();',
-			'return &(intret64->header);'
-		]
-	});
-	os.addMessage('srand', {
-		vars: {oseed: 'object *', seed: 'obj_int32 *'},
-		lines: [
-			'oseed = va_arg(args, object *);',
-			'seed = mcall(' + getMethodId("int32") + ', 1, oseed);',
-			'srand(seed->num);',
-			'return &(seed->header);'
-		]
-	});
-	os.addMessage('time', {
-		vars: {intret64: 'obj_int64 *'},
-		lines: [
-			'intret64 = (obj_int64 *)make_object(&obj_int64_meta, NULL, 0);',
-			'intret64->num = time(NULL);',
-			'return &(intret64->header);'
-		]
-	});
-	os.addMessage('sleep', {
-		vars: {osecs: 'object *', secs: 'obj_int32 *', intret: 'obj_int32 *'},
-		lines: [
-			'osecs = va_arg(args, object *);',
-			'secs = mcall(' + getMethodId("int32") + ', 1, osecs);',
-			'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);',
-			'intret->num = sleep(secs->num);',
-			'return &(intret->header);'
-		]
-	});
-	toplevel.names['os'] = os;
-}
-
 modulefile.prototype.toIL = function(){
 	return this.ast.toILModuleInstance();
 };
@@ -1175,7 +1024,6 @@
 		forwarddec += builtins[i].toEarlyCDef();
 		toplevelcode += builtins[i].toILDef();
 	}
-	addBuiltinModules(toplevel);
 	debugprint('//------POPULATING SYMBOLS-----');
 	obj.populateSymbols(toplevel);
 	var moduleinit = processUsedToplevel(toplevel);
--- a/modules/bytearray.tp	Thu Jul 24 09:43:18 2014 -0700
+++ b/modules/bytearray.tp	Thu Jul 24 21:58:26 2014 -0700
@@ -2,6 +2,87 @@
 	includeSystemHeader: "unistd.h"
 	includeSystemHeader: "sys/mman.h"
 
+	normal <- :size {
+		#{
+			llProperty: bytes withType: uint32_t
+			llProperty: buffer withType: (void ptr)
+			llMessage: _init_buf withVars: {
+				sz <_ obj_int32 ptr
+			} andCode: :sz {
+				bytes <- sz num
+				buffer <- GC_MALLOC_ATOMIC: bytes
+				self
+			}
+
+			llMessage: _buf_ptr withVArs: {
+				ptrret <- cpointer ptr
+			} andCode: {
+				ptrret <- make_object: (addr_of: cpointer_meta) NULL 0
+				ptrret val!: buffer
+				ptrret
+			}
+
+			llMessage: length withVars: {
+				intret <- obj_int32 ptr
+			} andCode: {
+				intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+				intret num!: bytes
+				intret
+			}
+
+			llMessage: set withVars: {
+				offset <- obj_int32 ptr
+				newval <- obj_uint8 ptr
+			} andCode: :offset newval {
+				(buffer castTo: (uint8_t ptr)) set: (offset num) (newval num)
+				self
+			}
+			llMessage: get withVars: {
+				offset <- obj_int32 ptr
+				ret <- obj_uint8 ptr
+			} andCode: :offset {
+				ret <- make_object: (addr_of: obj_uint8_meta) NULL 0
+				ret num!: ((buffer castTo: (uint8_t ptr)) get: (offset num))
+				ret
+			}
+
+			llMessage: stringFrom:to withVars:{
+				from <- obj_int32 ptr
+				to <- obj_int32 ptr
+				str <- string ptr
+			} andCode: :from :to {
+				//probably should do some UTF-8 validation at some point
+				str <- make_object: (addr_of: string_meta) NULL 0
+				str bytes!: (to num) - (from num)
+				str len!: (str bytes)
+				str data!: (GC_MALLOC_ATOMIC: (str bytes) + 1)
+				memcpy: (str data) buffer (str bytes)
+				(str data) set: (str bytes) 0
+				str
+			}
+
+			string <- {
+				stringFrom: 0 to:
+			}
+
+			findChar:else <- :char found :else {
+				notfound <- true
+				n <- length
+				i <- 0
+				while: { notFound && i < n } do: {
+					if: (get: i) = char {
+						notfound <- false
+					} else: {
+						i <- i + 1
+					}
+				}
+				if: notfound else else: {
+					found: i
+				}
+			}
+		} _init_buf: size
+	}
+
 	executable <- :size {
 		buf <- #{
 			llProperty: bytes withType: uint32_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/os.tp	Thu Jul 24 21:58:26 2014 -0700
@@ -0,0 +1,125 @@
+{
+	_constant <- macro: :name {
+		quote: (llMessage: name withVars: {
+			uintret <- obj_int32 ptr
+		} andCode: {
+			uintret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			uintret num!: name
+			uintret
+		})
+	}
+	#{
+		includeSystemHeader: "sys/stat.h"
+		includeSystemHeader: "fcntl.h"
+		includeSystemHeader: "stdlib.h"
+		includeSystemHeader: "time.h"
+		includeSystemHeader: "unistd.h"
+
+		llMessage: write withVars: {
+			str <- string ptr
+			intret <- obj_int32 ptr
+			filedes <- obj_int32 ptr
+		} andCode: :filedes str {
+			intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			intret num!: (write: (filedes num) (str data) (str bytes))
+			intret
+		}
+
+		llMessage: read withVars: {
+			str <- string ptr
+			size <- obj_int32 ptr
+			filedes <- obj_int32 ptr
+		} andCode: :filedes size {
+			str <- make_object: (addr_of: string_meta) NULL 0
+			str data!: (GC_MALLOC_ATOMIC: (size num) + 1)
+			str bytes!: (read: (filedes num) (str data) (size num))
+			if: (str bytes) < 0 {
+				str bytes!: 0
+			}
+			str len!: (str bytes)
+			(str data) set: (str bytes) 0
+			str
+		}
+
+		llMessage: readFrom:to withVars: {
+			buffer <- object ptr
+			bufOpaque <- cpointer ptr
+			size <- obj_int32 ptr
+			filedes <- obj_int32 ptr
+			intret <- obj_int32 ptr
+		} andCode: :filedes buffer {
+			bufOpaque <- (mcall: _buf_ptr 1 buffer) castTo: (cpointer ptr)
+			size <- (mcall: length 1 buffer) castTo: (obj_int32 ptr)
+			intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			intret num!: (read: (filedes num) (bufOpaque val) (size num))
+			intret
+		}
+
+		open <- :filename flags {
+			open: filename flags createPerm: 0b110110110
+		}
+
+		llMessage: open:createPerm withVars: {
+			filename <- string ptr
+			flags <- obj_int32 ptr
+			perm <- obj_int32 ptr
+			filedes <- obj_int32 ptr
+		} andCode: :filename flags :perm {
+			filedes <- make_object: (addr_of: obj_int32_meta) NULL 0
+			filedes num!: (open: (filename data) (flags num) (perm num))
+			filedes
+		}
+
+		llMessage: close withVars: {
+			filedes <- obj_int32 ptr
+			intret <- obj_int32 ptr
+		} andCode: :filedes {
+			intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			intret num!: (close: (filedes num))
+			intret
+		}
+
+		_constant: O_RDONLY
+		_constant: O_WRONLY
+		_constant: O_RDWR
+		_constant: O_CREAT
+		_constant: O_APPEND
+		_constant: O_TRUNC
+
+		llMessage: rand withVars: {
+			intret <- obj_int32 ptr
+		} andCode: {
+			intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			intret num!: (rand: )
+			intret
+		}
+
+		llMessage: srand withVars: {
+			oseed <- object ptr
+			seed <- obj_int32 ptr
+		} andCode: :oseed {
+			seed <- (mcall: i32 1 oseed) castTo: (obj_int32 ptr)
+			srand: (seed num)
+			seed
+		}
+
+		llMessage: time withVars: {
+			intret64 <- obj_int64 ptr
+		} andCode: {
+			intret64 <- make_object: (addr_of: obj_int64_meta) NULL 0
+			intret64 num!: (time: NULL)
+			intret64
+		}
+
+		llMessage: sleep withVars: {
+			osecs <- object ptr
+			secs <- obj_int32 ptr
+			intret <- obj_int32 ptr
+		} andCode: :osecs {
+			secs <- (mcall: i32 1 osecs) castTo: (obj_int32 ptr)
+			intret <- make_object: (addr_of: obj_int32_meta) NULL 0
+			intret num!: (sleep: (secs num))
+			intret
+		}
+	}
+}
--- a/samples/osmod.tp	Thu Jul 24 09:43:18 2014 -0700
+++ b/samples/osmod.tp	Thu Jul 24 21:58:26 2014 -0700
@@ -3,7 +3,7 @@
 		os write: 1 "hello stdout via POSIX write\n"
 		name <- os read: 0 100
 		os write: 2 "hello " . name . " via stderr\n"
-		file <- os open: "output.txt" (os O_WRONLY) + (os O_CREAT) + (os O_TRUNC) 0b110110110
+		file <- os open: "output.txt" (os O_WRONLY) + (os O_CREAT) + (os O_TRUNC) createPerm: 0b110110110
 		os write: file "hello file!\n"
 		os close: file
 		0