summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c34
-rw-r--r--main.c2
-rw-r--r--std/io.toc38
-rw-r--r--test.toc32
-rw-r--r--types.c9
5 files changed, 63 insertions, 52 deletions
diff --git a/cgen.c b/cgen.c
index b27f2fa..9bed06c 100644
--- a/cgen.c
+++ b/cgen.c
@@ -605,8 +605,7 @@ static inline void cgen_deferred_up_to_not_including(CGenerator *g, Block *to) {
Also, set_str and/or to_str should be NULL
this DOES NOT call cgen_expr_pre for set_expr or to_expr
*/
-static void cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, Expression *to_expr,
- const char *to_str) {
+static void cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, Expression *to_expr, const char *to_str) {
Type *type;
if (set_expr) {
type = &set_expr->type;
@@ -817,36 +816,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) {
++i;
}
if (e->type.kind == TYPE_TUPLE) {
- Type *t = &e->type;
- size_t ntypes = arr_len(t->tuple);
- IdentID *ids = err_malloc(ntypes * sizeof *ids);
- for (i = 0; i < ntypes; ++i) {
- ids[i] = ++g->ident_counter;
- cgen_type_pre(g, &t->tuple[i]);
- cgen_write(g, " ");
- cgen_ident_id(g, ids[i]);
- cgen_type_post(g, &t->tuple[i]);
- cgen_write(g, "; ");
- }
- cgen_expr(g, e->call.fn);
- cgen_write(g, "(");
- bool any_args = false;
- i = 0;
- arr_foreach(e->call.arg_exprs, Expression, arg) {
- if (!constness || !arg_is_const(arg, constness[i])) {
- if (any_args) cgen_write(g, ", ");
- any_args = true;
- cgen_arg(g, arg);
- }
- ++i;
- }
- for (i = 0; i < ntypes; ++i) {
- if (any_args) cgen_write(g, ", ");
- any_args = true;
- cgen_write(g, "&");
- cgen_ident_id(g, ids[i]);
- }
- cgen_write(g, ");");
+ /* we actually don't ever need this; it's handled individually elsewhere */
} else if (cgen_uses_ptr(&e->type)) {
IdentID id = e->cgen.id = ++g->ident_counter;
cgen_type_pre(g, &e->type);
diff --git a/main.c b/main.c
index 1863a1c..9e5bb52 100644
--- a/main.c
+++ b/main.c
@@ -8,8 +8,10 @@
/*
@TODO:
+a ::= fn() (int, int) { return 3, 5; } b ::= fn() (int, int) { return a(); }
if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared)
fix #foreign not at global scope - right now the cgen'd definition doesn't use the proper type
+find out why file output is really slow at compile time; try to improve it
improve type_to_str:
Foo ::= struct(t::Type) {}
type_to_str(Foo(int))
diff --git a/std/io.toc b/std/io.toc
index ebdff8d..b220918 100644
--- a/std/io.toc
+++ b/std/io.toc
@@ -11,7 +11,8 @@ str_to_cstr ::= fn(s: []char) []char {
// @TODO(eventually): enum
FileError ::= int;
FILE_ERR_OK ::= 0;
-FILE_ERR_MISC ::= 1;
+FILE_ERR_EOF ::= 1;
+FILE_ERR_MISC ::= 2;
// @TODO: more of these
/*
@@ -19,7 +20,7 @@ the raw file interface:
raw_stdout - standard output
raw_stderr - standard error
raw_stdin - standard input
-raw_file_read - read from a raw file - unlike raw_file_write, it's okay if the number of bytes read doesn't match the number of bytes requested.
+raw_file_read - read from a raw file - unlike raw_file_write, it's okay if the number of bytes read doesn't match the number of bytes requested, but if 0 bytes are read, it is assumed to be the end of the file
raw_file_write - write to a raw file
raw_file_open_write - open a raw file for writing
raw_file_open_read - open a raw file for reading
@@ -158,6 +159,7 @@ File ::= struct {
raw : RawFile;
buffer_used, buffer_len : int; // range from 0 to FILE_BUFSZ-1
mode : FileMode;
+ eof : bool;
nobuffer : bool; // if true, flush after every write
buffer : [BUFSZ]char;
}
@@ -178,6 +180,15 @@ fopen_write ::= fn(name: []char) f: &File, error: FileError {
}
}
+fopen_read ::= fn(name: []char) f: &File, error: FileError {
+ raw : RawFile;
+ raw, error = raw_file_open_read(name);
+ if !error {
+ f = mem.new(File);
+ raw_file_to_file(raw, MODE_READ, f);
+ }
+}
+
flush ::= fn(use f: &File) err: FileError {
if mode == MODE_READ {
// discard buffer
@@ -243,6 +254,10 @@ fread ::= fn(use f: &File, out: &[]char) FileError {
base.error("Reading from file which wasn't opened for reading.");
}
}
+ if eof {
+ out.len = 0;
+ return FILE_ERR_EOF;
+ }
to_read := out.len;
buffer_left := buffer_len - buffer_used;
if to_read <= buffer_left {
@@ -258,16 +273,23 @@ fread ::= fn(use f: &File, out: &[]char) FileError {
buffer_used = 0;
buffer_len = 0;
n, err := raw_file_read(raw, &out[out_idx], to_read);
+ if n == 0 {
+ eof = true;
+ }
out.len = n + buffer_left;
if err {
return err;
}
} elif to_read > 0 {
n, err := raw_file_read(raw, &buffer[0], BUFSZ);
+ if n == 0 {
+ eof = true;
+ }
buffer_len = n;
if n < to_read {
// we didn't read out.len bytes
out.len = n + buffer_left;
+ to_read = n;
}
if err {
buffer_used = 0;
@@ -281,19 +303,19 @@ fread ::= fn(use f: &File, out: &[]char) FileError {
}
-// read a line from in (default: standard input). does not include newline
-gets ::= fn(out: &[]char, in := &std_in) err : FileError {
- err = fread(in, out);
+// read a line from standard input. does not include newline
+gets ::= fn(out: &[]char) err : FileError {
+ err = fread(&std_in, out);
if out.len && out[out.len-1] == '\n' {
out.len -= 1;
}
}
-// read a line of file in (default: standard input), at most max_len (default: 256) characters
+// read a line of standard input, at most max_len (default: 256) characters
// a read error might happen, but this function just ignores it
-read_line ::= fn(max_len := 256, in := &std_in) []char {
+read_line ::= fn(max_len := 256) []char {
ret := mem.news(char, max_len);
- gets(&ret, in);
+ gets(&ret);
return ret;
}
diff --git a/test.toc b/test.toc
index d672753..afb40bb 100644
--- a/test.toc
+++ b/test.toc
@@ -3,14 +3,30 @@
#include "std/base.toc", base;
main ::= fn() {
- file, _ := io.fopen_write("test.txt");
- io.writes("What is your name? ");
- b : [64]char;
- name := b[:];
- err := io.gets(&name, file);
+ file, err := io.fopen_read("test.txt");
if err {
- base.error("File error");
+ base.error("Couldn't open file.");
}
- io.writes("Hello, ");
- io.puts(name);
+ defer io.fclose(file);
+ buf : [3]char;
+ while !err {
+ s := buf[:];
+ err = io.fread(file, &s);
+ io.writes(s);
+ }
+}
+
+/*
+// @TODO: fix this
+
+bar ::= fn() (int, int) {
+ return foo();
+}
+foo ::= fn() (int, int) {
+ return 3, 5;
+}
+
+main ::= fn() {
+ a, b := foo();
}
+*/
diff --git a/types.c b/types.c
index fc9bd23..17ac556 100644
--- a/types.c
+++ b/types.c
@@ -2438,17 +2438,18 @@ static Status types_expr(Typer *tr, Expression *e) {
err_print(e->where, "Unrecognized builtin value: %s.", builtin_name);
return false;
}
- get_builtin_val_type(tr->allocr, which, t);
+ BuiltinVal builtin = (BuiltinVal)which;
+ get_builtin_val_type(tr->allocr, builtin, t);
assert(t->flags & TYPE_IS_RESOLVED);
- switch (which) {
+ switch (builtin) {
/* immediately evaluate (things which do not differ between compile time & run time) */
case BUILTIN_DEBUG:
e->kind = EXPR_VAL;
- e->val = get_builtin_val(tr->gctx, which);
+ e->val = get_builtin_val(tr->gctx, builtin);
break;
/* stuff that's different between compile & run time */
default:
- e->builtin.which.val = (BuiltinVal)which;
+ e->builtin.which.val = builtin;
break;
}
} break;