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

File diff suppressed because it is too large Load Diff