107 lines
3.2 KiB
C++
107 lines
3.2 KiB
C++
/*
|
||
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
|
||
Author: Leonardo de Moura
|
||
*/
|
||
#include <iostream>
|
||
#include <chrono>
|
||
#include <iomanip>
|
||
#include "runtime/io.h"
|
||
#include "runtime/allocprof.h"
|
||
namespace lean {
|
||
static obj_res const REAL_WORLD = box(0);
|
||
|
||
obj_res set_io_result(obj_arg r, obj_arg a) {
|
||
if (is_exclusive(r)) {
|
||
cnstr_set(r, 0, a);
|
||
return r;
|
||
} else {
|
||
dec_ref(r);
|
||
object * new_r = alloc_cnstr(0, 2, 0);
|
||
cnstr_set(new_r, 0, a);
|
||
cnstr_set(new_r, 1, REAL_WORLD);
|
||
return new_r;
|
||
}
|
||
}
|
||
static obj_res option_of_io_result(obj_arg r) {
|
||
if (io_is_result_ok(r)) {
|
||
object * o = alloc_cnstr(1, 1, 0);
|
||
cnstr_set(o, 0, io_get_result(r));
|
||
dec(r);
|
||
return o;
|
||
} else {
|
||
dec(r);
|
||
return box(0);
|
||
}
|
||
}
|
||
|
||
extern "C" obj_res lean_io_prim_put_str(b_obj_arg s, obj_arg r) {
|
||
std::cout << string_to_std(s); // TODO(Leo): use out handle
|
||
return set_io_result(r, box(0));
|
||
}
|
||
|
||
extern "C" obj_res lean_io_prim_get_line(obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* handle.mk (s : string) (m : mode) (bin : bool := ff) : eio handle */
|
||
extern "C" obj_res lean_io_prim_handle_mk(b_obj_arg /* s */, uint8 /* mode */, uint8 /* bin */, obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* handle.is_eof : handle → eio bool */
|
||
extern "C" obj_res lean_io_prim_handle_is_eof(b_obj_arg /* h */, obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* handle.flush : handle → eio bool */
|
||
extern "C" obj_res lean_io_prim_handle_flush(b_obj_arg /* h */, obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* handle.close : handle → eio unit */
|
||
extern "C" obj_res lean_io_prim_handle_close(b_obj_arg /* h */, obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* handle.get_line : handle → eio unit */
|
||
extern "C" obj_res lean_io_prim_handle_get_line(b_obj_arg /* h */, obj_arg /* w */) {
|
||
// not implemented yet
|
||
lean_unreachable();
|
||
}
|
||
|
||
/* constant unsafe_io {α : Type} (fn : io α) : option α */
|
||
extern "C" obj_res lean_io_unsafe(obj_arg, obj_arg fn) {
|
||
object * r = io_mk_world();
|
||
return option_of_io_result(apply_1(fn, r));
|
||
}
|
||
|
||
/* timeit {α : Type} (msg : @& string) (fn : io α) : io α */
|
||
extern "C" obj_res lean_io_timeit(obj_arg, b_obj_arg msg, obj_arg fn, obj_arg r) {
|
||
auto start = std::chrono::steady_clock::now();
|
||
r = apply_1(fn, r);
|
||
auto end = std::chrono::steady_clock::now();
|
||
auto diff = std::chrono::duration<double>(end - start);
|
||
std::ostream & out = std::cerr; // TODO(Leo): replace?
|
||
out << std::setprecision(3);
|
||
if (diff < std::chrono::duration<double>(1)) {
|
||
out << string_cstr(msg) << " " << std::chrono::duration<double, std::milli>(diff).count() << "ms\n";
|
||
} else {
|
||
out << string_cstr(msg) << " " << diff.count() << "s\n";
|
||
}
|
||
return r;
|
||
}
|
||
|
||
/* allocprof {α : Type} (msg : string) (fn : io α) : io α */
|
||
extern "C" obj_res lean_io_allocprof(obj_arg, b_obj_arg msg, obj_arg fn, obj_arg r) {
|
||
std::ostream & out = std::cerr; // TODO(Leo): replace?
|
||
allocprof prof(out, string_cstr(msg));
|
||
return apply_1(fn, r);
|
||
}
|
||
}
|