diff options
-rw-r--r-- | cgen.c | 34 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | std/io.toc | 38 | ||||
-rw-r--r-- | test.toc | 32 | ||||
-rw-r--r-- | types.c | 9 |
5 files changed, 63 insertions, 52 deletions
@@ -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); @@ -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)) @@ -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; } @@ -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(); } +*/ @@ -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; |