Files
RCBASIC4/rcbasic_build/main.cpp
2024-05-20 09:14:32 -05:00

911 lines
27 KiB
C++
Executable File

#include <iostream>
#include <stack>
#include <vector>
#include <fstream>
#include <stdio.h>
#include <string>
#include "tokenizer.h"
#include "parser.h"
#include "rc_builtin.h"
#include "rc_vm_asm.h"
#include "file_directory.h"
#include "env_resolve.h"
#include "identifier.h"
using namespace std;
struct rc_src
{
string filename = "";
uint64_t line_number = 1;
uint64_t line_position = 0;
bool eof_reached = false;
uint64_t dbg_inc_index = 0;
};
stack<rc_src> rcbasic_program;
fstream rcbasic_file;
vector<string> inc_once;
bool rcbasic_build_debug = false;
uint64_t rcbasic_user_var_start = 0;
vector<string> inc_files;
void rcbasic_init()
{
//init built-in types here
init_embedded_types();
//init built-in functions here
block_state.push(BLOCK_STATE_MAIN);
current_block_state = BLOCK_STATE_MAIN;
current_scope = "main";
vm_asm.push_back(".code");
init_embedded_functions();
init_embedded_variables();
//cout << "numid_count = " << num_id_count << endl;
//cout << "strid_count = " << str_id_count << endl << endl;
block_state.push(BLOCK_STATE_MAIN);
current_block_state = BLOCK_STATE_MAIN;
isInFunctionScope = false;
current_scope = "main";
vm_asm.push_back(".code");
}
void rcbasic_dev_init()
{
//create_type("empty");
//init built-in functions here
block_state.push(BLOCK_STATE_MAIN);
current_block_state = BLOCK_STATE_MAIN;
current_scope = "main";
vm_asm.push_back(".code");
cout << "numid_count = " << num_id_count << endl;
cout << "strid_count = " << str_id_count << endl << endl;
block_state.push(BLOCK_STATE_MAIN);
current_block_state = BLOCK_STATE_MAIN;
isInFunctionScope = false;
current_scope = "main";
vm_asm.push_back(".code");
}
bool rcbasic_loadProgram(string src_file)
{
rc_src rc_program;
rc_program.filename = src_file;
rc_program.line_number = 1;
rc_program.line_position;
rc_program.dbg_inc_index = inc_files.size();
rcbasic_file.open(src_file.c_str(), fstream::in);
if(rcbasic_file.is_open())
{
rcbasic_program.push(rc_program);
inc_files.push_back(src_file);
return true;
}
return false;
}
bool rc_preprocessor()
{
rc_src inc_file;
if(tmp_token.size()>0)
{
if(tmp_token[0].compare("<include>")==0)
{
if(tmp_token.size() != 2)
{
rc_setError("Expected string literal or flag in INCLUDE");
return false;
}
//cout << "tmp_token[1] == " << tmp_token[1] << endl;
if(tmp_token[1].compare("<once>")==0)
{
tmp_token.clear();
inc_once.push_back(rcbasic_program.top().filename);
return true;
}
if(tmp_token[1].substr(0,8).compare("<string>")!=0)
{
rc_setError("Expected include file as string constant");
return false;
}
tmp_token[1] = resolveEnvironmentVariables(tmp_token[1]);
inc_file.filename = tmp_token[1].substr(8);
inc_file.filename = rc_absFilePath(inc_file.filename);
for(int i = 0; i < inc_once.size(); i++)
{
if(inc_once[i].compare(inc_file.filename)==0)
{
tmp_token.clear();
//cout << "DEBUG INC_ONCE: " << inc_file.filename << " can only be included once" << endl;
return true;
}
}
//cout << "\nDEBUG INCLUDE ABS_PATH:" << inc_file.filename << endl << endl;
inc_file.line_number = 0;
inc_file.line_position = 0;
inc_file.dbg_inc_index = inc_files.size();
rcbasic_file.close();
rcbasic_file.open(inc_file.filename.c_str(), fstream::in);
if(!rcbasic_file.is_open())
{
rc_setError("Could not open " + inc_file.filename);
return false;
}
//increase current file line number before pushing next file on stack
rcbasic_program.top().line_number++;
rcbasic_program.push(inc_file);
inc_files.push_back(inc_file.filename);
tmp_token.clear();
return true;
}
}
return true;
}
bool rc_eval(string line)
{
//adding an extra character to line to avoid a memory leak
line += " ";
ERROR_MSG = "";
clearRegs();
clearTokens();
byref_type_exception.clear();
if(line.compare("#var")==0)
{
output_vars();
return true;
}
//cout << "get tokens" << endl;
if(!tokens(line))
{
//cout << "Error1: " << rc_getError() << endl;
return false;
}
//current_Debug
//cout << "-------BEFORE PP START TOKENS--------" << endl;
//output_tokens();
//cout << "get preprocessor" << endl;
if(!rc_preprocessor())
{
return false;
}
//cout << "-------AFTER PP START TOKENS--------" << endl;
//output_tokens(); cout << endl;
//cout << "check rule" << endl;
//cout << "token: " << token[0] << endl;
int i = 0;
int dim_scope = 0;
bool is_dim_expr = false;
string dim_token = "";
for(i = 0; i < tmp_token.size(); i++)
{
if(tmp_token[i].compare("<dim>")==0 || tmp_token[i].compare("<redim>")==0)
{
dim_token = tmp_token[i];
dim_scope = 0;
is_dim_expr = true;
continue;
}
if(tmp_token[i].compare("<par>")==0 || tmp_token[i].compare("<square>")==0)
dim_scope++;
if(tmp_token[i].compare("</par>")==0 || tmp_token[i].compare("</square>")==0)
dim_scope--;
if(is_dim_expr==true && dim_scope==0 && tmp_token[i].compare("<comma>")==0)
{
tmp_token[i] = "<:>";
tmp_token.insert(tmp_token.begin()+ (i+1), dim_token);
}
if(tmp_token[i].compare("<:>")==0)
is_dim_expr = false;
}
i = 0;
while( i < tmp_token.size())
{
token.clear();
for(; i < tmp_token.size(); i++)
{
//cout << "start tmp_token loop :: ";
//cout << "i = " << i << " tmp_token_size = " << tmp_token.size() << endl;
if(tmp_token[i].compare("<:>")==0)
break;
//else if(!Array_Macros(i))
//{
// cout << "ERROR:" << rc_getError() << endl;
// return false;
//}
//cout << "### tmp_token[" << i << "] = ";
//cout << tmp_token[i] << endl;
token.push_back(tmp_token[i]);
}
i++;
//cout << "start rule" << endl;
if(!check_rule())
{
//cout << "ERROR:" << rc_getError() << endl;
return false;
}
}
if(byref_type_exception.size() > 0)
{
for(int i = 0; i < byref_type_exception.size(); i++)
{
//cout << "type exception: [" << byref_type_exception[i].tk_reg << "] exception_status = " << byref_type_exception[i].exception_used << endl;
if(!byref_type_exception[i].exception_used)
{
rc_setError(byref_type_exception[i].error_log);
return false;
}
}
}
return true;
//if(!eval_expression())
// cout << "Error2: " << rc_getError() << endl;
//cout << endl << endl << "----TOKENS-----" << endl;
//output_tokens();
//cout << endl << "VM CODE" << endl << endl;
//debug_output_VMASM();
//cout << "F_Error: " << rc_getError() << endl;
}
bool rc_eval_embedded(string line)
{
//adding an extra character to line to avoid a memory leak
line += " ";
ERROR_MSG = "";
clearRegs();
clearTokens();
if(line.compare("#var")==0)
{
output_vars();
}
if(!tokens(line))
{
cout << "Error1: " << rc_getError() << endl;
return false;
}
if(tmp_token.size()==0)
return true;
//cout << "-------START TOKENS--------" << endl;
//output_tokens();
token.clear();
for(int i = 0; i < tmp_token.size(); i++)
token.push_back(tmp_token[i]);
if(!check_rule_embedded())
{
cout << "---ERROR:" << rc_getError() << endl;
output_tokens();
cout << endl;
return false;
}
return true;
//if(!eval_expression())
// cout << "Error2: " << rc_getError() << endl;
//cout << endl << endl << "----TOKENS-----" << endl;
//output_tokens();
//cout << endl << "VM CODE" << endl << endl;
//debug_output_VMASM();
//cout << "F_Error: " << rc_getError() << endl;
}
rc_src rc_last_line;
bool rc_getline(string &line)
{
line = "";
getline(rcbasic_file, line);
if(!rcbasic_file.eof())
{
return true;
}
else if(!rcbasic_program.top().eof_reached)
{
//cout << "setting negative line in " << rcbasic_program.top().filename << " at line " << rcbasic_program.top().line_number << endl;
rcbasic_program.top().eof_reached = true; // end of file
return true;
}
else
{
rcbasic_file.close();
while(rcbasic_program.size()>0)
{
//cout << "debug STACK: " << rcbasic_program.top().filename << " -- " << rcbasic_program.top().line_number << ":" << rcbasic_program.top().line_position << endl;
if(rcbasic_program.top().eof_reached)
{
//cout << "popping " << rcbasic_program.top().filename << endl;
rcbasic_program.pop();
//cout << "new size = " << rcbasic_program.size() << endl;
}
else
{
//cout << "reopening " << rcbasic_program.top().filename << " at line " << rcbasic_program.top().line_number << ":" << rcbasic_program.top().line_position << endl;
rcbasic_file.open(rcbasic_program.top().filename.c_str(), fstream::in);
if(!rcbasic_file.is_open())
{
cout << "Could not open " << rcbasic_program.top().filename << endl;
return false;
}
rcbasic_file.seekg(rcbasic_program.top().line_position);
getline(rcbasic_file, line);
return true;
}
}
return false;
}
}
bool rcbasic_compile()
{
int current_file = 0;
string line = "";
fstream f;
string rc_asm_file = "main.rc_asm";
string rc_str_data = "main_str_data.sdata";
if(is_file_exist(rc_asm_file.c_str()))
{
if(remove(rc_asm_file.c_str())!=0)
{
cout << "Could not clear asm file" << endl;
return false;
}
}
if(is_file_exist(rc_str_data.c_str()))
{
if(remove(rc_str_data.c_str())!=0)
{
cout << "Could not clear sdata file" << endl;
return false;
}
}
while( rc_getline(line) )
{
if(rcbasic_build_debug)
{
vm_asm.push_back("dbg uint=0 uint=" + rc_uint64ToString(rcbasic_program.top().dbg_inc_index) + " uint=" + rc_uint64ToString(rcbasic_program.top().line_number));
}
//cout << "line " << rcbasic_program.top().line_number << ": " << rcbasic_file.tellg() << " -> " << line << endl;
if(!rcbasic_program.top().eof_reached)
rcbasic_program.top().line_position = rcbasic_file.tellg();
//vm_asm.push_back("mov n0 " + rc_intToString(rcbasic_program.top().line_number));
//vm_asm.push_back("print n0");
if(!rc_eval(line))
{
cout << "Error on Line " << rcbasic_program.top().line_number << " in " << rcbasic_program.top().filename << ": " << rc_getError() << endl;
//output_tokens();
cout << endl;
return false;
}
rcbasic_program.top().line_number++;
// if(rcbasic_program.top().line_number % 500 == 0)
// {
// f.open(rc_asm_file.c_str(), fstream::app);
// for(int i = 0; i < vm_asm.vm_code.size(); i++)
// f << vm_asm.vm_code[i] << endl;
// f.close();
// vm_asm.clear();
//
// f.open(rc_str_data.c_str(), fstream::app | fstream::binary);
// for(int i = 0; i < data_segment.size(); i++)
// f.put(data_segment[i]);
// f.close();
// data_segment.clear();
// }
}
if(rcbasic_build_debug)
{
vm_asm.push_back("dbg uint=0 uint=0 uint=0"); //I just need to call this at the end so it will output the last line messages
}
vm_asm.push_back("end");
f.open(rc_asm_file.c_str(), fstream::app);
for(int i = 0; i < vm_asm.vm_code.size(); i++)
f << vm_asm.vm_code[i] << endl;
f.close();
vm_asm.clear();
f.open(rc_str_data.c_str(), fstream::app | fstream::binary);
for(int i = 0; i < data_segment.size(); i++)
f.put(data_segment[i]);
f.close();
data_segment.clear();
return true;
//f.open("tst_var_output.txt", fstream::out | fstream::trunc);
//for(int i = 0; i < id.size(); i++)
// f << id[i].name << " -> " << id[i].vec_pos << endl;
//f.close();
//cout << endl << "VM Code" << endl << "---------------------" << endl;
//debug_output_VMASM();
}
void rcbasic_export_dev()
{
string fn_line = "";
fstream f("rcbasic_dev.txt", fstream::out | fstream::trunc);
fstream f2("rcbasic_dev2.txt", fstream::out | fstream::trunc);
fstream f3("rcbasic_dev3.txt", fstream::out | fstream::trunc);
fstream f4("rcbasic_dev4.txt", fstream::out | fstream::trunc);
if(!f.is_open())
return;
string output_line = "";
for(int i = 0; i < id.size(); i++)
{
fn_line = "#define FN_" + id[i].name + " " + rc_intToString(id[i].vmFunctionIndex);
output_line = "embed_function(\"" + id[i].name +"\", ";
switch(id[i].type)
{
case ID_TYPE_FN_NUM:
output_line += "ID_TYPE_FN_NUM);";
f2 << fn_line << endl;
f3 << "case FN_" << id[i].name << ": //Number Function" << endl << "break;" << endl;
break;
case ID_TYPE_FN_STR:
output_line += "ID_TYPE_FN_STR);";
f2 << fn_line << endl;
f3 << "case FN_" << id[i].name << ": //String Function" << endl << "break;" << endl;
break;
case ID_TYPE_FN_USER:
output_line += "ID_TYPE_FN_STR);";
f2 << fn_line << endl;
f3 << "case FN_" << id[i].name << ": //UDT Function" << endl << "break;" << endl;
break;
case ID_TYPE_SUB:
output_line += "ID_TYPE_SUB);";
f2 << fn_line << endl;
f3 << "case FN_" << id[i].name << ": //Sub Procedure" << endl << "break;" << endl;
break;
default:
continue;
}
f << output_line << endl;
output_line = "";
string fn_arg_utype = "";
for(int n = 0; n < id[i].num_args; n++)
{
fn_line = "#define " + StringToUpper(id[i].name + "_" + id[i].fn_arg[n]) + " ";
output_line = "add_embedded_arg(\"" + id[i].fn_arg[n] + "\", ";
switch(id[i].fn_arg_type[n])
{
case ID_TYPE_NUM:
output_line += "ID_TYPE_NUM);";
//fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value[0].value[0]";
fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value.value[ num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]";
break;
case ID_TYPE_BYREF_NUM:
output_line += "ID_TYPE_BYREF_NUM);";
fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value.value[ num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]";
break;
case ID_TYPE_STR:
output_line += "ID_TYPE_STR);";
fn_line += "str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].sid_value.value[ str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]";
break;
case ID_TYPE_BYREF_STR:
output_line += "ID_TYPE_BYREF_STR);";
fn_line += "str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].sid_value.value[ str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]";
break;
case ID_TYPE_USER:
//fn_arg_utype = "";
//if(id[i].fn_arg_utype[n] >= 0)
// fn_arg_utype = utype[id[i].fn_arg_utype[n]].name;
output_line += "ID_TYPE_USER, " + rc_intToString(id[i].fn_arg_utype[n]) + ");";
fn_line += "usr_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].var_ref->uid_value[0]";
break;
case ID_TYPE_BYREF_USER:
//fn_arg_utype = "";
//if(id[i].fn_arg_utype[n] >= 0)
// fn_arg_utype = utype[id[i].fn_arg_utype[n]].name;
output_line += "ID_TYPE_BYREF_USER, " + rc_intToString(id[i].fn_arg_utype[n]) + ");";
fn_line += "usr_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].var_ref";
break;
}
f2 << fn_line << endl;
f << output_line << endl;
}
}
for(int i = 0; i < utype.size(); i++)
{
output_line = "create_type(\"" + utype[i].name + "\");";
f4 << output_line << endl;
for(int n = 0; n < utype[i].num_members; n++)
{
output_line = "vm_asm.push_back(\"mov n0 " + rc_intToString(utype[i].member_dim[n].dim_size[0]) + "\");";
f4 << output_line << endl;
output_line = "vm_asm.push_back(\"mov n1 " + rc_intToString(utype[i].member_dim[n].dim_size[1]) + "\");";
f4 << output_line << endl;
output_line = "vm_asm.push_back(\"mov n2 " + rc_intToString(utype[i].member_dim[n].dim_size[2]) + "\");";
f4 << output_line << endl;
int ut_index = utype[i].member_utype_index[n];
string member_utype_name = "";
if(ut_index >= 0)
member_utype_name = utype[ut_index].name;
else if(utype[i].member_type[n] == ID_TYPE_USER)
{
cout << "ERROR CREATING TYPE" << endl;
f.close();
f2.close();
f3.close();
f4.close();
return;
}
output_line = "add_type_member(\"" + utype[i].member_name[n] + "\", " + rc_intToString(utype[i].member_type[n]) + ", \"" + member_utype_name + "\", " +
rc_intToString(utype[i].member_dim_count[n]) + ", \"n0\", \"n1\", \"n2\");";
f4 << output_line << endl;
}
}
f.close();
f2.close();
f3.close();
f4.close();
cout << "rcbasic_dev file was created" << endl;
}
bool rcbasic_embedded()
{
int current_file = 0;
string line = "";
while( getline(rcbasic_file, line) )
{
cout << "line " << rcbasic_program.top().line_number << ": " << rcbasic_file.tellg() << " -> " << line << endl;
//rcbasic_program.top().line_position = rcbasic_file.tellg();
if(!rc_eval_embedded(line))
{
cout << "Error on Line " << rcbasic_program.top().line_number << ": " << rc_getError() << endl;
return false;
}
rcbasic_program.top().line_number++;
}
cout << endl << "VM Code" << endl << "---------------------" << endl;
debug_output_VMASM();
return true;
}
void rcbasic_clean()
{
if(rcbasic_file.is_open())
rcbasic_file.close();
}
//a file with functions to add to rcbasic
void rcbasic_dev(string dev_input_file)
{
rcbasic_dev_init();
if(rcbasic_loadProgram(dev_input_file))
{
rcbasic_embedded();
rcbasic_export_dev();
rcbasic_clean();
}
}
void rcbasic_output_debug_info()
{
fstream f("rcbasic.dbgs", fstream::out | fstream::trunc);
for(int i = rcbasic_user_var_start; i < id.size(); i++)
{
switch(id[i].type)
{
case ID_TYPE_NUM:
f << "N " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_ARR_NUM:
f << "AN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_BYREF_NUM:
f << "BN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_STR:
f << "S " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_ARR_STR:
f << "AS " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_BYREF_STR:
f << "BS " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_USER:
f << "U " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_BYREF_USER:
f << "BU " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_USER_NUM:
f << "UN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_USER_NUM_ARRAY:
f << "UNA " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_USER_STR:
f << "US " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
case ID_TYPE_USER_STR_ARRAY:
f << "USA " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n";
break;
}
}
f.close();
f.open("rcbasic.dbgi", fstream::out | fstream::trunc);
for(int i = 0; i < inc_files.size(); i++)
{
f << inc_files[i] << "\n";
}
f.close();
}
int main(int argc, char * argv[])
{
string line = "";
//rcbasic_dev("embedded_functions.bas"); rcbasic_output_debug_info(); return 0;
string rc_filename = "";// = "tst.bas";
bool clean_after_build = false;
//DEBUG START
rc_filename = "/home/n00b/Projects/tst/test_types.bas";
//DEBUG END
if(argc > 1)
rc_filename = argv[1];
string cmd_arg = "";
for(int i = 1; i < argc; i++)
{
cmd_arg = (string)argv[i];
if(cmd_arg.substr(0,1).compare("-") != 0)
rc_filename = cmd_arg;
if(cmd_arg.compare("--debug")==0)
{
cout << "DEBUG MODE" << endl;
rcbasic_build_debug = true;
}
else if(cmd_arg.compare("--no-presets")==0)
{
cout << "DISABLE PRESETS" << endl;
enable_presets = false;
}
else if(cmd_arg.compare("--no-clean")==0)
{
clean_after_build = false;
}
}
if(rc_filename.compare("--version")==0)
{
cout << "RCBASIC Compiler v4.0a" << endl;
return 0;
}
//rc_filename = "tst.bas";
cout << "Source: " << rc_filename << endl;
string cbc_file = rcbasic_build_debug ? "debug.cbc" : rc_filename.substr(0, rc_filename.find_last_of(".")) + ".cbc";
if(is_file_exist(cbc_file.c_str()))
remove(cbc_file.c_str());
if(is_file_exist("rcbasic.dbgs"))
remove("rcbasic.dbgs");
if(is_file_exist("rcbasic.dbgi"))
remove("rcbasic.dbgi");
if(rc_filename.compare("")==0)
return 0;
rcbasic_init();
rcbasic_user_var_start = id.size();
if(rc_filename.find_first_of(".") == string::npos)
{
cout << "file must have extension" << endl;
return 0;
}
//if(rcbasic_loadProgram("tst.bas"))
if(rcbasic_loadProgram(rc_filename))
{
if(!rcbasic_compile())
{
cout << "Compile Failed" << endl;
rcbasic_clean();
return 0;
}
else if(current_block_state != BLOCK_STATE_MAIN)
{
switch(current_block_state)
{
case BLOCK_STATE_DO:
cout << "Compile Error: Failed to close DO loop" << endl;
break;
case BLOCK_STATE_WHILE:
cout << "Compile Error: Failed to close WHILE loop" << endl;
break;
case BLOCK_STATE_FOR:
cout << "Compile Error: Failed to close FOR loop" << endl;
break;
case BLOCK_STATE_FUNCTION:
cout << "Compile Error: Failed to close FUNCTION" << endl;
break;
case BLOCK_STATE_SUB:
cout << "Compile Error: Failed to close SUB" << endl;
break;
case BLOCK_STATE_SELECT:
cout << "Compile Error: Failed to close SELECT" << endl;
break;
case BLOCK_STATE_IF:
cout << "Compile Error: Failed to close IF" << endl;
break;
case BLOCK_STATE_TYPE:
cout << "Compile Error: Failed to close TYPE" << endl;
break;
}
cout << "Compile Failed" << endl;
return 0;
}
else
rcbasic_clean();
//Debug
//return 0;
//for(int i = 0; i < vm_asm.label.size(); i++)
// cout << vm_asm.label[i].label_name << " = " << vm_asm.label[i].label_address << endl;
//cout << "for_loop = " << max_for_count << endl;
//cout << "max_n = " << max_n_reg << endl;
//cout << "max_s = " << max_s_reg << endl;
//cout << "n_stack_size = " << vm_asm.max_n_stack_count << endl;
//cout << "s_stack_size = " << vm_asm.max_s_stack_count << endl;
//n_count
//s_count
//n_stack_count
//s_stack_count
//loop_stack_count
//numID_count
//strID_count
//label_count
//labels
if(rcbasic_build_debug)
rcbasic_output_debug_info();
rcbasic_output_debug_info();
fstream f("main.rc_data", fstream::trunc | fstream::out);
f << max_n_reg << endl;
f << max_s_reg << endl;
f << max_u_reg << endl;
f << vm_asm.max_n_stack_count << endl;
f << vm_asm.max_s_stack_count << endl;
f << vm_asm.max_u_stack_count << endl;
f << max_for_count << endl;
f << num_id_count << endl;
f << str_id_count << endl;
f << usr_id_count << endl;
f << vm_asm.label.size() << endl;
for(int i = 0; i < vm_asm.label.size(); i++)
f << vm_asm.label[i].label_name << " " << vm_asm.label[i].label_address << " " << vm_asm.label[i].label_segment << endl;
f.close();
rc_cbc_assembler::rc_assemble(cbc_file, clean_after_build);
}
else
{
cout << "Could not load program" << endl;
return 0;
}
cout << endl << "Compiled Successfully" << endl << endl << endl; //skip 3 lines so that start of program is not right below this line
return 0;
while(getline(cin, line))
{
rc_eval(line);
}
return 0;
}