`if .. else if ..` can now be used as a primary expression (i.e., `println(if(1 ...
[aqualang.git] / src / stdlib.file.cpp
blob3ac81a2cd8824e45e5c4768a73a8a6b496ef2565
2 #include "private.h"
3 #include "builtin.h"
5 //! todo: type checking - maybe add more helper methods in Interpreter
7 namespace Aqua
9 namespace Builtins
11 static void make_mode(const std::string& str, std::ios_base::openmode& dest)
13 // laaaaazy
14 if(str == "r")
16 dest = std::ios::in;
20 OBJMEMBER_PROTO(File, constructor, ip, stack)
22 std::cerr << "in File::constructor" << std::endl;
23 std::string path;
24 std::string mode;
25 std::ios_base::openmode realmode;
26 realmode = std::ios::in;
27 Table<Interpreter::Value> self;
28 if(stack.empty())
30 std::cerr << "File() expects 2 arguments" << std::endl;
31 return;
33 path = stack[1].string();
34 mode = stack[2].string();
35 make_mode(mode, realmode);
36 auto fh = new std::fstream(path, realmode);
37 if(fh->good())
39 fprintf(stderr, "File.constructor: fh=%p\n", fh);
40 // create "self" object - similar concept as in Javascript
41 auto tb = ip.makeTable();
42 tb->set(ID_HANDLE, ip.makeUserPointer(fh));
43 for(auto pair: FileMembers)
45 tb->set(pair.first, ip.makeFunction(pair.second));
47 stack.emplace_back(tb);
48 return;
50 else
52 std::cerr << "fopen('" << path << "', '" << mode << "') failed" << std::endl;
53 stack.clear();
54 return;
59 OBJMEMBER_PROTO(File, proto_typeof, ip, stack)
61 stack.emplace_back(ip.makeString("file"));
64 OBJMEMBER_PROTO(File, close, ip, stack)
66 (void)ip;
67 auto self = stack[0].table();
68 auto fh = (std::fstream*)self->get(ID_HANDLE).userptr();
69 delete fh;
72 OBJMEMBER_PROTO(File, flush, ip, stack)
74 (void)ip;
75 auto self = stack[0].table();
76 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
77 (*fh) << std::flush;
81 OBJMEMBER_PROTO(File, read, ip, stack)
83 char* buffer;
84 size_t bufsize;
85 size_t realsize;
86 auto self = stack[0].table();
87 auto fh = (std::istream*)self->get(ID_HANDLE).userptr();
88 bufsize = size_t(stack[1].number());
89 buffer = new char[bufsize + 1];
90 fh->read(buffer, bufsize);
91 realsize = fh->gcount();
92 stack.emplace_back(ip.makeString(std::string(buffer, realsize)));
93 delete[] buffer;
94 return;
97 OBJMEMBER_PROTO(File, readAll, ip, stack)
99 auto self = stack[0].table();
100 auto fh = (std::istream*)self->get(ID_HANDLE).userptr();
101 std::string filestr((std::istreambuf_iterator<char>(*fh)), (std::istreambuf_iterator<char>()));
102 stack.emplace_back(ip.makeString(filestr));
103 return;
106 OBJMEMBER_PROTO(File, readChar, ip, stack)
108 (void)ip;
109 (void)stack;
112 OBJMEMBER_PROTO(File, readByte, ip, stack)
114 (void)ip;
115 (void)stack;
118 OBJMEMBER_PROTO(File, readLines, ip, stack)
120 (void)ip;
121 (void)stack;
124 OBJMEMBER_PROTO(File, readLine, ip, stack)
126 (void)ip;
127 (void)stack;
130 OBJMEMBER_PROTO(File, print, ip, stack)
132 (void)ip;
133 auto self = stack[0].table();
134 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
135 for(size_t i=1; i<stack.size(); i++)
137 (*fh) << stack[i];
139 stack.clear();
142 OBJMEMBER_PROTO(File, println, ip, stack)
144 (void)ip;
145 auto self = stack[0].table();
146 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
147 for(size_t i=1; i<stack.size(); i++)
149 (*fh) << stack[i];
151 (*fh) << std::endl;
152 stack.clear();
155 OBJMEMBER_PROTO(File, write, ip, stack)
157 size_t write_this_much;
158 size_t writtensize;
159 size_t before;
160 Interpreter::Value raw_thismuch;
161 Interpreter::Value chunk;
162 if((ip.needString(stack[1], chunk)) && ip.needNumber(stack[2], raw_thismuch))
164 auto self = stack[0].table();
165 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
166 before = fh->tellp();
167 write_this_much = size_t(raw_thismuch.number());
168 if(fh->write(chunk.string().data(), write_this_much))
170 writtensize = (size_t(fh->tellp()) - before);
171 stack.emplace_back(ip.makeNumber(writtensize));
172 return;
175 stack.clear();
178 OBJMEMBER_PROTO(File, writeByte, ip, stack)
180 Interpreter::Value thing;
181 auto self = stack[0].table();
182 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
183 if(ip.needNumber(stack[1], thing))
185 (*fh) << char(thing.number());
187 stack.clear();