v2: more informative assert output; string interpolation formatting
parent
6892a3e0a8
commit
f489c89987
|
@ -99,7 +99,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
|
||||||
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
|
//////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
|
||||||
csymbols := backtrace_symbols(&buffer[skipframes], nr_actual_frames)
|
csymbols := backtrace_symbols(&buffer[skipframes], nr_actual_frames)
|
||||||
for i in 0 .. nr_actual_frames {
|
for i in 0 .. nr_actual_frames {
|
||||||
sframes << tos2(csymbols[i])
|
sframes << tos2( byteptr( voidptr(csymbols[i]) ) )
|
||||||
}
|
}
|
||||||
for sframe in sframes {
|
for sframe in sframes {
|
||||||
executable := sframe.all_before('(')
|
executable := sframe.all_before('(')
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
fn test_strip_margins_no_tabs() {
|
||||||
|
no_tabs := ['Hello there',
|
||||||
|
'This is a string',
|
||||||
|
'With multiple lines',
|
||||||
|
].join('\n')
|
||||||
|
no_tabs_stripped := 'Hello there
|
||||||
|
|This is a string
|
||||||
|
|With multiple lines'.strip_margin()
|
||||||
|
assert no_tabs == no_tabs_stripped
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_text_before() {
|
||||||
|
text_before := ['There is text',
|
||||||
|
'before the delimiter',
|
||||||
|
'that should be removed as well',
|
||||||
|
].join('\n')
|
||||||
|
text_before_stripped := 'There is text
|
||||||
|
f lasj asldfj j lksjdf |before the delimiter
|
||||||
|
Which is removed hello |that should be removed as well'.strip_margin()
|
||||||
|
assert text_before_stripped == text_before
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_white_space_after_delim() {
|
||||||
|
tabs := [' Tab',
|
||||||
|
' spaces',
|
||||||
|
' another tab',
|
||||||
|
].join('\n')
|
||||||
|
tabs_stripped := ' Tab
|
||||||
|
| spaces
|
||||||
|
| another tab'.strip_margin()
|
||||||
|
assert tabs == tabs_stripped
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_alternate_delim() {
|
||||||
|
alternate_delimiter := ['This has a different delim,',
|
||||||
|
'but that is ok',
|
||||||
|
'because everything works',
|
||||||
|
].join('\n')
|
||||||
|
alternate_delimiter_stripped := 'This has a different delim,
|
||||||
|
#but that is ok
|
||||||
|
#because everything works'.strip_margin(`#`)
|
||||||
|
assert alternate_delimiter_stripped == alternate_delimiter
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_multiple_delims_after_first() {
|
||||||
|
delim_after_first_instance := ['The delimiter used',
|
||||||
|
'only matters the |||| First time it is seen',
|
||||||
|
'not any | other | times',
|
||||||
|
].join('\n')
|
||||||
|
delim_after_first_instance_stripped := 'The delimiter used
|
||||||
|
|only matters the |||| First time it is seen
|
||||||
|
|not any | other | times'.strip_margin()
|
||||||
|
assert delim_after_first_instance_stripped == delim_after_first_instance
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_uneven_delims() {
|
||||||
|
uneven_delims := ['It doesn\'t matter if the delims are uneven,',
|
||||||
|
'The text will still be delimited correctly.',
|
||||||
|
'Maybe not everything needs 3 lines?',
|
||||||
|
'Let us go for 4 then',
|
||||||
|
].join('\n')
|
||||||
|
uneven_delims_stripped := 'It doesn\'t matter if the delims are uneven,
|
||||||
|
|The text will still be delimited correctly.
|
||||||
|
|Maybe not everything needs 3 lines?
|
||||||
|
|Let us go for 4 then'.strip_margin()
|
||||||
|
assert uneven_delims_stripped == uneven_delims
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_multiple_blank_lines() {
|
||||||
|
multi_blank_lines := ['Multiple blank lines will be removed.',
|
||||||
|
' I actually consider this a feature.',
|
||||||
|
].join('\n')
|
||||||
|
multi_blank_lines_stripped := 'Multiple blank lines will be removed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| I actually consider this a feature.'.strip_margin()
|
||||||
|
assert multi_blank_lines == multi_blank_lines_stripped
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_end_newline() {
|
||||||
|
end_with_newline := ['This line will end with a newline',
|
||||||
|
'Something cool or something.',
|
||||||
|
'',
|
||||||
|
].join('\n')
|
||||||
|
end_with_newline_stripped := 'This line will end with a newline
|
||||||
|
|Something cool or something.
|
||||||
|
|
||||||
|
'.strip_margin()
|
||||||
|
assert end_with_newline_stripped == end_with_newline
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_space_delimiter() {
|
||||||
|
space_delimiter := ['Using a white-space char will',
|
||||||
|
'revert back to default behavior.',
|
||||||
|
].join('\n')
|
||||||
|
space_delimiter_stripped := 'Using a white-space char will
|
||||||
|
|revert back to default behavior.'.strip_margin(`\n`)
|
||||||
|
assert space_delimiter == space_delimiter_stripped
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_strip_margins_crlf() {
|
||||||
|
crlf := ['This string\'s line endings have CR as well as LFs.',
|
||||||
|
'This should pass',
|
||||||
|
'Definitely',
|
||||||
|
].join('\r\n')
|
||||||
|
crlf_stripped := 'This string\'s line endings have CR as well as LFs.\r
|
||||||
|
|This should pass\r
|
||||||
|
|Definitely'.strip_margin()
|
||||||
|
|
||||||
|
assert crlf == crlf_stripped
|
||||||
|
}
|
|
@ -20,11 +20,6 @@ fn test_add() {
|
||||||
assert a.ends_with('bbbbb')
|
assert a.ends_with('bbbbb')
|
||||||
a += '123'
|
a += '123'
|
||||||
assert a.ends_with('3')
|
assert a.ends_with('3')
|
||||||
mut foo := Foo{10, 'hi'}
|
|
||||||
assert foo.str == 'hi'
|
|
||||||
assert foo.bar == 10
|
|
||||||
foo.str += '!'
|
|
||||||
assert foo.str == 'hi!'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_ends_with() {
|
fn test_ends_with() {
|
||||||
|
@ -481,20 +476,6 @@ fn test_reverse() {
|
||||||
assert 'a'.reverse() == 'a'
|
assert 'a'.reverse() == 'a'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (f Foo) baz() string {
|
|
||||||
return 'baz'
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_interpolation() {
|
|
||||||
num := 7
|
|
||||||
mut s := 'number=$num'
|
|
||||||
assert s == 'number=7'
|
|
||||||
foo := Foo{}
|
|
||||||
s = 'baz=${foo.baz()}'
|
|
||||||
assert s == 'baz=baz'
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_bytes_to_string() {
|
fn test_bytes_to_string() {
|
||||||
mut buf := vcalloc(10)
|
mut buf := vcalloc(10)
|
||||||
buf[0] = `h`
|
buf[0] = `h`
|
||||||
|
@ -703,115 +684,3 @@ fn test_split_into_lines() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_strip_margins_no_tabs() {
|
|
||||||
no_tabs := ['Hello there',
|
|
||||||
'This is a string',
|
|
||||||
'With multiple lines',
|
|
||||||
].join('\n')
|
|
||||||
no_tabs_stripped := 'Hello there
|
|
||||||
|This is a string
|
|
||||||
|With multiple lines'.strip_margin()
|
|
||||||
assert no_tabs == no_tabs_stripped
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_text_before() {
|
|
||||||
text_before := ['There is text',
|
|
||||||
'before the delimiter',
|
|
||||||
'that should be removed as well',
|
|
||||||
].join('\n')
|
|
||||||
text_before_stripped := 'There is text
|
|
||||||
f lasj asldfj j lksjdf |before the delimiter
|
|
||||||
Which is removed hello |that should be removed as well'.strip_margin()
|
|
||||||
assert text_before_stripped == text_before
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_white_space_after_delim() {
|
|
||||||
tabs := [' Tab',
|
|
||||||
' spaces',
|
|
||||||
' another tab',
|
|
||||||
].join('\n')
|
|
||||||
tabs_stripped := ' Tab
|
|
||||||
| spaces
|
|
||||||
| another tab'.strip_margin()
|
|
||||||
assert tabs == tabs_stripped
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_alternate_delim() {
|
|
||||||
alternate_delimiter := ['This has a different delim,',
|
|
||||||
'but that is ok',
|
|
||||||
'because everything works',
|
|
||||||
].join('\n')
|
|
||||||
alternate_delimiter_stripped := 'This has a different delim,
|
|
||||||
#but that is ok
|
|
||||||
#because everything works'.strip_margin(`#`)
|
|
||||||
assert alternate_delimiter_stripped == alternate_delimiter
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_multiple_delims_after_first() {
|
|
||||||
delim_after_first_instance := ['The delimiter used',
|
|
||||||
'only matters the |||| First time it is seen',
|
|
||||||
'not any | other | times',
|
|
||||||
].join('\n')
|
|
||||||
delim_after_first_instance_stripped := 'The delimiter used
|
|
||||||
|only matters the |||| First time it is seen
|
|
||||||
|not any | other | times'.strip_margin()
|
|
||||||
assert delim_after_first_instance_stripped == delim_after_first_instance
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_uneven_delims() {
|
|
||||||
uneven_delims := ['It doesn\'t matter if the delims are uneven,',
|
|
||||||
'The text will still be delimited correctly.',
|
|
||||||
'Maybe not everything needs 3 lines?',
|
|
||||||
'Let us go for 4 then',
|
|
||||||
].join('\n')
|
|
||||||
uneven_delims_stripped := 'It doesn\'t matter if the delims are uneven,
|
|
||||||
|The text will still be delimited correctly.
|
|
||||||
|Maybe not everything needs 3 lines?
|
|
||||||
|Let us go for 4 then'.strip_margin()
|
|
||||||
assert uneven_delims_stripped == uneven_delims
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_multiple_blank_lines() {
|
|
||||||
multi_blank_lines := ['Multiple blank lines will be removed.',
|
|
||||||
' I actually consider this a feature.',
|
|
||||||
].join('\n')
|
|
||||||
multi_blank_lines_stripped := 'Multiple blank lines will be removed.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| I actually consider this a feature.'.strip_margin()
|
|
||||||
assert multi_blank_lines == multi_blank_lines_stripped
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_end_newline() {
|
|
||||||
end_with_newline := ['This line will end with a newline',
|
|
||||||
'Something cool or something.',
|
|
||||||
'',
|
|
||||||
].join('\n')
|
|
||||||
end_with_newline_stripped := 'This line will end with a newline
|
|
||||||
|Something cool or something.
|
|
||||||
|
|
||||||
'.strip_margin()
|
|
||||||
assert end_with_newline_stripped == end_with_newline
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_space_delimiter() {
|
|
||||||
space_delimiter := ['Using a white-space char will',
|
|
||||||
'revert back to default behavior.',
|
|
||||||
].join('\n')
|
|
||||||
space_delimiter_stripped := 'Using a white-space char will
|
|
||||||
|revert back to default behavior.'.strip_margin(`\n`)
|
|
||||||
assert space_delimiter == space_delimiter_stripped
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_strip_margins_crlf() {
|
|
||||||
crlf := ['This string\'s line endings have CR as well as LFs.',
|
|
||||||
'This should pass',
|
|
||||||
'Definitely',
|
|
||||||
].join('\r\n')
|
|
||||||
crlf_stripped := 'This string\'s line endings have CR as well as LFs.\r
|
|
||||||
|This should pass\r
|
|
||||||
|Definitely'.strip_margin()
|
|
||||||
|
|
||||||
assert crlf == crlf_stripped
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +1,57 @@
|
||||||
|
fn test_simple_string_interpolation() {
|
||||||
fn test_simple_string_interpolation(){
|
|
||||||
a := 'Hello'
|
a := 'Hello'
|
||||||
b := 'World'
|
b := 'World'
|
||||||
res := '$a $b'
|
res := '$a $b'
|
||||||
assert res == 'Hello World'
|
assert res == 'Hello World'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_mixed_string_interpolation() {
|
||||||
|
num := 7
|
||||||
|
str := 'abc'
|
||||||
|
s1 := 'number=$num'
|
||||||
|
assert s1 == 'number=7'
|
||||||
|
s2 := 'string=$str'
|
||||||
|
assert s2 == 'string=abc'
|
||||||
|
s3 := 'a: $num | b: $str'
|
||||||
|
assert s3 == 'a: 7 | b: abc'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_formatted_string_interpolation() {
|
||||||
|
x := 'abc'
|
||||||
|
axb := 'a:$x:b'
|
||||||
|
assert axb == 'a:abc:b'
|
||||||
|
x_10 := 'a:${x:10s}:b'
|
||||||
|
x10_ := 'a:${x:-10s}:b'
|
||||||
|
assert x_10 == 'a: abc:b'
|
||||||
|
assert x10_ == 'a:abc :b'
|
||||||
|
i := 23
|
||||||
|
si_right := '${i:10d}'
|
||||||
|
si__left := '${i:-10d}'
|
||||||
|
assert si_right == ' 23'
|
||||||
|
assert si__left == '23 '
|
||||||
|
}
|
||||||
|
|
||||||
fn test_excape_dollar_in_string() {
|
fn test_excape_dollar_in_string() {
|
||||||
i := 42
|
i := 42
|
||||||
|
assert '($i)' == '(42)'
|
||||||
assert '($i)' == '(42)'
|
assert '(\$i)'.contains('i') && !'(\$i)'.contains('42')
|
||||||
assert '(\$i)'.contains('i') && !'(\$i)'.contains('42')
|
assert !'(\\$i)'.contains('i') && '(\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||||
assert !'(\\$i)'.contains('i') && '(\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
assert '(\\\$i)'.contains('i') && !'(\\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
||||||
assert '(\\\$i)'.contains('i') && !'(\\\$i)'.contains('42') && '(\\$i)'.contains('\\')
|
assert !'(\\\\$i)'.contains('i') && '(\\\\$i)'.contains('42') && '(\\\\$i)'.contains('\\\\')
|
||||||
assert !'(\\\\$i)'.contains('i') && '(\\\\$i)'.contains('42') && '(\\\\$i)'.contains('\\\\')
|
assert '(${i})' == '(42)'
|
||||||
|
assert '(\${i})'.contains('i') && !'(\${i})'.contains('42')
|
||||||
assert '(${i})' == '(42)'
|
assert !'(\\${i})'.contains('i') && '(\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||||
assert '(\${i})'.contains('i') && !'(\${i})'.contains('42')
|
assert '(\\\${i})'.contains('i') && !'(\\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
||||||
assert !'(\\${i})'.contains('i') && '(\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
assert !'(\\\\${i})'.contains('i') && '(\\\\${i})'.contains('42') && '(\\\\${i})'.contains('\\\\')
|
||||||
assert '(\\\${i})'.contains('i') && !'(\\\${i})'.contains('42') && '(\\${i})'.contains('\\')
|
assert i == 42
|
||||||
assert !'(\\\\${i})'.contains('i') && '(\\\\${i})'.contains('42') && '(\\\\${i})'.contains('\\\\')
|
|
||||||
assert i==42
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_implicit_str() {
|
fn test_implicit_str() {
|
||||||
i := 42
|
i := 42
|
||||||
assert 'int $i' == 'int 42'
|
assert 'int $i' == 'int 42'
|
||||||
assert '$i' == '42'
|
assert '$i' == '42'
|
||||||
|
check := '$i' == '42'
|
||||||
check := '$i' == '42'
|
assert check
|
||||||
assert check
|
text := '$i' + '42'
|
||||||
|
assert text == '4242'
|
||||||
text := '$i' + '42'
|
|
||||||
assert text == '4242'
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
bar int
|
||||||
|
mut:
|
||||||
|
str string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (f Foo) baz() string {
|
||||||
|
return 'baz'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_string_method_interpolation() {
|
||||||
|
foo := Foo{}
|
||||||
|
s := 'baz=${foo.baz()}'
|
||||||
|
assert s == 'baz=baz'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_adding_to_mutable_string_field() {
|
||||||
|
mut foo := Foo{10, 'hi'}
|
||||||
|
assert foo.bar == 10
|
||||||
|
assert foo.str == 'hi'
|
||||||
|
foo.str += '!'
|
||||||
|
eprintln( foo.str )
|
||||||
|
assert foo.str == 'hi!'
|
||||||
|
}
|
|
@ -59,6 +59,9 @@ pub fn (node &FnDecl) str(t &table.Table) string {
|
||||||
// string representaiton of expr
|
// string representaiton of expr
|
||||||
pub fn (x Expr) str() string {
|
pub fn (x Expr) str() string {
|
||||||
match x {
|
match x {
|
||||||
|
Ident {
|
||||||
|
return it.name
|
||||||
|
}
|
||||||
InfixExpr {
|
InfixExpr {
|
||||||
return '(${it.left.str()} $it.op.str() ${it.right.str()})'
|
return '(${it.left.str()} $it.op.str() ${it.right.str()})'
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,16 +269,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
// g.writeln('//// stmt start')
|
// g.writeln('//// stmt start')
|
||||||
match node {
|
match node {
|
||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
g.writeln('// assert')
|
g.gen_assert_stmt(it)
|
||||||
g.write('if ((')
|
|
||||||
g.expr(it.expr)
|
|
||||||
g.writeln(')) {')
|
|
||||||
g.writeln('g_test_oks++;')
|
|
||||||
// g.writeln('puts("OK $g.fn_decl.name");')
|
|
||||||
g.writeln('} else {')
|
|
||||||
g.writeln('g_test_fails++;')
|
|
||||||
g.writeln('puts("FAILED $g.fn_decl.name $it.pos.line_nr");')
|
|
||||||
g.writeln('}')
|
|
||||||
}
|
}
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
g.gen_assign_stmt(it)
|
g.gen_assign_stmt(it)
|
||||||
|
@ -522,6 +513,29 @@ fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type table.Type, exp_type table
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) {
|
||||||
|
g.writeln('// assert')
|
||||||
|
g.write('if( ')
|
||||||
|
g.expr(a.expr)
|
||||||
|
s_assertion := a.expr.str().replace('"', "\'")
|
||||||
|
g.write(' )')
|
||||||
|
if g.is_test {
|
||||||
|
g.writeln('{')
|
||||||
|
g.writeln(' g_test_oks++;')
|
||||||
|
// g.writeln(' println(_STR("OK ${g.file.path}:${a.pos.line_nr}: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||||
|
g.writeln('}else{')
|
||||||
|
g.writeln(' g_test_fails++;')
|
||||||
|
g.writeln(' eprintln(_STR("${g.file.path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||||
|
g.writeln(' exit(1);')
|
||||||
|
g.writeln('}')
|
||||||
|
} else {
|
||||||
|
g.writeln('{}else{')
|
||||||
|
g.writeln(' eprintln(_STR("${g.file.path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||||
|
g.writeln(' exit(1);')
|
||||||
|
g.writeln('}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
// g.write('/*assign_stmt*/')
|
// g.write('/*assign_stmt*/')
|
||||||
if assign_stmt.left.len > assign_stmt.right.len {
|
if assign_stmt.left.len > assign_stmt.right.len {
|
||||||
|
@ -537,7 +551,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
else {
|
else {
|
||||||
panic('expected call')
|
panic('expected call')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mr_var_name := 'mr_$assign_stmt.pos.pos'
|
mr_var_name := 'mr_$assign_stmt.pos.pos'
|
||||||
g.expr_var_name = mr_var_name
|
g.expr_var_name = mr_var_name
|
||||||
if table.type_is_optional(return_type) {
|
if table.type_is_optional(return_type) {
|
||||||
|
@ -738,9 +752,9 @@ fn (g mut Gen) free_scope_vars(pos int) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.writeln('// other' + t)
|
g.writeln('// other ' + t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.writeln('string_free($var.name); // autofreed')
|
g.writeln('string_free($var.name); // autofreed')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2031,24 +2045,39 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
// }
|
// }
|
||||||
// else {}
|
// else {}
|
||||||
// }
|
// }
|
||||||
if node.expr_types[i] == table.string_type {
|
|
||||||
|
sfmt := node.expr_fmts[i]
|
||||||
|
if sfmt.len > 0 {
|
||||||
|
fspec := sfmt[sfmt.len-1]
|
||||||
|
if fspec == `s` && node.expr_types[i] != table.string_type {
|
||||||
|
verror('only V strings can be formatted with a ${sfmt} format')
|
||||||
|
}
|
||||||
|
g.write('%' + sfmt[1..])
|
||||||
|
}else if node.expr_types[i] == table.string_type {
|
||||||
g.write('%.*s')
|
g.write('%.*s')
|
||||||
}
|
}else {
|
||||||
else if node.expr_types[i] == table.int_type {
|
|
||||||
g.write('%d')
|
g.write('%d')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.write('", ')
|
g.write('", ')
|
||||||
// Build args
|
// Build args
|
||||||
for i, expr in node.exprs {
|
for i, expr in node.exprs {
|
||||||
if node.expr_types[i] == table.string_type {
|
sfmt := node.expr_fmts[i]
|
||||||
|
if sfmt.len > 0 {
|
||||||
|
fspec := sfmt[sfmt.len-1]
|
||||||
|
if fspec == `s` && node.expr_types[i] == table.string_type {
|
||||||
|
g.expr(expr)
|
||||||
|
g.write('.str')
|
||||||
|
}else{
|
||||||
|
g.expr(expr)
|
||||||
|
}
|
||||||
|
} else if node.expr_types[i] == table.string_type {
|
||||||
// `name.str, name.len,`
|
// `name.str, name.len,`
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write('.len, ')
|
g.write('.len, ')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write('.str')
|
g.write('.str')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
}
|
}
|
||||||
if i < node.exprs.len - 1 {
|
if i < node.exprs.len - 1 {
|
||||||
|
@ -2366,15 +2395,36 @@ fn (g &Gen) type_default(typ table.Type) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g mut Gen) write_tests_main() {
|
pub fn (g mut Gen) write_tests_main() {
|
||||||
|
g.definitions.writeln('int g_test_oks = 0;')
|
||||||
|
g.definitions.writeln('int g_test_fails = 0;')
|
||||||
g.writeln('int main() {')
|
g.writeln('int main() {')
|
||||||
g.writeln('\t_vinit();')
|
g.writeln('\t_vinit();')
|
||||||
|
mut tfuncs := []string
|
||||||
|
mut tsuite_begin := ''
|
||||||
|
mut tsuite_end := ''
|
||||||
for _, f in g.table.fns {
|
for _, f in g.table.fns {
|
||||||
|
if f.name == 'testsuite_begin' {
|
||||||
|
tsuite_begin = f.name
|
||||||
|
}
|
||||||
|
if f.name == 'testsuite_end' {
|
||||||
|
tsuite_end = f.name
|
||||||
|
}
|
||||||
if !f.name.starts_with('test_') {
|
if !f.name.starts_with('test_') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
g.writeln('\t${f.name}();')
|
tfuncs << f.name
|
||||||
}
|
}
|
||||||
g.writeln('return 0; }')
|
if tsuite_begin.len > 0 {
|
||||||
|
g.writeln('\t${tsuite_begin}();\n')
|
||||||
|
}
|
||||||
|
for t in tfuncs {
|
||||||
|
g.writeln('\t${t}();')
|
||||||
|
}
|
||||||
|
if tsuite_end.len > 0 {
|
||||||
|
g.writeln('\t${tsuite_end}();\n')
|
||||||
|
}
|
||||||
|
g.writeln('\treturn 0;')
|
||||||
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g &Gen) is_importing_os() bool {
|
fn (g &Gen) is_importing_os() bool {
|
||||||
|
|
|
@ -186,8 +186,6 @@ extern wchar_t **_wenviron;
|
||||||
|
|
||||||
//================================== GLOBALS =================================*/
|
//================================== GLOBALS =================================*/
|
||||||
byte g_str_buf[1024];
|
byte g_str_buf[1024];
|
||||||
int g_test_fails = 0;
|
|
||||||
int g_test_oks = 0;
|
|
||||||
int load_so(byteptr);
|
int load_so(byteptr);
|
||||||
void reload_so();
|
void reload_so();
|
||||||
void _vinit();
|
void _vinit();
|
||||||
|
|
Loading…
Reference in New Issue