From e57804e6c27496c5a2822c517d833343a94fcadc Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 21 Mar 2020 09:29:16 +0100 Subject: [PATCH] cgen: generate init() --- vlib/strings/builder_c.v | 4 +++- vlib/v/gen/cgen.v | 41 +++++++++++++++++++++++----------------- vlib/v/gen/cgen_test.v | 1 + vlib/v/gen/cheaders.v | 3 ++- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/vlib/strings/builder_c.v b/vlib/strings/builder_c.v index db197e2a49..07d2eb9484 100644 --- a/vlib/strings/builder_c.v +++ b/vlib/strings/builder_c.v @@ -72,7 +72,9 @@ pub fn (b &Builder) after(n int) string { return '' } buf := b.buf[n..] - return string(buf.clone()) + mut copy := buf.clone() + copy << `\0` + return string(copy) } pub fn (b mut Builder) str() string { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index d3f809e409..5b8c162adf 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -12,6 +12,7 @@ struct Gen { out strings.Builder typedefs strings.Builder definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) + inits strings.Builder // contents of `void _init(){}` table &table.Table mut: fn_decl &ast.FnDecl // pointer to the FnDecl we are currently inside otherwise 0 @@ -33,6 +34,7 @@ pub fn cgen(files []ast.File, table &table.Table) string { out: strings.new_builder(100) typedefs: strings.new_builder(100) definitions: strings.new_builder(100) + inits: strings.new_builder(100) table: table fn_decl: 0 } @@ -42,6 +44,9 @@ pub fn cgen(files []ast.File, table &table.Table) string { } g.write_variadic_types() g.write_str_definitions() + g.writeln('void _init() {') + g.writeln(g.inits.str()) + g.writeln('}') return g.typedefs.str() + g.definitions.str() + g.out.str() } @@ -1425,31 +1430,28 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) { for i, field in node.fields { name := field.name.replace('.', '__') expr := node.exprs[i] + // TODO hack. Cut the generated value and paste it into definitions. + pos := g.out.len + g.expr(expr) + val := g.out.after(pos) + g.out.go_back(val.len) match expr { - // Simple expressions should use a #define - // so that we don't pollute the binary with unnecessary global vars - // Do not do this when building a module, otherwise the consts - // will not be accessible. ast.CharLiteral, ast.IntegerLiteral { + // Simple expressions should use a #define + // so that we don't pollute the binary with unnecessary global vars + // Do not do this when building a module, otherwise the consts + // will not be accessible. g.definitions.write('#define $name ') - // TODO hack. Cut the generated value and paste it into definitions. - g.write('//') - pos := g.out.len - g.expr(expr) - mut b := g.out.buf[pos..g.out.buf.len].clone() - b << `\0` - val := string(b) - // val += '\0' - // g.out.go_back(val.len) - // println('pos=$pos buf.len=$g.out.buf.len len=$g.out.len val.len=$val.len val="$val"\n') - g.writeln('') g.definitions.writeln(val) } else { + // Initialize more complex consts in `void _init(){}` + // (C doesn't allow init expressions that can't be resolved at compile time). styp := g.typ(field.typ) g.definitions.writeln('$styp $name; // inited later') // = ') - // TODO - // g.expr(node.exprs[i]) + g.inits.write('$name = ') + g.inits.write(val) + g.inits.writeln(';') } } } @@ -1534,6 +1536,11 @@ fn verror(s string) { // exit(1) } +fn (g mut Gen) write_init_function() { + g.writeln('void _init() {') + g.writeln('}') +} + fn (g mut Gen) write_str_definitions() { // _STR function can't be defined in vlib g.writeln(' diff --git a/vlib/v/gen/cgen_test.v b/vlib/v/gen/cgen_test.v index 4bc320b576..e81ee5dc4b 100644 --- a/vlib/v/gen/cgen_test.v +++ b/vlib/v/gen/cgen_test.v @@ -48,6 +48,7 @@ fn compare_texts(a, b, path string) bool { for i, line_a in lines_a { if i >= lines_b.len { + println(line_a) return false } line_b := lines_b[i] diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index 2d42d01dc5..504a7fde85 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -188,9 +188,10 @@ extern wchar_t **_wenviron; byte g_str_buf[1024]; int load_so(byteptr); void reload_so(); +void _init(); // ============== wyhash ============== -// Author: Wang Yi +// Author: Wang Yi #ifndef wyhash_version_4 #define wyhash_version_4 #include