cgen: generate fn main for tests; fix consts bug
parent
2a7bc63919
commit
437bba5566
|
@ -156,3 +156,4 @@ fn test_int_decl() {
|
||||||
assert typeof(x6) == 'int'
|
assert typeof(x6) == 'int'
|
||||||
assert typeof(x7) == 'u64'
|
assert typeof(x7) == 'u64'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ mut:
|
||||||
autofree bool
|
autofree bool
|
||||||
indent int
|
indent int
|
||||||
empty_line bool
|
empty_line bool
|
||||||
|
is_test bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -64,7 +65,10 @@ pub fn cgen(files []ast.File, table &table.Table) string {
|
||||||
g.file = file
|
g.file = file
|
||||||
// println('\ncgen "$g.file.path" nr_stmts=$file.stmts.len')
|
// println('\ncgen "$g.file.path" nr_stmts=$file.stmts.len')
|
||||||
building_v := g.file.path.contains('/vlib/') || g.file.path.contains('cmd/v')
|
building_v := g.file.path.contains('/vlib/') || g.file.path.contains('cmd/v')
|
||||||
is_test := g.file.path.ends_with('.vv')
|
is_test := g.file.path.ends_with('.vv') || g.file.path.ends_with('_test.v')
|
||||||
|
if is_test {
|
||||||
|
g.is_test = is_test
|
||||||
|
}
|
||||||
if g.file.path == '' || is_test || building_v {
|
if g.file.path == '' || is_test || building_v {
|
||||||
// cgen test or building V
|
// cgen test or building V
|
||||||
// println('autofree=false')
|
// println('autofree=false')
|
||||||
|
@ -82,6 +86,9 @@ pub fn cgen(files []ast.File, table &table.Table) string {
|
||||||
g.write_variadic_types()
|
g.write_variadic_types()
|
||||||
// g.write_str_definitions()
|
// g.write_str_definitions()
|
||||||
g.write_init_function()
|
g.write_init_function()
|
||||||
|
if g.is_test {
|
||||||
|
g.write_tests_main()
|
||||||
|
}
|
||||||
return g.typedefs.str() + g.definitions.str() + g.out.str()
|
return g.typedefs.str() + g.definitions.str() + g.out.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,6 +676,9 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
if g.autofree {
|
if g.autofree {
|
||||||
g.writeln('_vcleanup();')
|
g.writeln('_vcleanup();')
|
||||||
}
|
}
|
||||||
|
if g.is_test {
|
||||||
|
verror('test files cannot have function `main`')
|
||||||
|
}
|
||||||
g.writeln('return 0;')
|
g.writeln('return 0;')
|
||||||
}
|
}
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
|
@ -1283,27 +1293,30 @@ fn (g mut Gen) ident(node ast.Ident) {
|
||||||
}
|
}
|
||||||
if node.name.starts_with('C.') {
|
if node.name.starts_with('C.') {
|
||||||
g.write(node.name[2..].replace('.', '__'))
|
g.write(node.name[2..].replace('.', '__'))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
if node.kind == .constant && !node.name.starts_with('g_') {
|
||||||
name := c_name(node.name)
|
// TODO globals hack
|
||||||
// TODO `is`
|
g.write('_const_')
|
||||||
match node.info {
|
}
|
||||||
ast.IdentVar {
|
name := c_name(node.name)
|
||||||
// x ?int
|
// TODO `is`
|
||||||
// `x = 10` => `x.data = 10` (g.right_is_opt == false)
|
match node.info {
|
||||||
// `x = new_opt()` => `x = new_opt()` (g.right_is_opt == true)
|
ast.IdentVar {
|
||||||
// `println(x)` => `println(*(int*)x.data)`
|
// x ?int
|
||||||
if it.is_optional && !(g.is_assign_expr && g.right_is_opt) {
|
// `x = 10` => `x.data = 10` (g.right_is_opt == false)
|
||||||
g.write('/*opt*/')
|
// `x = new_opt()` => `x = new_opt()` (g.right_is_opt == true)
|
||||||
styp := g.typ(it.typ)[7..] // Option_int => int TODO perf?
|
// `println(x)` => `println(*(int*)x.data)`
|
||||||
g.write('(*($styp*)${name}.data)')
|
if it.is_optional && !(g.is_assign_expr && g.right_is_opt) {
|
||||||
return
|
g.write('/*opt*/')
|
||||||
}
|
styp := g.typ(it.typ)[7..] // Option_int => int TODO perf?
|
||||||
|
g.write('(*($styp*)${name}.data)')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {}
|
}
|
||||||
}
|
else {}
|
||||||
g.write(name)
|
|
||||||
}
|
}
|
||||||
|
g.write(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) if_expr(node ast.IfExpr) {
|
fn (g mut Gen) if_expr(node ast.IfExpr) {
|
||||||
|
@ -1574,15 +1587,15 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) {
|
||||||
// so that we don't pollute the binary with unnecessary global vars
|
// so that we don't pollute the binary with unnecessary global vars
|
||||||
// Do not do this when building a module, otherwise the consts
|
// Do not do this when building a module, otherwise the consts
|
||||||
// will not be accessible.
|
// will not be accessible.
|
||||||
g.definitions.write('#define $name ')
|
g.definitions.write('#define _const_$name ')
|
||||||
g.definitions.writeln(val)
|
g.definitions.writeln(val)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Initialize more complex consts in `void _vinit(){}`
|
// Initialize more complex consts in `void _vinit(){}`
|
||||||
// (C doesn't allow init expressions that can't be resolved at compile time).
|
// (C doesn't allow init expressions that can't be resolved at compile time).
|
||||||
styp := g.typ(field.typ)
|
styp := g.typ(field.typ)
|
||||||
g.definitions.writeln('$styp $name; // inited later') // = ')
|
g.definitions.writeln('$styp _const_$name; // inited later') // = ')
|
||||||
g.inits.write('$name = ')
|
g.inits.write('_const_$name = ')
|
||||||
g.inits.write(val)
|
g.inits.write(val)
|
||||||
g.inits.writeln(';')
|
g.inits.writeln(';')
|
||||||
}
|
}
|
||||||
|
@ -1719,7 +1732,7 @@ fn (g mut Gen) ref_or_deref_arg(arg ast.CallArg) {
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
println('cgen error: $s')
|
println('cgen error: $s')
|
||||||
// exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write_init_function() {
|
fn (g mut Gen) write_init_function() {
|
||||||
|
@ -1729,8 +1742,8 @@ fn (g mut Gen) write_init_function() {
|
||||||
if g.autofree {
|
if g.autofree {
|
||||||
g.writeln('void _vcleanup() {')
|
g.writeln('void _vcleanup() {')
|
||||||
g.writeln('puts("cleaning up...");')
|
g.writeln('puts("cleaning up...");')
|
||||||
g.writeln('free(os__args.data);')
|
g.writeln('free(_const_os__args.data);')
|
||||||
g.writeln('free(strconv__ftoa__powers_of_10.data);')
|
g.writeln('free(_const_strconv__ftoa__powers_of_10.data);')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2217,3 +2230,14 @@ fn (g &Gen) type_default(typ table.Type) string {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (g mut Gen) write_tests_main() {
|
||||||
|
g.writeln('int main() {')
|
||||||
|
for _, f in g.table.fns {
|
||||||
|
if !f.name.starts_with('test_') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.writeln('${f.name}();')
|
||||||
|
}
|
||||||
|
g.writeln('return 0; }')
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue