]>
Commit | Line | Data |
---|---|---|
057f943f JF |
1 | #define _GNU_SOURCE |
2 | ||
693d501b | 3 | #include <substrate.h> |
30ddc20c | 4 | #include "cycript.hpp" |
057f943f JF |
5 | |
6 | #include <cstdio> | |
7 | #include <sstream> | |
8 | ||
9 | #include <setjmp.h> | |
10 | ||
11 | #include <readline/readline.h> | |
12 | #include <readline/history.h> | |
13 | ||
14 | #include "Cycript.tab.hh" | |
15 | ||
16 | static jmp_buf ctrlc_; | |
17 | ||
18 | void sigint(int) { | |
19 | longjmp(ctrlc_, 1); | |
20 | } | |
21 | ||
22 | int main(int argc, const char *argv[]) { | |
1f8eae40 JF |
23 | bool bypass(false); |
24 | bool debug(false); | |
25 | ||
057f943f JF |
26 | FILE *fout(stdout); |
27 | ||
28 | rl_bind_key('\t', rl_insert); | |
29 | ||
30 | struct sigaction action; | |
31 | sigemptyset(&action.sa_mask); | |
32 | action.sa_handler = &sigint; | |
33 | action.sa_flags = 0; | |
34 | sigaction(SIGINT, &action, NULL); | |
35 | ||
36 | restart: for (;;) { | |
37 | std::string command; | |
38 | std::vector<std::string> lines; | |
39 | ||
931b816a JF |
40 | bool extra(false); |
41 | const char *prompt("cy# "); | |
42 | ||
057f943f JF |
43 | if (setjmp(ctrlc_) != 0) { |
44 | fputs("\n", fout); | |
45 | fflush(fout); | |
46 | goto restart; | |
47 | } | |
48 | ||
057f943f JF |
49 | read: |
50 | char *line(readline(prompt)); | |
51 | if (line == NULL) | |
52 | break; | |
931b816a JF |
53 | |
54 | if (!extra) { | |
55 | extra = true; | |
56 | if (line[0] == '\\') { | |
1f8eae40 JF |
57 | std::string data(line + 1); |
58 | if (data == "bypass") { | |
59 | bypass = !bypass; | |
60 | fprintf(fout, "bypass == %s\n", bypass ? "true" : "false"); | |
61 | fflush(fout); | |
62 | } else if (data == "debug") { | |
63 | debug = !debug; | |
64 | fprintf(fout, "debug == %s\n", debug ? "true" : "false"); | |
65 | fflush(fout); | |
66 | } | |
d35a3b07 | 67 | add_history(line); |
931b816a JF |
68 | goto restart; |
69 | } | |
70 | } | |
71 | ||
057f943f JF |
72 | lines.push_back(line); |
73 | command += line; | |
74 | free(line); | |
75 | ||
1f8eae40 JF |
76 | std::string code; |
77 | ||
78 | if (bypass) | |
79 | code = command; | |
80 | else { | |
81 | CYDriver driver(""); | |
82 | cy::parser parser(driver); | |
83 | ||
84 | driver.data_ = command.c_str(); | |
85 | driver.size_ = command.size(); | |
86 | ||
87 | if (parser.parse() != 0 || !driver.errors_.empty()) { | |
88 | for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i) { | |
89 | cy::position begin(i->location_.begin); | |
90 | if (begin.line != lines.size() || begin.column - 1 != lines.back().size()) { | |
91 | std::cerr << i->message_ << std::endl; | |
92 | add_history(command.c_str()); | |
93 | goto restart; | |
94 | } | |
95 | } | |
057f943f | 96 | |
1f8eae40 | 97 | driver.errors_.clear(); |
057f943f | 98 | |
1f8eae40 JF |
99 | command += '\n'; |
100 | prompt = "cy> "; | |
101 | goto read; | |
057f943f JF |
102 | } |
103 | ||
1f8eae40 JF |
104 | if (driver.source_ == NULL) |
105 | goto restart; | |
057f943f | 106 | |
1f8eae40 JF |
107 | std::ostringstream str; |
108 | driver.source_->Show(str); | |
109 | code = str.str(); | |
057f943f JF |
110 | } |
111 | ||
057f943f JF |
112 | add_history(command.c_str()); |
113 | ||
1f8eae40 JF |
114 | if (debug) |
115 | std::cout << code << std::endl; | |
057f943f JF |
116 | |
117 | _pooled | |
118 | ||
119 | JSStringRef script(JSStringCreateWithUTF8CString(code.c_str())); | |
120 | ||
121 | JSContextRef context(CYGetJSContext()); | |
122 | ||
123 | JSValueRef exception(NULL); | |
124 | JSValueRef result(JSEvaluateScript(context, script, NULL, NULL, 0, &exception)); | |
125 | JSStringRelease(script); | |
126 | ||
127 | if (exception != NULL) | |
128 | result = exception; | |
129 | ||
130 | if (JSValueIsUndefined(context, result)) | |
131 | goto restart; | |
132 | ||
133 | CFStringRef json; | |
134 | ||
135 | @try { json: | |
136 | json = CYCopyJSONString(context, result); | |
137 | } @catch (id error) { | |
138 | CYThrow(context, error, &result); | |
139 | goto json; | |
140 | } | |
141 | ||
142 | fputs([reinterpret_cast<const NSString *>(json) UTF8String], fout); | |
143 | CFRelease(json); | |
62ca2b82 | 144 | |
057f943f JF |
145 | fputs("\n", fout); |
146 | fflush(fout); | |
147 | } | |
62ca2b82 | 148 | |
057f943f JF |
149 | fputs("\n", fout); |
150 | fflush(fout); | |
e7ed5354 | 151 | |
057f943f | 152 | return 0; |
62ca2b82 | 153 | } |