-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cpp
90 lines (78 loc) · 2.25 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <chrono>
#include "src/ami.h"
#include "src/lex.h"
#include "src/parse.h"
#include "src/vm/vm.h"
#include "src/vm/compile.h"
#include "src/vm/serialize.h"
size_t cur_ms() {
using namespace std::chrono;
return duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
).count();
}
void test_vm() {
size_t start, finish;
start = cur_ms();
auto lex = ami::lexer{"test.ami"};
auto toks = lex.lex();
finish = cur_ms();
size_t lex_time = finish - start;
start = cur_ms();
auto parse = ami::parser{toks};
auto ast = parse.global();
finish = cur_ms();
size_t parse_time = finish - start;
if (!ast.has_value()) throw std::runtime_error(ast.error());
std::ofstream("out.txt") << (*ast)->pretty(0);
start = cur_ms();
auto compile = ami::vm::compiler{ami::vm::value::function::type::script};
auto res = compile.global(ast->get());
finish = cur_ms();
size_t compile_time = finish - start;
if (!res.has_value()) throw std::runtime_error(res.error());
auto& fn = res.value();
fn.desc->chunk.disasm(std::cout);
std::cout << "\nvm: \n";
using namespace ami;
auto vm = vm::vm{fn};
using nt_ret = std::expected<vm::value, std::string>;
vm.def_native(
"log",
1,
[](std::span<vm::value> args) {
std::cout << args[0] << '\n';
return nt_ret{vm::value::nil{}};
});
vm.def_native(
"time",
0,
[](std::span<vm::value> args) {
using namespace std::chrono;
size_t ms = duration_cast<milliseconds>(
system_clock::now().time_since_epoch()
).count();
return nt_ret{vm::value{double(ms)}};
});
vm.def_native(
"to_str",
1,
[](std::span<vm::value> args) {
return nt_ret{vm::value{vm::value::str{args[0].to_string()}}};
});
start = cur_ms();
auto interp_res = vm.run(std::cout);
finish = cur_ms();
size_t run_time = finish - start;
if (!interp_res.has_value()) throw std::runtime_error(interp_res.error());
std::cout << "\n\n\n";
std::cout << "lex took " << lex_time << "ms" << '\n';
std::cout << "parse took " << parse_time << "ms" << '\n';
std::cout << "compile took " << compile_time << "ms" << '\n';
std::cout << "run took " << run_time << "ms" << '\n';
}
int main() {
test_vm();
return 0;
}