16 if (operand.size() == 2) {
17 std::string &filename = operand[0].op;
18 std::string &mode = operand[1].op;
22 throw mx::Exception(
"Requires string variable type for fopen.\n");
31 throw mx::Exception(
"Requires string variable type for fopen.\n");
38 program->
vars[
"%rax"].var_name =
"%rax";
39 program->
vars[
"%rax"].var_value.ptr_value = (
void *)fopen(filename.c_str(), mode.c_str());
46 if (operand.size() < 2) {
47 throw mx::Exception(
"Requires at least two arguments for fprintf.");
50 std::vector<mxvm::Variable *> v;
51 for (
size_t i = 2; i < operand.size(); ++i) {
65 throw mx::Exception(
"fprintf requires format to be a string.");
71 fprintf(fptr,
"%s", value.c_str());
74 throw mx::Exception(
"fprintf requires format to be a variable");
77 throw mx::Exception(
"fprintf requires first argument to be valid variable found: " + operand[0].op);
82 if (operand.size() != 1) {
83 throw mx::Exception(
"fclose requires a single file pointer argument.");
85 std::string &file_var = operand[0].op;
87 throw mx::Exception(
"fclose argument must be a variable (file pointer).");
91 throw mx::Exception(
"fclose argument must be a pointer variable.");
94 int result = fclose(fp);
97 program->
vars[
"%rax"].var_value.int_value = result;
101 if (operand.size() != 1) {
102 throw mx::Exception(
"fsize requires a single file pointer argument.");
104 std::string &file_var = operand[0].op;
106 throw mx::Exception(
"fsize argument must be a variable pointer.");
110 throw mx::Exception(
"fsize argument must be a pointer variable.");
114 throw mx::Exception(
"Error pointer handle must not be null");
116 fseek(fptr, 0, SEEK_END);
117 size_t result = ftell(fptr);
118 fseek(fptr, 0, SEEK_SET);
121 program->
vars[
"%rax"].var_value.int_value = result;
125 if (operand.size() != 4) {
128 std::string &buf_var = operand[0].op;
130 throw mx::Exception(
"fread argument must be a variable pointer.");
134 throw mx::Exception(
"fread argument must be a pointer variable.");
143 throw mx::Exception(
"Argument type mismatch expected integer for fread");
146 throw mx::Exception(
"Final argument for fread requires pointer");
152 program->
vars[
"%rax"].var_value.int_value = result;
156 if (operand.size() != 4) {
159 std::string &buf_var = operand[0].op;
161 throw mx::Exception(
"fwrite argument must be a variable pointer.");
165 throw mx::Exception(
"fwrite argument must be a pointer variable.");
174 throw mx::Exception(
"Argument type mismatch expected integer for fwrite");
177 throw mx::Exception(
"Final argument for fwrite requires pointer");
183 program->
vars[
"%rax"].var_value.int_value = result;
187 if (operand.size() != 3) {
188 throw mx::Exception(
"fseek requires three arguments got: " + std::to_string(operand.size()));
190 std::string &buf_var = operand[0].op;
192 throw mx::Exception(
"fseek argument must be a variable found: " + buf_var);
196 throw mx::Exception(
"fseek argument must be a pointer variable.");
205 throw mx::Exception(
"Argument type mismatch expec ted integer for fread");
208 throw mx::Exception(
"Final argument for fread requires pointer");
214 program->
vars[
"%rax"].var_value.int_value = result;
218 if (operand.size() != 1) {
219 throw mx::Exception(
"rand_number requires one argument (size).");
225 throw mx::Exception(
"rand_number argument must be integer (size).");
231 rsize = std::stoll(operand[0].op,
nullptr, 0);
233 throw mx::Exception(
"rand_number expected variable or constant: " + operand[0].op);
236 throw mx::Exception(
"rand_number: size must be positive, got " + std::to_string(rsize));
238 int result = std::rand() % rsize;
241 program->
vars[
"%rax"].var_value.int_value = result;
245 auto now = std::chrono::high_resolution_clock::now().time_since_epoch().count();
246 uint64_t mixed =
static_cast<uint64_t
>(now);
247 mixed ^=
static_cast<uint64_t
>(
reinterpret_cast<std::uintptr_t
>(program));
248 mixed ^= (mixed >> 33);
249 mixed *= 0xff51afd7ed558ccdULL;
250 mixed ^= (mixed >> 33);
251 mixed *= 0xc4ceb9fe1a85ec53ULL;
252 mixed ^= (mixed >> 33);
253 std::srand(
static_cast<unsigned int>(mixed));
256 program->
vars[
"%rax"].var_value.int_value = 0;
261 if (operand.size() != 1) {
262 throw mx::Exception(
"feof requires one file pointer argument.");
264 std::string &file_var = operand[0].op;
266 throw mx::Exception(
"feof argument must be a variable (file pointer).");
270 throw mx::Exception(
"feof argument must be a pointer variable.");
273 int result = feof(fp) ? 1 : 0;
276 program->
vars[
"%rax"].var_value.int_value = result;
280 if (operand.size() != 1) {
281 throw mx::Exception(
"mxvm_fgets requires one file pointer argument.");
283 std::string &file_var = operand[0].op;
285 throw mx::Exception(
"fgets argument must be a variable (file pointer).");
289 throw mx::Exception(
"fgets argument must be a pointer variable.");
293 char *res = fgets(buf,
sizeof(buf), fp);
295 size_t len = strlen(buf);
296 if (len > 0 && buf[len - 1] ==
'\n')
298 char *str = strdup(buf);
301 program->
vars[
"%rax"].var_value.str_value = str;
305 program->
vars[
"%rax"].var_value.str_value = strdup(
"");
310 if (operand.size() != 2) {
311 throw mx::Exception(
"fputs requires two arguments (string, file).");
319 throw mx::Exception(
"fputs first argument must be a string variable.");
322 throw mx::Exception(
"fputs first argument must be a variable.");
324 std::string &file_var = operand[1].op;
326 throw mx::Exception(
"fputs second argument must be a variable (file pointer).");
330 throw mx::Exception(
"fputs second argument must be a pointer variable.");
333 int result = fputs(str_val.c_str(), fp);
336 program->
vars[
"%rax"].var_value.int_value = result;
General-purpose exception with errno-aware factory method.
std::unordered_map< std::string, Variable > vars
variable symbol table
Complete MXVM program: instruction interpreter and native x64 code generator.
Variable createTempVariable(VarType type, const std::string &value)
Create a temporary unnamed variable with the given type and value.
Variable & getVariable(const std::string &name)
Look up a variable by name, searching local scope then global.
bool isVariable(const std::string &name)
Check whether a variable exists in local or global scope.
Variable variableFromOperand(const Operand &op)
Resolve an Operand to its corresponding Variable.
std::string printFormatted(const std::string &format, const std::vector< Variable * > &args, bool output=true)
Format and optionally print a printf-style format string with variable arguments.
Intermediate code representation, execution engine, and native x64 code generation (SysV + Win64).
Instruction set enum, operand/instruction structs, variable types, and Variable/Variable_Value defini...
void mxvm_io_seed_random(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fsize(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_feof(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fwrite(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fopen(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_rand_number(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fread(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fprintf(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fputs(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fclose(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_mxvm_fgets(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
void mxvm_io_fseek(mxvm::Program *program, std::vector< mxvm::Operand > &operand)
A named variable with type, value, and optional object association.