extended Interpreter with ::need* functions, also extended File functions
[aqualang.git] / src / stdlib.file.cpp
bloba775ce7ff9ee79ecd6743686462ee982ff75fa50
2 #include "private.h"
4 //! todo: type checking - maybe add more helper methods in Interpreter
7 namespace Stdlib
9 static void make_mode(const std::string& str, std::ios_base::openmode& dest)
11 // laaaaazy
12 if(str == "r")
14 dest = std::ios::in;
19 void rt_file_constructor(Interpreter& ip, std::vector<Interpreter::Value>& stack);
20 void rt_file_proto_typeof(Interpreter& ip, std::vector<Interpreter::Value>& stack);
21 void rt_file_close(Interpreter& ip, std::vector<Interpreter::Value>& stack);
22 void rt_file_read(Interpreter& ip, std::vector<Interpreter::Value>& stack);
23 void rt_file_readchar(Interpreter& ip, std::vector<Interpreter::Value>& stack);
24 void rt_file_readbyte(Interpreter& ip, std::vector<Interpreter::Value>& stack);
25 void rt_file_print(Interpreter& ip, std::vector<Interpreter::Value>& stack);
26 void rt_file_println(Interpreter& ip, std::vector<Interpreter::Value>& stack);
27 void rt_file_write(Interpreter& ip, std::vector<Interpreter::Value>& stack);
28 void rt_file_writebyte(Interpreter& ip, std::vector<Interpreter::Value>& stack);
31 void rt_file_constructor(Interpreter& ip, std::vector<Interpreter::Value>& stack)
33 std::fstream* fh;
34 std::string path;
35 std::string mode;
36 std::ios_base::openmode realmode;
37 realmode = std::ios::in;
38 Table<Interpreter::Value> self;
39 if(stack.empty())
41 std::cerr << "File() expects 2 arguments" << std::endl;
42 return;
44 path = stack[1].string();
45 mode = stack[2].string();
46 make_mode(mode, realmode);
47 fh = new std::fstream(path, realmode);
48 if(fh->good())
50 fprintf(stderr, "File.constructor: fh=%p\n", fh);
51 // create "self" object - similar concept as in Javascript
52 auto tb = ip.makeTable();
53 tb->set(ID_HANDLE, ip.makeUserPointer(fh));
54 for(auto pair: rtfile_functions)
56 tb->set(pair.first, ip.makeFunction(pair.second));
58 stack.emplace_back(tb);
59 return;
61 else
63 std::cerr << "fopen('" << path << "', '" << mode << "') failed" << std::endl;
64 stack.clear();
65 return;
70 void rt_file_proto_typeof(Interpreter& ip, std::vector<Interpreter::Value>& stack)
72 stack.emplace_back(ip.makeString("file"));
75 void rt_file_close(Interpreter&, std::vector<Interpreter::Value>& stack)
77 auto self = stack[0].table();
78 auto fh = (std::fstream*)self->get(ID_HANDLE).userptr();
79 delete fh;
82 void rt_file_flush(Interpreter& ip, std::vector<Interpreter::Value>& stack)
84 auto self = stack[0].table();
85 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
86 (*fh) << std::flush;
90 void rt_file_read(Interpreter& ip, std::vector<Interpreter::Value>& stack)
92 std::istream* fh;
93 char* buffer;
94 size_t bufsize;
95 size_t realsize;
96 auto self = stack[0].table();
97 fh = (std::istream*)self->get(ID_HANDLE).userptr();
98 bufsize = size_t(stack[1].number());
99 buffer = new char[bufsize + 1];
100 fh->read(buffer, bufsize);
101 realsize = fh->gcount();
102 stack.emplace_back(ip.makeString(std::string(buffer, realsize)));
103 delete[] buffer;
104 return;
107 void rt_file_readchar(Interpreter& ip, std::vector<Interpreter::Value>& stack)
111 void rt_file_readbyte(Interpreter& ip, std::vector<Interpreter::Value>& stack)
115 void rt_file_print(Interpreter& ip, std::vector<Interpreter::Value>& stack)
117 std::ostream* fh;
118 auto self = stack[0].table();
119 fh = (std::ostream*)self->get(ID_HANDLE).userptr();
120 for(size_t i=1; i<stack.size(); i++)
122 (*fh) << stack[i];
124 stack.clear();
127 void rt_file_println(Interpreter& ip, std::vector<Interpreter::Value>& stack)
129 std::ostream* fh;
130 auto self = stack[0].table();
131 fh = (std::ostream*)self->get(ID_HANDLE).userptr();
132 for(size_t i=1; i<stack.size(); i++)
134 (*fh) << stack[i];
136 (*fh) << std::endl;
137 stack.clear();
140 void rt_file_write(Interpreter& ip, std::vector<Interpreter::Value>& stack)
142 size_t write_this_much;
143 size_t writtensize;
144 size_t before;
145 Interpreter::Value raw_thismuch;
146 Interpreter::Value chunk;
147 if((ip.needString(stack[1], chunk)) && ip.needNumber(stack[2], raw_thismuch))
149 auto self = stack[0].table();
150 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
151 before = fh->tellp();
152 write_this_much = size_t(raw_thismuch.number());
153 if(fh->write(chunk.string().data(), write_this_much))
155 writtensize = (size_t(fh->tellp()) - before);
156 stack.emplace_back(ip.makeNumber(writtensize));
157 return;
160 stack.clear();
163 void rt_file_writebyte(Interpreter& ip, std::vector<Interpreter::Value>& stack)
165 size_t bytething;
166 Interpreter::Value thing;
167 auto self = stack[0].table();
168 auto fh = (std::ostream*)self->get(ID_HANDLE).userptr();
169 if(ip.needNumber(stack[1], thing))
171 (*fh) << char(thing.number());
173 stack.clear();