native: add support for print, eprint and eprintln (#11034)
parent
80976e640c
commit
00d4c7082e
|
@ -346,7 +346,7 @@ pub fn execute(cmd string) Result {
|
|||
// if cmd.contains(';') || cmd.contains('&&') || cmd.contains('||') || cmd.contains('\n') {
|
||||
// return Result{ exit_code: -1, output: ';, &&, || and \\n are not allowed in shell commands' }
|
||||
// }
|
||||
pcmd := '$cmd 2>&1'
|
||||
pcmd := if cmd.contains('2>') { cmd } else { '$cmd 2>&1' }
|
||||
f := vpopen(pcmd)
|
||||
if isnil(f) {
|
||||
return Result{
|
||||
|
|
|
@ -457,7 +457,7 @@ pub fn (mut g Gen) inline_strlen(r Register) {
|
|||
}
|
||||
|
||||
// TODO: strlen of string at runtime
|
||||
pub fn (mut g Gen) gen_print_reg(r Register, n int) {
|
||||
pub fn (mut g Gen) gen_print_reg(r Register, n int, fd int) {
|
||||
mystrlen := true
|
||||
g.mov_reg(.rsi, r)
|
||||
if mystrlen {
|
||||
|
@ -467,16 +467,16 @@ pub fn (mut g Gen) gen_print_reg(r Register, n int) {
|
|||
g.mov(.edx, n)
|
||||
}
|
||||
g.mov(.eax, g.nsyscall_write())
|
||||
g.mov(.edi, 1)
|
||||
g.mov(.edi, fd)
|
||||
g.syscall()
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_print(s string) {
|
||||
pub fn (mut g Gen) gen_print(s string, fd int) {
|
||||
//
|
||||
// qq := s + '\n'
|
||||
//
|
||||
g.mov(.eax, g.nsyscall_write())
|
||||
g.mov(.edi, 1)
|
||||
g.mov(.edi, fd)
|
||||
// segment_start + 0x9f) // str pos // placeholder
|
||||
g.mov64(.rsi, g.allocate_string(s, 2)) // for rsi its 2
|
||||
g.mov(.edx, s.len) // len
|
||||
|
|
|
@ -12,7 +12,7 @@ import v.errors
|
|||
import v.pref
|
||||
import term
|
||||
|
||||
pub const builtins = ['println', 'exit']
|
||||
pub const builtins = ['print', 'eprint', 'println', 'eprintln', 'exit']
|
||||
|
||||
interface CodeGen {
|
||||
mut:
|
||||
|
@ -227,22 +227,24 @@ fn (mut g Gen) get_var_offset(var_name string) int {
|
|||
return offset
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, newline bool) {
|
||||
pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) {
|
||||
newline := name in ['println', 'eprintln']
|
||||
fd := if name in ['eprint', 'eprintln'] { 2 } else { 1 }
|
||||
match expr {
|
||||
ast.StringLiteral {
|
||||
if newline {
|
||||
g.gen_print(expr.val + '\n')
|
||||
g.gen_print(expr.val + '\n', fd)
|
||||
} else {
|
||||
g.gen_print(expr.val)
|
||||
g.gen_print(expr.val, fd)
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
g.call_fn(expr)
|
||||
g.gen_print_reg(.rax, 3)
|
||||
g.gen_print_reg(.rax, 3, fd)
|
||||
}
|
||||
ast.Ident {
|
||||
g.expr(expr)
|
||||
g.gen_print_reg(.rax, 3)
|
||||
g.gen_print_reg(.rax, 3, fd)
|
||||
}
|
||||
else {
|
||||
dump(typeof(expr).name)
|
||||
|
@ -389,7 +391,7 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
}
|
||||
if node.name in ['println', 'print', 'eprintln', 'eprint'] {
|
||||
expr := node.args[0].expr
|
||||
g.gen_print_from_expr(expr, node.name in ['println', 'eprintln'])
|
||||
g.gen_print_from_expr(expr, node.name)
|
||||
return
|
||||
}
|
||||
g.call_fn(node)
|
||||
|
|
|
@ -46,7 +46,8 @@ fn test_native() {
|
|||
eprintln(bench.step_message_fail(cmd))
|
||||
continue
|
||||
}
|
||||
res := os.execute(exe_test_path)
|
||||
tmperrfile := '$dir/${test}.tmperr'
|
||||
res := os.execute('$exe_test_path 2> $tmperrfile')
|
||||
if res.exit_code != 0 {
|
||||
bench.fail()
|
||||
eprintln(bench.step_message_fail('$full_test_path failed to run'))
|
||||
|
@ -54,6 +55,24 @@ fn test_native() {
|
|||
continue
|
||||
}
|
||||
mut expected := os.read_file('$dir/${test}.out') or { panic(err) }
|
||||
errfile := '$dir/${test}.err'
|
||||
if os.exists(errfile) {
|
||||
mut err_expected := os.read_file('$dir/${test}.err') or { panic(err) }
|
||||
err_expected = err_expected.trim_right('\r\n').replace('\r\n', '\n')
|
||||
errstr := os.read_file(tmperrfile) or { panic(err) }
|
||||
mut err_found := errstr.trim_right('\r\n').replace('\r\n', '\n')
|
||||
if err_expected != err_found {
|
||||
println(term.red('FAIL'))
|
||||
println('============')
|
||||
println('stderr expected: "$err_expected" len=$err_expected.len')
|
||||
println('============')
|
||||
println('stderr found:"$err_found" len=$err_found.len')
|
||||
println('============\n')
|
||||
bench.fail()
|
||||
continue
|
||||
}
|
||||
}
|
||||
os.rm(tmperrfile) or {}
|
||||
expected = expected.trim_right('\r\n').replace('\r\n', '\n')
|
||||
mut found := res.output.trim_right('\r\n').replace('\r\n', '\n')
|
||||
found = found.trim_space()
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
fn test_stdout() {
|
||||
print('Hello ')
|
||||
println('World')
|
||||
}
|
||||
|
||||
fn test_stderr() {
|
||||
eprint('2(Hello)')
|
||||
eprintln('2(World)')
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_stdout()
|
||||
test_stderr()
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
2(Hello)2(World)
|
|
@ -0,0 +1 @@
|
|||
Hello World
|
Loading…
Reference in New Issue