-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparaio.cpp
More file actions
100 lines (76 loc) · 2.07 KB
/
paraio.cpp
File metadata and controls
100 lines (76 loc) · 2.07 KB
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
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <new>
#include <stdexcept>
#include "paraio.hpp"
extern "C" ParaValue paracl_in()
{
int value = 0;
std::cin >> value;
if (std::cin.fail())
throw std::runtime_error("Incorrect input");
return paracl_int(value);
}
extern "C" void paracl_print(ParaValue v)
{
if (v.tag != PARA_INT)
throw std::runtime_error("Cannot print non-int value yet");
std::cout << v.int_value << '\n';
}
extern "C" ParaValue paracl_int(int32_t x)
{
ParaValue v{};
v.tag = PARA_INT;
v.int_value = x;
return v;
}
extern "C" int32_t paracl_as_int(ParaValue v)
{
if (v.tag != PARA_INT)
throw std::runtime_error("Type error: expected int value");
return v.int_value;
}
extern "C" ParaClosure* paracl_closure(ParaCodePtr code, void* env)
{
if (!code)
throw std::runtime_error("Cannot create closure with null code pointer");
ParaClosure* closure = new ParaClosure{};
closure->code = code;
closure->env = env;
return closure;
}
extern "C" ParaValue paracl_closure_value(ParaClosure* closure)
{
if (!closure)
throw std::runtime_error("Cannot wrap null closure");
ParaValue v{};
v.tag = PARA_CLOSURE;
v.closure_value = closure;
return v;
}
extern "C" ParaClosure* paracl_as_closure(ParaValue v)
{
if (v.tag != PARA_CLOSURE)
throw std::runtime_error("Type error: expected function/closure value");
return v.closure_value;
}
extern "C" void* paracl_env_alloc(std::size_t size)
{
void* mem = std::calloc(1, size);
if (!mem)
throw std::bad_alloc();
return mem;
}
extern "C" ParaValue paracl_call(ParaClosure* closure, ParaValue* args, int32_t argc)
{
if (!closure)
throw std::runtime_error("Cannot call null closure");
if (!closure->code)
throw std::runtime_error("Closure has null code pointer");
return closure->code(closure, args, argc);
}
extern "C" void* paracl_env(ParaClosure* closure)
{
if (!closure)
throw std::runtime_error("Null closure in paracl_env");
return closure->env;
}