summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c5
-rw-r--r--std/base.toc3
-rw-r--r--std/io.toc50
-rw-r--r--std/mem.toc6
-rw-r--r--test.toc12
-rw-r--r--types.h2
6 files changed, 66 insertions, 12 deletions
diff --git a/main.c b/main.c
index 08c3a2f..1d83b41 100644
--- a/main.c
+++ b/main.c
@@ -8,8 +8,10 @@
/*
@TODO:
+remove while loops with no condition- they're weird
initialization functions (maybe #init(-50), where -50 is the priority and <0 is reserved for standard library)
-start making a standard library... (printf; stringbuilder would be nice to have)
+detect circular declarations (A ::= B; B ::= A)
+either detect circular #includes or set a #include depth limit (maybe sometimes you want finite circular includes with #if)
if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
improve type_to_str:
Foo ::= struct(t::Type) {}
@@ -20,7 +22,6 @@ enums
unions
bitwise operations
---
-either detect circular #includes or set a #include depth limit (maybe sometimes you want finite circular includes with #if)
switch to / add as an alternative: libffi
- better yet, inline assembly
don't bother generating ret_ if nothing's deferred
diff --git a/std/base.toc b/std/base.toc
index 08c5e53..54d64d6 100644
--- a/std/base.toc
+++ b/std/base.toc
@@ -23,5 +23,4 @@ PLATFORM ::= #builtin("platform");
PLATFORM_IS_UNIX :: bool = PLATFORM == PLATFORM_LINUX || PLATFORM == PLATFORM_OSX || PLATFORM == PLATFORM_FREEBSD
|| PLATFORM == PLATFORM_OPENBSD || PLATFORM == PLATFORM_MISC_UNIX;
-// @TODO: write your own
-memcpy ::= #foreign("memcpy", libc) fn(&void, #C &"const void", #C size_t) &void;
+
diff --git a/std/io.toc b/std/io.toc
index f00be4e..acba673 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -1,11 +1,32 @@
#include "std/base.toc", base;
+#include "std/mem.toc", mem;
+
+str_to_cstr ::= fn(s: []char) []char {
+ ret := mem.news(char, s.len+1);
+ mem.mem_copy(&ret[0], &s[0], s.len);
+ ret
+}
#if base.PLATFORM_IS_UNIX {
// @TODO: use syscall instead
- write ::= #foreign("write", "libc.so.6") fn(#C int, #C &"const void", #C size_t) #C long;
+ write ::= #foreign("write", base.libc) fn(#C int, #C &"const void", #C size_t) #C long;
+ open ::= #foreign("open", base.libc) fn (#C &"const char", #C int) #C int;
+
+ O_RDONLY ::= 0x00;
+ O_WRONLY ::= 0x01;
+ O_CREAT ::= 0x40;
+
RawFile ::= int;
- raw_file_write ::= fn(file: RawFile, buf: &void, size: int) int {
- write(file as #C int, buf, size as #C size_t) as int
+ raw_file_write ::= fn(file: RawFile, buf: &void, size: int) bool {
+ while size > 0 {
+ bytes_written := write(file as #C int, buf, size as #C size_t);
+ if bytes_written < 0 {
+ return false;
+ }
+ size -= bytes_written;
+ buf += bytes_written;
+ }
+ true
}
raw_stdout ::= fn() RawFile {
1
@@ -13,12 +34,20 @@
raw_stderr ::= fn() RawFile {
2
}
+ file_open_write ::= fn(name: []char) f: RawFile, success: bool {
+ cstr := str_to_cstr(name);
+ defer mem.dels(cstr);
+ // @TODO: switch to bitwise or when that exists
+ f = open(&cstr[0], (O_WRONLY + O_CREAT) as #C int) as RawFile;
+ success = f != -1;
+ }
} else {
// @TODO: on windows, use WriteFile
fwrite ::= #foreign("fwrite", base.libc) fn(#C &"const void", #C size_t, #C size_t, &void) #C size_t;
RawFile ::= &void;
- raw_file_write ::= fn(file: RawFile, buf: &void, size: int) int {
- fwrite(buf, 1, size, file);
+ raw_file_write ::= fn(file: RawFile, buf: &void, size: int) bool {
+ bytes_written := fwrite(buf, 1, size, file) as int;
+ bytes_written == size
}
raw_stdout ::= fn() RawFile {
#builtin("stdout")
@@ -26,6 +55,13 @@
raw_stderr ::= fn() RawFile {
#builtin("stdout")
}
+ file_open_write ::= fn(name: []char) f: RawFile, success: bool {
+ cstr := base.str_to_cstr(name);
+ defer mem.dels(cstr);
+ mode := "w\0";
+ f = fopen(&cstr[0], &mode[0]);
+ success = f != null;
+ }
}
@@ -58,11 +94,11 @@ file_writes ::= fn(use f: &File, s : []char) {
if s.len > BUFSZ {
raw_file_write(raw, &s[0], s.len);
} else {
- base.memcpy(&buffer[0], &s[0], s.len as #C size_t);
+ mem.mem_copy(&buffer[0], &s[0], s.len);
written = s.len;
}
} else {
- base.memcpy(&buffer[written], &s[0], s.len as #C size_t);
+ mem.mem_copy(&buffer[written], &s[0], s.len);
written += s.len;
}
}
diff --git a/std/mem.toc b/std/mem.toc
index ef4e638..1e21702 100644
--- a/std/mem.toc
+++ b/std/mem.toc
@@ -23,3 +23,9 @@ del ::= fn(t::=, x: &t) {
dels ::= fn(t::=, x: []t) {
free(x.data);
}
+
+// @TODO: write your own
+memcpy ::= #foreign("memcpy", base.libc) fn(&void, #C &"const void", #C size_t) &void;
+mem_copy ::= fn(dst: &void, src: &void, n: int) {
+ memcpy(dst, src, n as #C size_t);
+}
diff --git a/test.toc b/test.toc
index 6b7ac06..24b13b7 100644
--- a/test.toc
+++ b/test.toc
@@ -1,3 +1,5 @@
+/*
+
#include "std/io.toc", io;
#include "std/base.toc", base;
@@ -12,4 +14,14 @@ main ::= fn() {
io.file_writes(&io.std_err, "something went wrong!\n");
}
main();
+*/
+
+a ::= nms {
+ #if 1 {
+ test ::= 0x501;
+ foo ::= fn() {
+ test;
+ }
+ }
+}
diff --git a/types.h b/types.h
index 50983a2..a33839f 100644
--- a/types.h
+++ b/types.h
@@ -883,7 +883,7 @@ typedef struct Declaration {
Value val; /* only for constant decls, non-constant globals, and varargs. */
/*
- for eval, for non-constant local decls
+ for eval, for non-constant decls
the pointers to values need to be fixed, which is why this isn't just Value *.
no, this can't be a union with val, because of global variables and possibly
other things (varargs maybe?)