diff options
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | std/base.toc | 3 | ||||
-rw-r--r-- | std/io.toc | 50 | ||||
-rw-r--r-- | std/mem.toc | 6 | ||||
-rw-r--r-- | test.toc | 12 | ||||
-rw-r--r-- | types.h | 2 |
6 files changed, 66 insertions, 12 deletions
@@ -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; + @@ -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); +} @@ -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; + } + } +} @@ -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?) |