4 //! todo: type checking - maybe add more helper methods in Interpreter
9 static void make_mode(const std::string
& str
, std::ios_base::openmode
& dest
)
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
)
36 std::ios_base::openmode realmode
;
37 realmode
= std::ios::in
;
38 Table
<Interpreter::Value
> self
;
41 std::cerr
<< "File() expects 2 arguments" << std::endl
;
44 path
= stack
[1].string();
45 mode
= stack
[2].string();
46 make_mode(mode
, realmode
);
47 fh
= new std::fstream(path
, realmode
);
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
);
63 std::cerr
<< "fopen('" << path
<< "', '" << mode
<< "') failed" << std::endl
;
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();
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();
90 void rt_file_read(Interpreter
& ip
, std::vector
<Interpreter::Value
>& stack
)
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
)));
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
)
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
++)
127 void rt_file_println(Interpreter
& ip
, std::vector
<Interpreter::Value
>& stack
)
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
++)
140 void rt_file_write(Interpreter
& ip
, std::vector
<Interpreter::Value
>& stack
)
142 size_t write_this_much
;
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
));
163 void rt_file_writebyte(Interpreter
& ip
, std::vector
<Interpreter::Value
>& stack
)
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());