diff --git a/rcbasic_build/identifier.h b/rcbasic_build/identifier.h index 8fb8c83..f548075 100644 --- a/rcbasic_build/identifier.h +++ b/rcbasic_build/identifier.h @@ -60,8 +60,8 @@ stack for_counter; stack do_end; stack while_end; -bool isFunctionArg_flag = false; - +bool isFunctionArg_flag = false; + bool enable_presets = true; struct if_data @@ -441,13 +441,34 @@ int getIDInScope_ByIndex_TypeMatch(string id_name, string check_scope="") int id_match = -1; check_scope = StringToLower(check_scope); //cout << "CHECK SCOPE = " << check_scope << endl; + + string id_name_str = ""; + + if(id_name.substr(id_name.length()-1,1).compare("$")==0) + { + id_name_str = id_name; + } + else + { + id_name_str = id_name + "$"; + } + for(int i = 0; i < id.size(); i++) { if(id[i].scope.compare(check_scope)==0) { - //cout << id_name << " ~ " << id[i].name << endl; - if(id_name.compare(id[i].name)==0) - return i; + if(id[i].name.substr(id[i].name.length()-1,1).compare("$")==0) //id in type is string + { + //cout << id_name_str << " ~ " << id[i].name << endl; + if(id_name_str.compare(StringToLower(id[i].name))==0) + return i; + } + else + { + //cout << id_name << " ~ " << id[i].name << endl; + if(id_name.compare(StringToLower(id[i].name))==0) + return i; + } } } return id_match; diff --git a/rcbasic_build/main.cpp b/rcbasic_build/main.cpp index 0a04fe7..9f9dcb5 100644 --- a/rcbasic_build/main.cpp +++ b/rcbasic_build/main.cpp @@ -524,6 +524,8 @@ bool rc_eval(string line) ERROR_MSG = ""; clearRegs(); clearTokens(); + byref_type_exception.clear(); + if(line.compare("#var")==0) { output_vars(); diff --git a/rcbasic_build/parser.h b/rcbasic_build/parser.h index 00b4dc8..b23904d 100644 --- a/rcbasic_build/parser.h +++ b/rcbasic_build/parser.h @@ -22,7 +22,19 @@ int u_reg = 0; //expression result string expr_result = ""; bool type_delete_flag = false; -string type_delete_arg = ""; +string type_delete_arg = ""; +int type_delete_arg_type = 0; +bool type_delete_arg_whole = false; + +struct type_error_exception +{ + string error_log; + string tk_reg; + string resolve_reg; +}; + +vector byref_type_exception; //This will store the error that might be generated if a user type var is in an expression without its dimensions expressed + bool pre_parse(int start_token, int end_token, int pp_flags = 0, bool eval_udt = false); //puts number and string values and variables inside number and string registers //void getBlock(int& start_block, int& end_block); //gets the start and end index of the next block to evaluate (first and last token if there isnt a block left to evaluate @@ -1016,7 +1028,9 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ string s = ""; string u = ""; int expr_id = -1; - string sdata = ""; + string sdata = ""; + + bool byref_type_flag = false; for(int i = start_token; i <= end_token; i++) { @@ -1105,7 +1119,7 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ } else if( (id[expr_id].type == ID_TYPE_BYREF_NUM || id[expr_id].type == ID_TYPE_BYREF_STR) && pp_flags == PP_FLAG_ARRAY) { - //cout << "found array: " << id[expr_id].name << endl << endl; + cout << "found array: " << id[expr_id].name << endl << endl; int s_scope = 0; int arr_token_start = i; int arr_token_end = i; @@ -1267,19 +1281,30 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ int tmp_id = 0; bool has_child = false; + int num_id_parents = 0; + int num_id_children = 0; + byref_type_flag = false; + for(int t = i; t <= end_token; t++) { if(token[t].substr(0,4).compare("")==0) { - cout << "FIGURE IT OUT: " << t << endl; + if(num_id_parents != num_id_children) + { + rc_setError("Expected member separator or member ID"); + return false; + } + + num_id_parents++; + //cout << "FIGURE IT OUT: " << t << endl; string args[3]; int arg_count = 0; string full_id = token[t].substr(4); token[t] = ""; tmp_id = getIDInScope_ByIndex_TypeMatch(full_id, tmp_scope); - //cout << "\ntmp_id = " << tmp_id << endl; + cout << "\ntmp_id = " << tmp_id << endl; if(tmp_id < 0) { @@ -1350,6 +1375,8 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ arg_count++; } + else if(type_delete_flag) + t2--; } @@ -1364,12 +1391,54 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ cout << "Has Child = " << has_child << ", " << t << ", " << t2 << endl; } + if(type_delete_flag && (!has_child) && arg_count != 0) + { + rc_setError("Expected identifier without index"); + return false; + } + if(arg_count != id[tmp_id].num_args) { if(!type_delete_flag) { - rc_setError("[0]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + if(arg_count != 0) + rc_setError("[0]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + + cout << "ID_TYPE = " << id[tmp_id].type << ", " << arg_count << ", " << (has_child ? "true" : "false") << endl; + + args[0] = ""; + args[1] = ""; + args[2] = ""; + + string tmp_instruction = "obj_usr_"; + + //trying stuff out + if(id[tmp_id].type == ID_TYPE_USER_NUM) + { + vm_asm.push_back("mov " + n + " 0"); + tmp_instruction += "n" + ( id[tmp_id].num_args <= 0 ? "" : rc_intToString(id[tmp_id].num_args) ); + for(int tmp_arg_i = 0; tmp_arg_i < id[tmp_id].num_args; tmp_arg_i++) + args[tmp_arg_i] = n; + + + vm_asm.push_back(tmp_instruction + " !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + byref_type_flag = true; + break; + } + else if(id[tmp_id].type == ID_TYPE_USER_STR) + { + vm_asm.push_back("mov " + n + " 0"); + tmp_instruction += "s" + ( id[tmp_id].num_args <= 0 ? "" : rc_intToString(id[tmp_id].num_args) ); + for(int tmp_arg_i = 0; tmp_arg_i < id[tmp_id].num_args; tmp_arg_i++) + args[tmp_arg_i] = n; + + vm_asm.push_back(tmp_instruction + " !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + byref_type_flag = true; + break; + } + //------------------------------- + return false; } else @@ -1392,7 +1461,7 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ if(type_delete_flag && (!has_child)) { //DO NOTHING - //cout << "NO CHILD: " << id[tmp_id].name << endl; + cout << "NO CHILD: " << id[tmp_id].name << endl; } else { @@ -1483,6 +1552,8 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ } else if(token[t].compare("")==0) { + num_id_children++; + type_delete_arg_whole = false; token[t] = ""; continue; } @@ -1499,6 +1570,7 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ { //cout << "DELETE_VAR = " << id[tmp_id].name << endl; type_delete_arg = "!" + rc_intToString(id[tmp_id].vec_pos); + type_delete_arg_type = id[tmp_id].type; } else switch(id[tmp_id].type) @@ -1528,6 +1600,15 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ break; } + if(byref_type_flag) + { + type_error_exception tx; + tx.error_log = "[0]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name; + tx.tk_reg = token[i]; + byref_type_exception.push_back(tx); + byref_type_flag = false; + } + cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << endl; @@ -2048,7 +2129,7 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ resolve_index = getResolveReg(args[n]); if(args[n].substr(0,4).compare("")==0) { - //cout << "found id: " << args[n] << " in " << id[expr_id].name << endl; + cout << "found id: " << args[n] << " in " << id[expr_id].name << endl; string t_replace = ""; int arg_id = getIDInScope_ByIndex(args[n].substr(4)); if(arg_id < 0) @@ -2087,11 +2168,24 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ rc_setError("Could not resolve Identifier in ByRef argument"); return false; } - } + } + + //check if byref_type_exception + bool type_exception_found = false; + for(int bt_i = 0; bt_i < byref_type_exception.size(); bt_i++) + { + if(args[n].compare(byref_type_exception[bt_i].tk_reg)==0) + { + cout << "FOUND EXCEPTION: " << args[n] << endl; + byref_type_exception[bt_i].tk_reg = ""; + type_exception_found = true; + } + } + //---------------- - if(resolve_index < 0) + if(resolve_index < 0 && (!type_exception_found)) { - rc_setError("Expected identifier for ByRef argument"); + rc_setError("[4]Expected identifier for ByRef argument"); return false; } @@ -2101,8 +2195,29 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ { rc_setError("Identifier " + resolveID_id_reg[resolve_index] + " was not defined in this scope"); return false; - }*/ - + }*/ + + if(type_exception_found) + switch(id[expr_id].fn_arg_type[n]) + { + case ID_TYPE_BYREF_NUM: + if(args[n].substr(0,1).compare("n")!=0) + { + rc_setError("Expected number identifier for argument"); + return false; + } + vm_asm.push_back("ptr !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + break; + case ID_TYPE_BYREF_STR: + if(args[n].substr(0,1).compare("s")!=0) + { + rc_setError("Expected string identifier for argument"); + return false; + } + vm_asm.push_back("ptr$ !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + break; + } + else switch(id[expr_id].fn_arg_type[n]) { case ID_TYPE_BYREF_NUM: @@ -2177,7 +2292,18 @@ bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_ vm_asm.push_back("mov_type !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); } - } + } + + //check if any exceptions weren't used and return error if there are any left + for(int bt_i = 0; bt_i < byref_type_exception.size(); bt_i++) + { + if(byref_type_exception[bt_i].tk_reg.compare("")!=0) + { + rc_setError(byref_type_exception[bt_i].error_log); + return false; + } + } + //----------------------------------------------------------------------------- string token_replace = ""; @@ -5319,6 +5445,7 @@ bool check_rule() type_delete_flag = true; type_delete_arg = ""; + type_delete_arg_whole = true; if(!eval_expression()) { @@ -5330,9 +5457,38 @@ bool check_rule() rc_setError("Could not determine Identifier Type in DELETE: " + type_delete_arg); return false; } - vm_asm.push_back("delete_t " + type_delete_arg); + + string d_type = "!"; + string top_level_flag = "!0"; + + if(!type_delete_arg_whole) + top_level_flag = "!1"; + + if(type_delete_arg_type == ID_TYPE_USER_STR || type_delete_arg_type == ID_TYPE_USER_STR_ARRAY) + { + cout << "DELETE STRING" << endl; + d_type += "1"; + } + else if(type_delete_arg_type == ID_TYPE_USER_NUM || type_delete_arg_type == ID_TYPE_USER_NUM_ARRAY) + { + cout << "DELETE NUMBER" << endl; + d_type += "0"; + } + else if(type_delete_arg_type == ID_TYPE_USER) + { + cout << "DELETE USER TYPE" << endl; + d_type += "2"; + } + else + { + rc_setError("Cannot delete identifier of this type or within this scope"); + return false; + } + + vm_asm.push_back("delete_t " + type_delete_arg + " " + top_level_flag + " " + d_type); type_delete_flag = false; + type_delete_arg_whole = true; } else { diff --git a/rcbasic_build/rc_global.h b/rcbasic_build/rc_global.h index 688837f..b1b2908 100644 --- a/rcbasic_build/rc_global.h +++ b/rcbasic_build/rc_global.h @@ -128,7 +128,7 @@ public: s.substr(0,s.find_first_of(" ")).compare("end_x")==0 || s.substr(0,s.find_first_of(" ")).compare("lval")==0 || s.substr(0,s.find_first_of(" ")).compare("lval$")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_get")==0 || - s.substr(0,s.find_first_of(" ")).compare("delete_t")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_init")==0) + s.substr(0,s.find_first_of(" ")).compare("obj_usr_init")==0) { current_address[current_segment] += 9; //1 byte for instruction and 8 bytes a single argument } @@ -138,7 +138,8 @@ public: s.substr(0,s.find_first_of(" ")).compare("redim2")==0 || s.substr(0,s.find_first_of(" ")).compare("redim2$")==0 || s.substr(0,s.find_first_of(" ")).compare("for_offset_arr3")==0 || s.substr(0,s.find_first_of(" ")).compare("dbg")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s2")==0 || - s.substr(0,s.find_first_of(" ")).compare("obj_usr_init2")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t1")==0) + s.substr(0,s.find_first_of(" ")).compare("obj_usr_init2")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t1")==0 || + s.substr(0,s.find_first_of(" ")).compare("delete_t")==0) { current_address[current_segment] += 25; //1 byte for instruction and 8 bytes for 3 arguments } diff --git a/rcbasic_build/vm_asm b/rcbasic_build/vm_asm index 00076f2..75e3008 100644 --- a/rcbasic_build/vm_asm +++ b/rcbasic_build/vm_asm @@ -258,7 +258,7 @@ OBJ_CURRENT_TYPE 173 - push_t_null -174 - delete_t !id +174 - delete_t !id !id (0 - top level, 1 - member) !id (0 - num, 1 - str, 2 - type) 175 - dim_type u# raw_number (user_type) 176 - dim_type1 u# raw_number (user type) n# (dim1) diff --git a/rcbasic_runtime/main.cpp b/rcbasic_runtime/main.cpp index a83bb09..6fb42d3 100644 --- a/rcbasic_runtime/main.cpp +++ b/rcbasic_runtime/main.cpp @@ -4463,9 +4463,47 @@ void push_t_null_173() //I will need to do something with this } -void delete_t_174(uint64_t uid) +void delete_t_174(uint64_t oid, uint64_t top_level_flag, uint64_t obj_type) { - rc_free_type(&usr_object.obj_ref->uid_value[uid]); + cout << "DEBUG: " << oid << ", " << top_level_flag << ", " << obj_type << endl; + //cout << "Delete Object: " << usr_object.obj_ref->str_var[1].dim[0] << endl; + if(top_level_flag == 0) + { + //cout << "[START] USR TL: " << usr_var[oid].uid_value[0].str_var.size() << endl; + rc_free_type(&usr_var[oid]); + //cout << "[END] USR TL: " << usr_var[oid].uid_value[0].str_var.size() << endl; + } + else + { + switch(obj_type) + { + case 0: + cout << "DBG NDATA: " << usr_object.obj_ref->num_var[oid].dim[0] << endl; + usr_object.obj_ref->num_var[oid].nid_value.value.clear(); + usr_object.obj_ref->num_var[oid].nid_value.value.shrink_to_fit(); + usr_object.obj_ref->num_var[oid].dimensions = 0; + usr_object.obj_ref->num_var[oid].dim[0] = 0; + usr_object.obj_ref->num_var[oid].dim[1] = 0; + usr_object.obj_ref->num_var[oid].dim[2] = 0; + break; + + case 1: + cout << "DBG SDATA: " << usr_object.obj_ref->str_var[oid].dim[0] << endl; + usr_object.obj_ref->str_var[oid].sid_value.value.clear(); + usr_object.obj_ref->str_var[oid].sid_value.value.shrink_to_fit(); + usr_object.obj_ref->str_var[oid].dimensions = 0; + usr_object.obj_ref->str_var[oid].dim[0] = 0; + usr_object.obj_ref->str_var[oid].dim[1] = 0; + usr_object.obj_ref->str_var[oid].dim[2] = 0; + break; + + case 2: + cout << "DBG UDATA: " << usr_object.obj_ref->uid_value[oid].dim[0] << endl; + rc_free_type(&usr_object.obj_ref->uid_value[oid]); + break; + } + } + cout << "Done" << endl; } void dim_type_175(int u1, int udt_index) @@ -5371,7 +5409,9 @@ bool rcbasic_run() break; case 174: i[0] = readInt(); - delete_t_174(i[0]); + i[1] = readInt(); + i[2] = readInt(); + delete_t_174(i[0], i[1], i[2]); break; case 175: i[0] = readInt();