diff --git a/compiler/cgen.v b/compiler/cgen.v index d7dc301b03..dc400dec5d 100644 --- a/compiler/cgen.v +++ b/compiler/cgen.v @@ -31,9 +31,15 @@ mut: } fn new_cgen(out_name_c string) *CGen { + path:='$TmpPath/$out_name_c' + out := os.create(path) or { + println('failed to create $path') + return &CGen{} +} + gen := &CGen { - out_path: '$TmpPath/$out_name_c' - out: os.create('$TmpPath/$out_name_c') + out_path: path + out: out } return gen } diff --git a/compiler/jsgen.v b/compiler/jsgen.v index 86da28a0fa..9f2a8f98af 100644 --- a/compiler/jsgen.v +++ b/compiler/jsgen.v @@ -104,7 +104,8 @@ string res = tos2(""); enc += ' cJSON_AddItemToObject(o, "$name", $enc_name(val.$name)); \n' } // cJSON_delete - p.cgen.fns << '$dec return opt_ok(res); \n}' + //p.cgen.fns << '$dec return opt_ok(res); \n}' + p.cgen.fns << '$dec return opt_ok(res, sizeof(res)); \n}' p.cgen.fns << '/*enc start*/ $enc return o;}' } diff --git a/compiler/main.v b/compiler/main.v index cea10a1e52..14001137fe 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -618,7 +618,7 @@ mut args := '' println('linux cross compilation done. resulting binary: "$v.out_name"') } if !v.pref.is_debug && v.out_name_c != 'v.c' && v.out_name_c != 'v_macos.c' { - os.rm('$TmpPath/$v.out_name_c') + //os.rm('$TmpPath/$v.out_name_c') } } @@ -882,7 +882,8 @@ fn new_v(args[]string) *V { if os.file_exists(vroot_path) { mut vroot := os.read_file(vroot_path) or { break - } + } + //mut vroot := os.read_file(vroot_path) vroot=vroot.trim_space() if os.dir_exists(vroot) && os.dir_exists(vroot + '/vlib/builtin') { lang_dir = vroot diff --git a/compiler/parser.v b/compiler/parser.v index 8a5c378614..90a4700b30 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -239,7 +239,10 @@ fn (p mut Parser) parse() { p.check_unused_variables() } if false && !p.first_run() && p.fileis('main.v') { - out := os.create('/var/tmp/fmt.v') + out := os.create('/var/tmp/fmt.v') or { + panic('failed to create fmt.v') + return +} out.writeln(p.scanner.fmt_out.str()) out.close() } @@ -670,14 +673,14 @@ fn (p mut Parser) error(s string) { //q := "SDF" // Dump all vars and types for debugging if false { - file_types := os.create('$TmpPath/types') - file_vars := os.create('$TmpPath/vars') + //file_types := os.create('$TmpPath/types') + //file_vars := os.create('$TmpPath/vars') // ////debug("ALL T", q.J(p.table.types)) // os.write_to_file('/var/tmp/lang.types', '')//pes(p.table.types)) // //debug("ALL V", q.J(p.table.vars)) // os.write_to_file('/var/tmp/lang.vars', q.J(p.table.vars)) - file_types.close() - file_vars.close() + //file_types.close() + //file_vars.close() } if !p.pref.is_repl { println('pass=$p.run fn=`$p.cur_fn.name`') @@ -1082,7 +1085,8 @@ fn (p mut Parser) assign_statement(v Var, ph int, is_map bool) { println('allowing option asss') expr := p.cgen.cur_line.right(pos) left := p.cgen.cur_line.left(pos) - p.cgen.cur_line = left + 'opt_ok($expr)' + //p.cgen.cur_line = left + 'opt_ok($expr)' + p.cgen.cur_line = left + 'opt_ok($expr, sizeof($expr_type))' } else if !p.builtin_pkg && !p.check_types_no_throw(expr_type, p.assigned_type) { p.scanner.line_nr-- @@ -3030,8 +3034,9 @@ fn (p mut Parser) return_st() { expr_type := p.bool_expression() // Automatically wrap an object inside an option if the function returns an option if p.cur_fn.typ.ends_with(expr_type) && p.cur_fn.typ.starts_with('Option_') { + //p.cgen.set_placeholder(ph, 'opt_ok(& ') p.cgen.set_placeholder(ph, 'opt_ok(& ') - p.gen(')') + p.gen(', sizeof($expr_type))') } p.check_types(expr_type, p.cur_fn.typ) } diff --git a/compiler/scanner.v b/compiler/scanner.v index dc2608304b..527db200b9 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -32,6 +32,7 @@ fn new_scanner(file_path string) *Scanner { if !os.file_exists(file_path) { panic('"$file_path" doesn\'t exist') } + //text := os.read_file(file_path) text := os.read_file(file_path) or { panic('scanner: failed to open "$file_path"') return &Scanner{} diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 6f65c71858..2d19eae95a 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -94,23 +94,11 @@ fn _strlen(s byteptr) int { return C.strlen(s) } -// `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }` -fn opt_ok(data voidptr) Option { - return Option { - data: data - ok: true - } -} fn memdup(src voidptr, sz int) voidptr { mem := malloc(sz) return C.memcpy(mem, src, sz) } -pub fn error(s string) Option { - return Option { - error: s - } -} diff --git a/vlib/builtin/option.v b/vlib/builtin/option.v index 63d9f410b8..8e7c84d263 100644 --- a/vlib/builtin/option.v +++ b/vlib/builtin/option.v @@ -5,8 +5,27 @@ module builtin struct Option { - data voidptr + data [255] byte error string ok bool } +// `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }` +fn opt_ok(data voidptr, size int) Option { + if size > 255 { + panic('option size too big: $size (max is 255)') + } + res := Option { + ok: true + } + C.memcpy(res.data, data, size) + return res +} + +pub fn error(s string) Option { + return Option { + error: s + } +} + + diff --git a/vlib/os/os.v b/vlib/os/os.v index 6725a3491f..c27d976463 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -105,7 +105,34 @@ fn parse_windows_cmd_line(cmd byteptr) []string { } // read_file reads the file in `path` and returns the contents. -pub fn read_file(path string) ?string { +//pub fn read_file(path string) ?string { +pub fn read_file(path string) ?string { + mut res := '' + mut mode := 'r' + 777 // TODO + // Need 'rb' on windows to avoid the \r\n mess. + $if windows { + mode = 'rb' + } + cpath := path.cstr() + fp := C.fopen(cpath, mode.cstr()) + if isnil(fp) { + return error('failed to open file "$path"') + //panic('failed to open file "$path"') + } + C.fseek(fp, 0, SEEK_END) + fsize := C.ftell(fp) + // C.fseek(fp, 0, SEEK_SET) // same as C.rewind(fp) below + C.rewind(fp) + mut str := malloc(fsize + 1) + C.fread(str, fsize, 1, fp) + C.fclose(fp) + str[fsize] = 0 + res = tos(str, fsize) + return res +} + +pub fn read_file_opt(path string) ?string { mut res := '' mut mode := 'r' 777 // TODO @@ -178,36 +205,38 @@ fn read_ulines(path string) []ustring { return ulines } -// TODO return `File?` -pub fn open(path string) File { - return open_file(path) -} - -fn open_file(file string) File { - return create_file2(file, 'r') -} - -// `create` creates a file at a specified location and returns a writable `File` object. -pub fn create(path string) File { - return create_file2(path, 'w') -} - -fn create_file_a(file string) File { - return create_file2(file, 'a') -} - -fn open_file_a(file string) File { - return create_file2(file, 'a') -} - -fn create_file2(file, mode string) File { - res := File { - cfile: C.fopen(file.cstr(), mode.cstr()) +pub fn open(path string) ?File { + cpath := path.cstr() + file := File { + cfile: C.fopen(cpath, 'r') } - if isnil(res.cfile) { - println('coudlnt create file "$file"') + if isnil(file.cfile) { + return error('failed to open file "$path"') } - return res + return file +} + +// create creates a file at a specified location and returns a writable `File` object. +pub fn create(path string) ?File { + cpath := path.cstr() + file := File { + cfile: C.fopen(cpath, 'w') + } + if isnil(file.cfile) { + return error('failed to create file "$path"') + } + return file +} + +pub fn open_append(path string) ?File { + cpath := path.cstr() + file := File { + cfile: C.fopen(cpath, 'a') + } + if isnil(file.cfile) { + return error('failed to create file "$path"') + } + return file } pub fn (f File) write(s string) { @@ -243,15 +272,6 @@ pub fn (f File) close() { C.fclose(f.cfile) } -fn close_file(fp *FILE) { - $if windows { - } - if isnil(fp) { - return - } - C.fclose(fp) -} - // system starts the specified command, waits for it to complete, and returns its code. pub fn system(cmd string) int { ret := C.system(cmd.cstr()) @@ -479,7 +499,9 @@ pub fn home_dir() string { // write_file writes text data to a file in `path`. pub fn write_file(path, text string) { - f := os.create(path) + f := os.create(path) or { + return + } f.write(text) f.close() }