Added support for user defined types to embedded_functions.bas

This commit is contained in:
n00b87
2024-04-22 20:42:20 -05:00
parent 53c3ce4483
commit 1248387749
2 changed files with 1745 additions and 1599 deletions

View File

@@ -6045,98 +6045,158 @@ bool check_rule_embedded()
return false;
}
int fn_type = ID_TYPE_FN_NUM;
if(fn_name.substr(fn_name.length()-1,1).compare("$")==0)
fn_type = ID_TYPE_FN_STR;
embed_function(fn_name, fn_type);
current_block_state = BLOCK_STATE_FUNCTION;
block_state.push(current_block_state);
string fn_arg = "";
int fn_arg_type = ID_TYPE_NUM;
bool fn_byref = false;
int end_token = 0;
for(int i = 3; i < token.size(); i++)
{
if(token[i].compare("<byref>")==0)
{
fn_byref = true;
}
else if(rc_substr(token[i], 0, 4).compare("<id>")==0)
{
fn_arg += token[i];
if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0)
fn_arg_type = ID_TYPE_STR;
else
fn_arg_type = ID_TYPE_NUM;
}
else if(token[i].compare("<comma>")==0)
{
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("Function argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("Function argument identifier already exists in current scope");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else
fn_arg_type = ID_TYPE_BYREF_STR;
}
add_embedded_arg(fn_arg, fn_arg_type);
fn_arg = "";
fn_byref = false;
}
else if(token[i].compare("</par>")==0)
{
if(fn_arg.compare("")==0)
{
end_token = i+1;
break;
}
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("Function argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("Function argument identifier already exists in current scope: " + fn_arg + " -> " + current_scope + " ? ");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else
fn_arg_type = ID_TYPE_BYREF_STR;
}
add_embedded_arg(fn_arg, fn_arg_type);
fn_arg = "";
fn_byref = false;
end_token = i+1;
break;
}
else
{
rc_setError("Argument to function must be a valid identifier: " + token[i]);
return false;
}
int fn_type = ID_TYPE_FN_NUM;
if(fn_name.substr(fn_name.length()-1,1).compare("$")==0)
fn_type = ID_TYPE_FN_STR;
string fn_type_name = "";
if(token.size()>2)
{
if(token[token.size()-2].compare("<as>")==0)
{
fn_type = ID_TYPE_FN_USER;
if(token[token.size()-1].substr(0,4).compare("<id>")==0)
fn_type_name = token[token.size()-1].substr(4);
else
{
rc_setError("Invalid return type in FUNCTION definition");
return false;
}
token.pop_back();
token.pop_back();
}
}
if(!create_function(fn_name, fn_type, fn_type_name))
{
rc_setError("Could not create FUNCTION \"" + fn_name + "\" of type \"" + fn_type_name + "\"");
return false;
}
current_block_state = BLOCK_STATE_FUNCTION;
block_state.push(current_block_state);
string fn_arg = "";
int fn_arg_type = ID_TYPE_NUM;
string fn_arg_user_type = "";
bool fn_byref = false;
int end_token = 0;
for(int i = 3; i < token.size(); i++)
{
if(token[i].compare("<byref>")==0)
{
fn_byref = true;
}
else if(rc_substr(token[i], 0, 4).compare("<id>")==0)
{
fn_arg += token[i];
if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0)
fn_arg_type = ID_TYPE_STR;
else
fn_arg_type = ID_TYPE_NUM;
}
else if(token[i].compare("<as>")==0)
{
i++;
fn_arg_type = ID_TYPE_USER;
fn_arg_user_type = "";
int arg_type_index = -1;
if(i < token.size())
if(token[i].substr(0,4).compare("<id>")==0)
fn_arg_user_type = token[i].substr(4);
if(fn_arg_user_type.compare("")==0)
{
rc_setError("Invalid Type in FUNCTION Definition");
return false;
}
}
else if(token[i].compare("<comma>")==0)
{
//cout << "ADD ARG: " << fn_arg << endl;
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("FUNCTION argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("FUNCTION argument identifier already exists in current scope");
return false;
}
//cout << "CHECK 1" << endl;
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else if(fn_arg_type == ID_TYPE_STR)
fn_arg_type = ID_TYPE_BYREF_STR;
else
fn_arg_type = ID_TYPE_BYREF_USER;
}
if(!add_function_arg(fn_arg, fn_arg_type, fn_arg_user_type))
{
return false;
}
fn_arg = "";
fn_byref = false;
//cout << "DONE" << endl;
}
else if(token[i].compare("</par>")==0)
{
if((i+1) < token.size())
{
rc_setError("Expected End of FUNCTION Declaration");
return false;
}
if(fn_arg.compare("")==0)
{
end_token = i+1;
break;
}
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("FUNCTION argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("FUNCTION argument identifier already exists in current scope");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else if(fn_arg_type == ID_TYPE_STR)
fn_arg_type = ID_TYPE_BYREF_STR;
else
fn_arg_type = ID_TYPE_BYREF_USER;
}
if(!add_function_arg(fn_arg, fn_arg_type, fn_arg_user_type))
{
return false;
}
fn_arg = "";
fn_byref = false;
end_token = i+1;
break;
}
else
{
rc_setError("Argument to FUNCTION must be a valid identifier: " + token[i]);
}
}
current_block_state = BLOCK_STATE_MAIN;
@@ -6172,96 +6232,140 @@ bool check_rule_embedded()
return false;
}
int fn_type = ID_TYPE_SUB;
embed_function(fn_name, fn_type);
current_block_state = BLOCK_STATE_SUB;
block_state.push(current_block_state);
string fn_arg = "";
int fn_arg_type = ID_TYPE_NUM;
bool fn_byref = false;
int end_token = 0;
for(int i = 3; i < token.size(); i++)
{
if(token[i].compare("<byref>")==0)
{
fn_byref = true;
}
else if(rc_substr(token[i], 0, 4).compare("<id>")==0)
{
fn_arg += token[i];
if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0)
fn_arg_type = ID_TYPE_STR;
else
fn_arg_type = ID_TYPE_NUM;
}
else if(token[i].compare("<comma>")==0)
{
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("Function argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("Function argument identifier already exists in current scope");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else
fn_arg_type = ID_TYPE_BYREF_STR;
}
add_embedded_arg(fn_arg, fn_arg_type);
fn_arg = "";
fn_byref = false;
}
else if(token[i].compare("</par>")==0)
{
if(fn_arg.compare("")==0)
{
end_token = i+1;
break;
}
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("Function argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("Function argument identifier already exists in current scope");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else
fn_arg_type = ID_TYPE_BYREF_STR;
}
add_embedded_arg(fn_arg, fn_arg_type);
fn_arg = "";
fn_byref = false;
end_token = i+1;
break;
}
else
{
rc_setError("Argument to function must be a valid identifier: " + token[i]);
return false;
}
int fn_type = ID_TYPE_SUB;
string fn_type_name = "";
if(!create_function(fn_name, fn_type, fn_type_name))
{
rc_setError("Could not create SUB ROUTINE \"" + fn_name + "\"");
return false;
}
current_block_state = BLOCK_STATE_SUB;
block_state.push(current_block_state);
string fn_arg = "";
int fn_arg_type = ID_TYPE_NUM;
string fn_arg_user_type = "";
bool fn_byref = false;
int end_token = 0;
for(int i = 3; i < token.size(); i++)
{
if(token[i].compare("<byref>")==0)
{
fn_byref = true;
}
else if(rc_substr(token[i], 0, 4).compare("<id>")==0)
{
fn_arg += token[i];
if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0)
fn_arg_type = ID_TYPE_STR;
else
fn_arg_type = ID_TYPE_NUM;
}
else if(token[i].compare("<as>")==0)
{
i++;
fn_arg_type = ID_TYPE_USER;
fn_arg_user_type = "";
int arg_type_index = -1;
if(i < token.size())
if(token[i].substr(0,4).compare("<id>")==0)
fn_arg_user_type = token[i].substr(4);
if(fn_arg_user_type.compare("")==0)
{
rc_setError("Invalid Type in SUB ROUTINE Definition");
return false;
}
}
else if(token[i].compare("<comma>")==0)
{
//cout << "ADD ARG: " << fn_arg << endl;
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("SUB ROUTINE argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("SUB ROUTINE argument identifier already exists in current scope");
return false;
}
//cout << "CHECK 1" << endl;
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else if(fn_arg_type == ID_TYPE_STR)
fn_arg_type = ID_TYPE_BYREF_STR;
else
fn_arg_type = ID_TYPE_BYREF_USER;
}
if(!add_function_arg(fn_arg, fn_arg_type, fn_arg_user_type))
{
return false;
}
fn_arg = "";
fn_byref = false;
//cout << "DONE" << endl;
}
else if(token[i].compare("</par>")==0)
{
if((i+1) < token.size())
{
rc_setError("Expected End of SUB ROUTINE Declaration");
return false;
}
if(fn_arg.compare("")==0)
{
end_token = i+1;
break;
}
fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1);
if(!isValidIDName(fn_arg))
{
rc_setError("SUB ROUTINE argument is not a valid identifier name");
return false;
}
if(idExistsInScope(fn_arg))
{
rc_setError("SUB ROUTINE argument identifier already exists in current scope");
return false;
}
if(fn_byref)
{
if(fn_arg_type == ID_TYPE_NUM)
fn_arg_type = ID_TYPE_BYREF_NUM;
else if(fn_arg_type == ID_TYPE_STR)
fn_arg_type = ID_TYPE_BYREF_STR;
else
fn_arg_type = ID_TYPE_BYREF_USER;
}
if(!add_function_arg(fn_arg, fn_arg_type, fn_arg_user_type))
{
return false;
}
fn_arg = "";
fn_byref = false;
end_token = i+1;
break;
}
else
{
rc_setError("Argument to SUB ROUTINE must be a valid identifier: " + token[i]);
}
}
current_block_state = BLOCK_STATE_MAIN;
@@ -6276,6 +6380,37 @@ bool check_rule_embedded()
return false;
}
}
else if(token[0].compare("<type>")==0)
{
if(current_scope.compare("main")!=0)
{
rc_setError("TYPE cannot be defined in this scope");
return false;
}
if(token.size() != 2)
{
rc_setError("Expected TYPE Identifier in TYPE statement");
return false;
}
if(token[1].substr(0,4).compare("<id>")!=0)
{
rc_setError("Expected TYPE Identifier in TYPE statement");
return false;
}
int id_index = getIDInScope_ByIndex(token[1].substr(4));
if(id_index >= 0)
{
rc_setError("TYPE Identifier exists in current scope");
return false;
}
create_type(token[1].substr(4));
current_block_state = BLOCK_STATE_TYPE;
block_state.push(current_block_state);
string start_label = current_scope + ".#TYPE:" + token[1].substr(4);
current_scope = start_label;
}
}
return true;