summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c1
-rw-r--r--parse.c18
-rw-r--r--std/io.toc24
-rw-r--r--test.toc23
-rw-r--r--types.c13
5 files changed, 53 insertions, 26 deletions
diff --git a/main.c b/main.c
index 631e456..08c3a2f 100644
--- a/main.c
+++ b/main.c
@@ -8,6 +8,7 @@
/*
@TODO:
+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)
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:
diff --git a/parse.c b/parse.c
index 4ced599..4112492 100644
--- a/parse.c
+++ b/parse.c
@@ -1176,18 +1176,22 @@ static Status parse_c_type(Parser *p, CType *ctype, Type *type) {
} else if (t->token->kind == TOKEN_IDENT) {
char *id = t->token->ident;
ctype->kind = 0;
- if (ident_str_len(id) > 9 && strncmp(id, "unsigned_", 9) == 0) {
- ctype->kind |= CTYPE_UNSIGNED;
- id += 9;
- }
if (ident_str_eq_str(id, "signed_char"))
ctype->kind = CTYPE_SIGNED_CHAR;
else if (ident_str_eq_str(id, "short"))
- ctype->kind |= CTYPE_SHORT;
+ ctype->kind = CTYPE_SHORT;
+ else if (ident_str_eq_str(id, "unsigned_short"))
+ ctype->kind = CTYPE_UNSIGNED_SHORT;
+ else if (ident_str_eq_str(id, "unsigned"))
+ ctype->kind = CTYPE_UNSIGNED_INT;
else if (ident_str_eq_str(id, "long"))
- ctype->kind |= CTYPE_LONG;
+ ctype->kind = CTYPE_LONG;
+ else if (ident_str_eq_str(id, "unsigned_long"))
+ ctype->kind = CTYPE_UNSIGNED_LONG;
else if (ident_str_eq_str(id, "long_long"))
- ctype->kind |= CTYPE_LONGLONG;
+ ctype->kind = CTYPE_LONGLONG;
+ else if (ident_str_eq_str(id, "unsigned_long_long"))
+ ctype->kind = CTYPE_UNSIGNED_LONGLONG;
else if (ident_str_eq_str(id, "double"))
ctype->kind = CTYPE_DOUBLE;
else if (ident_str_eq_str(id, "size_t"))
diff --git a/std/io.toc b/std/io.toc
index 9b77ac3..f00be4e 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -7,9 +7,12 @@
raw_file_write ::= fn(file: RawFile, buf: &void, size: int) int {
write(file as #C int, buf, size as #C size_t) as int
}
- get_stdout ::= fn() RawFile {
+ raw_stdout ::= fn() RawFile {
1
}
+ raw_stderr ::= fn() RawFile {
+ 2
+ }
} 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;
@@ -17,7 +20,10 @@
raw_file_write ::= fn(file: RawFile, buf: &void, size: int) int {
fwrite(buf, 1, size, file);
}
- get_stdout ::= fn() RawFile {
+ raw_stdout ::= fn() RawFile {
+ #builtin("stdout")
+ }
+ raw_stderr ::= fn() RawFile {
#builtin("stdout")
}
}
@@ -27,6 +33,7 @@ File ::= struct {
BUFSZ ::= 4096;
raw : RawFile;
written : int; // ranges from 0 to FILE_BUFSZ-1
+ nobuffer : bool; // if true, flush after every write
buffer : [BUFSZ]char;
}
@@ -34,7 +41,7 @@ raw_file_to_file ::= fn(raw : RawFile) f: File {
f.raw = raw;
}
-std_out := raw_file_to_file(get_stdout());
+std_out, std_err : File;
file_flush ::= fn(use f: &File) {
raw_file_write(raw, &buffer[0], written);
@@ -42,6 +49,10 @@ file_flush ::= fn(use f: &File) {
}
file_writes ::= fn(use f: &File, s : []char) {
+ if f.nobuffer {
+ raw_file_write(raw, &s[0], s.len);
+ return;
+ }
if written + s.len > BUFSZ {
file_flush(f);
if s.len > BUFSZ {
@@ -55,3 +66,10 @@ file_writes ::= fn(use f: &File, s : []char) {
written += s.len;
}
}
+
+io_init ::= fn() {
+ std_out = raw_file_to_file(raw_stdout());
+ std_out.nobuffer = true;
+ std_err = raw_file_to_file(raw_stderr());
+ std_err.nobuffer = true;
+}
diff --git a/test.toc b/test.toc
index f989ecf..6b7ac06 100644
--- a/test.toc
+++ b/test.toc
@@ -1,22 +1,15 @@
-/*
-
#include "std/io.toc", io;
+#include "std/base.toc", base;
-
+sleep ::= #foreign("sleep", base.libc) fn(#C unsigned) #C unsigned;
main ::= fn() {
+ io.io_init();
io.file_writes(&io.std_out, "hello!\n");
- io.file_flush(&io.std_out);
-}
-
-*/
-
-
-#include "tests/std/io.toc", io;
-a, b := 5;
-main ::= fn() {
- a = 6;
- io.puti(a);
- io.puti(b);
+ io.file_writes(&io.std_out, "goodbye!\n");
+ io.file_writes(&io.std_err, "ERROR: ");
+ sleep(1);
+ io.file_writes(&io.std_err, "something went wrong!\n");
}
main();
+
diff --git a/types.c b/types.c
index 789d95f..31de794 100644
--- a/types.c
+++ b/types.c
@@ -3475,6 +3475,17 @@ static Status types_decl(Typer *tr, Declaration *d) {
}
}
}
+ } else if (!tr->block || tr->block->kind == BLOCK_NMS) {
+ /* give global variables without initializers a value stack */
+ Value *val = typer_malloc(tr, sizeof *val);
+ arr_add(d->val_stack, val);
+ if (n_idents > 1 && dtype->kind != TYPE_TUPLE) {
+ Value *tuple = val->tuple = typer_malloc(tr, n_idents * sizeof *tuple);
+ for (size_t i = 0; i < n_idents; ++i)
+ tuple[i] = val_zero(dtype);
+ } else {
+ *val = val_zero(dtype);
+ }
}
@@ -3739,7 +3750,7 @@ static Status types_stmt(Typer *tr, Statement *s) {
return false;
}
} else {
- if (type_is_void(&tr->fn->ret_type) && !tr->fn->ret_decls) {
+ if (!type_is_void(&tr->fn->ret_type) || tr->fn->ret_decls) {
err_print(s->where, "No return value in non-void function.");
return false;
}