PNFHA: if-else code generation

des000's Avatar, Join Date: Jul 2014
Newbie Member
I am trying to create a language called PNFHA. I am having trouble getting the code for an if-else statement to work. The problem is the code generation. I have to use tricks to get bison to put the generated code where it belongs in an if-else. The current problem is that I cannot seem to count if statements correctly, and if I could, I could use that number to try to correct the line numbers and then the code would work.
0
des000's Avatar, Join Date: Jul 2014
Newbie Member
I would post a link to more information about the problem, but it says there are too many links/images to post it.
0
des000's Avatar, Join Date: Jul 2014
Newbie Member
So here is my current code:

Code:
			| IF LEFTP expression RIGHTP stmt ELSE stmt
			{
			 if (strcmp(yytext, "}") == 0)
	                  blockinelse = true;

			 if ($5.to_string().get().getString() == "}")
			  blockinif = true;


			 ifbegin = out.length() - 1;
			 if (!inblock)
			  ifbeginlineno = yylineno - 2;
			 else
                          ifbeginlineno = yylineno - 5;

			 conprint("ALOAD TBOOLEAN %s\n", $3.to_boolean().get().getString().c_str());

			 String if_body_str = "if_body_";
			 if_body_str += ifcounter;
			 String else_body_str = "else_body_";
			 else_body_str += ifcounter;
			 String after_if_str = "after_if_";
			 after_if_str += ifcounter;

			 conprint("CGOTOL TVOID %u\n", ifcounter);
			 conprint("GOTOL TVOID %u\n", ifcounter + 1);

			 labelTable.insert();
			 labelTable[labelTable.length() - 1].name(if_body_str);
			 labelTable[labelTable.length() - 1].address(labelTable.length() - 2);

			 labelTable.insert();
			 labelTable[labelTable.length() - 1].name(else_body_str);
			 labelTable[labelTable.length() - 1].address(labelTable.length() - 2);

			 labelTable.insert();
			 labelTable[labelTable.length() - 1].name(after_if_str);
			 labelTable[labelTable.length() - 1].address(labelTable.length() - 2);

			 conprint("\n\nLBL TVOID 0V\n");
			 unsigned long ifbodybegin = out.length() - 1;


			 // Calculate elsebegin...
			 unsigned long k = outcount;
			 unsigned long l = outcount;
			 unsigned long m;
			 for (unsigned long i = 0; i < statementoutcount.length(); ++i)
			 {
			  if (statementlineno[i] >= ifbeginlineno)
			  {
			   unsigned long j;
			   for (j = statementoutcount[i]; j < ifbegin; ++j, ++k)
 			    ;
			   outcount = k;
			   elsebeginlineno = j + 1;
			  }
			 }
			 elsebegin = outcount;


			 bool found = false;
			 bool multiplestmts = false;
			 unsigned long l2 = 0;
			 unsigned long n = outcount;


			 unsigned long fpos = ifbegin - 1;


			 // Calculate l2...
			 n = outcount;
			 found = false;
			 bool elsefound = false;
			 multiplestmts = false;
			 l2 = 0;
			 for (unsigned long i = 0; i < ifbegin; ++i)
			 {		  
			  ++l2;
			 }


			 // Mark the code...
			 for (unsigned long i = 0, m = statementlineno[i]; i < out.length(); ++i, ++m)
		         {
			  if (i < ifbegin)
			  {
                           out[i].insert(out[i].length(), ':');
			   out[i].insert();
			   String str;
			   str.from_long(m);
			   out[i] += str;
  		           out[i] += '\n';
			  }
			 }


			 // Calculate some other values...
			 n = outcount;
			 unsigned long len = out.length();
			 found = false;
			 elsefound = false;
			 multiplestmts = false;
			 for (unsigned long i = 0; i < len; ++i)
			 {
			  String str;
			  str = out[i];
			  unsigned long k = str.getString().find(':');
                          if (k == string::npos)
			  {
                           continue;
		          }
   		          found = true;
			  str = out[i].getString().substr(k + 2);
			  unsigned long l = atoi(str.getString().c_str());
			  
			  if (l2 > 1)
			   multiplestmts = true;

			  if (blockinelse == true && multiplestmts == true)
			  {
			   if (l >= (elsebeginlineno - 1))
                           {
			    elsefound = true;
			   }
			  }
			  else
			  {
			   if (l >= elsebeginlineno)
                           {
			    elsefound = true;
			   }
			  }
			 }
			 outcount = out.length() - 1;


			 // Are there multiple statements in the if?
			 bool multipleif = false;
			 unsigned long ifstmts = 0;
			 for (unsigned long i = 0; i < out.length(); ++i)
			 {
			  if (i > ifbegin && i < elsebegin)
			  {
			   ++ifstmts;
			  }
			 }
			 if (ifstmts > 1)
			  multipleif = true;


			 // After this point, these are off, so we adjust them...
			 if (l2 == 4 && !blockinif)
			 {
			  ifbeginlineno -= 1;
			  elsebeginlineno -= 2;
			 }
			 else if (l2 == 3 && !blockinif)
			 {
			  elsebeginlineno -= 1;
			 }
			 else if (l2 >= 5 && !blockinif)
			 {
			  unsigned long l2offset = 0;
			  unsigned long i;
			  for (i = 6; i <= l2; ++i)
                           ++l2offset;

			  ifbeginlineno -= (2 + l2offset);
			  elsebeginlineno -= (3 + l2offset);
			 }
			 else if (l2 == 2 && blockinif)
			 {
			  ++elsebeginlineno;
			 }
			 else if (l2 == 4 && blockinif)
			 {
			  --ifbeginlineno;
			  --elsebeginlineno;
		         }
			 else if (l2 == 5 && blockinif)
			 {
			  ifbeginlineno -= 2;
			  elsebeginlineno -= 2;
		         }
			 else if (l2 >= 6 && blockinif)
			 {
			  unsigned long l2offset = 3;
			  unsigned long i;
			  for (i = 7; i <= l2; ++i)
                          {
			   ++l2offset;
			  }

			  ifbeginlineno -= (l2offset);
			  elsebeginlineno -= (l2offset);

			  if (ifstmts == 6)
			   elsebeginlineno += 1;
			  if (ifstmts == 5)
			   elsebeginlineno += 2;
			 }
			 cout << l2 << " " << ifstmts << endl;
			 cout << ifbegin << " " << elsebegin << endl;
			 cout << ifbeginlineno << " " << elsebeginlineno << endl;


		         // Move the if code to the right spot...
			 k = ifbodybegin;
			 for (unsigned long i = 0; i < statementoutcount.length(); ++i)
			 {
			  for (unsigned long j = statementoutcount[i]; j < ifbegin; ++j, ++k)
 			   out.move(j, k);
			  outcount = k;			 
			 }


			 conprint("GOTOL TVOID %u\n", ifcounter + 2);
			 statementoutcount.insert();
			 statementoutcount[statementoutcount.length() - 1] = outcount - 1;
			 statementlineno.insert();
			 statementlineno[statementlineno.length() - 1] = elsebeginlineno;


			 conprint("\n\nLBL TVOID 0V\n");
			 statementoutcount.insert();
			 statementoutcount[statementoutcount.length() - 1] = outcount - 1;
			 statementlineno.insert();
			 statementlineno[statementlineno.length() - 1] = elsebeginlineno;

			 unsigned long elsebodybegin = out.length();

			 
			 // Add the else code to an array...
			 n = outcount;
			 len = out.length();
			 found = false;
			 elsefound = false;
			 multiplestmts = false;
			 l2 = 0;
			 Array<String> a;
			 for (unsigned long i = 0; i < len; ++i)
			 {
			  String str;
			  str = out[i];
			  unsigned long k = str.getString().find(':');
                          if (k == string::npos)
			  {
                           continue;
		          }
   		          found = true;
			  str = out[i].getString().substr(k + 2);
			  unsigned long l = atoi(str.getString().c_str());
			  
			  ++l2;
			  if (l2 > 1)
			   multiplestmts = true;

			  if (l >= elsebeginlineno)
			  {
			   if (l2 > 1)
			    a.insert();
			   a[a.length() - 1] = out[i];
			   out[i] = "";
                          }
			 }
			 // Sort it by line number...
			 sort_lines(a);

			
			 // ...And insert it back into the output...
	                 for (unsigned long i = 0; i < a.length(); ++i)
                         {
			  out.insert();
			  out[elsebodybegin + i] = a[i];
			 }
			 outcount = out.length();


			 conprint("GOTOL TVOID %u\n", ifcounter + 2);


			 conprint("\n\nLBL TVOID 0V\n");

			
			 // Remove the extra line number code...
 			 for (unsigned long i = 0; i < out.length(); ++i)
			 {
			  unsigned long pos = out[i].getString().find(':');
			  String str;

			  if (pos != string::npos)
			   str = out[i].getString().substr(0, pos);
			  else
			   str = out[i];

   			  out[i] = str;
			 }


			 ++ifcounter;
			}