LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   PNF: Help with a Loop to Identify extrai values (https://www.linuxquestions.org/questions/programming-9/pnf-help-with-a-loop-to-identify-extrai-values-4175650411/)

des_a 03-18-2019 11:02 AM

PNF: Help with a Loop to Identify extrai values
 
I have this loop:

Code:

unsigned long ifcounter = 0, ifcounter2 = 0, sifcounter = 0;
 for (unsigned long i = 0, j = reg.ecount; i != reg.ecount; i += 3, j -= 3)
 {
  if (mem.get(i + 1) == TSTRING)
  {
  unsigned long is = 0;
  for (is = i + 2; mem.get(is) != 0; ++is)
    ;
  ++is;
  j = i;
  i = is;
  i -= 3;
  continue;
  }

  if (mem.get(i) == IIF || mem.get(j) == IENDIF || mem.get(i) == IIFELSE || mem.get(j) == IEIF)
  {
  if (mem.get(i) == IIF)
  {
    ++ifcounter;
    reg.inif.insert();
    reg.ifflag.insert();
  }

  if (mem.get(j) == IEIF)
  {
    ++ifcounter2;
    ifcounter = ifcounter2;
  }

  reg.extrai.put(i, ifcounter);
  }
 }

It's supposed to load the extrai values, but it doesn't work.

Here's a brief explanation of what's supposed to be going on.

This is running a program. A program has a variable number of memory slots. It has the same amount of extrai values. extrai is a register. extrai is computed at run time, during the load. The rest of the information comes from a file.

A file has a signature: !@.PNF

A file has a series of numbers.

Generally the first number is the instruction, the second, the type, and the third, the operand.

For ifs, extrai is supposed to count the ifnumber. That's where this goes wrong. This is a loop that is computed at load time.

It's supposed to count the ifs, and then load extrai with the ifnumber. Ifs look like this:

Code:

IF TVOID 0V
IFBEGIN TVOID 0V
[PNF_CODE]
IFEND TVOID 0V
ENDIF TVOID 0V
{
IFELSE TVOID 0V
IFBEGIN TVOID 0V
[PNF_CODE]
IFEND TVOID 0V
ENDIFELSE TVOID 0V
}
EIF TVOID 0V

Where anything inbetween {} or [] is optional. It's got the same if belonging rules as C++, where the last else will belong to the last if basically. My loops supposed to reflect that, but it fails. Please help. Thanks!

rtmistler 03-18-2019 11:06 AM

If variable i is equal to reg.ecount, then the loop will never execute.

What have you done to debug this? You gave code, but not all references contained within the code.

Run GDB on this and single step through it using some watchpoints on the relevant variables. There are some links in my signature giving instruction about how to accomplish this.

des_a 03-18-2019 05:26 PM

reg.ecount marks the end of memory. It isn't and won't be equal to that until we have looped through the memory.

I have been doing a series of write technique output commands. Plus I've been desk checking it thourouly. I always forget about gdb...

What references are still missing?

des_a 03-19-2019 08:09 PM

I figured it out, it would seem.

Code:

unsigned long ifcounter = 0, sifcounter = 0;
 for (unsigned long i = 0; i != reg.ecount; i += 3)
 {
  if (mem.get(i + 1) == TSTRING)
  {
  unsigned long is = 0;
  for (is = i + 2; mem.get(is) != 0; ++is)
    ;
  ++is;
  i = is;
  i -= 3;
  continue;
  }

  if (mem.get(i) == IIF || mem.get(i) == IENDIF || mem.get(i) == IIFELSE || mem.get(i) == IENDIFELSE || mem.get(i) == IEIF)
  {
  if (mem.get(i) == IIF)
  {
    ++ifcounter;
    reg.inif.insert();
    reg.ifflag.insert();
  }
  }
 }

and...

Code:

  case IIF:
  {
    if (reg.ninstruction != IIFBEGIN)
    crash((char *)"Invalid IF.");

    ++reg.ifcounter;
    reg.extrai.put(i, reg.ifcounter);
    reg.inif[reg.extrai.get(i)].type.ifb = i;
  }
  break;
 
  case IENDIF:
  {
    if (mem.get(i - 3) != IIFEND)
    crash((char *)"Invalid IF.");

    reg.extrai.put(i, reg.ifcounter);
    reg.inif[reg.extrai.get(i)].type.endif = i;
  }
  break;
 
  case IIFELSE:
  {
    if (reg.ninstruction != IIFBEGIN)
    crash((char *)"Invalid ELSE.");

    reg.extrai.put(i, reg.ifcounter);
    reg.inif[reg.extrai.get(i)].type.elseb = i;
  }
  break;
 
  case IENDIFELSE:
  {
    if (mem.get(i - 3) != IIFEND)
    crash((char *)"Invalid ELSE.");

    reg.extrai.put(i, reg.ifcounter);
    reg.inif[reg.extrai.get(i)].type.endelse = i;
  }
  break;
 
  case IEIF:
  {
    reg.extrai.put(i, reg.ifcounter);

    reg.inif[reg.extrai.get(i)].type.eif = i;
    ++reg.ifindex;
    --reg.ifcounter;
  }
  break;

  case IIFBEGIN:
  {
    ++reg.ifscope;
    reg.inif[reg.extrai.get(i)].type.scope = reg.ifscope;

    if (mem.get(i - 3) == IIF)
    reg.inif[reg.extrai.get(i)].type.ifb = i;
    else if (mem.get(i - 3) == IIFELSE)
    reg.inif[reg.extrai.get(i)].type.elseb = i;
    else
    crash((char *)"Invalid IF.");
  }
  break;

  case IIFEND:
  {
    --reg.ifscope;
    reg.inif[reg.extrai.get(i)].type.scope = reg.ifscope;

    if (mem.get(i + 3) == IENDIF)
    reg.inif[reg.extrai.get(i)].type.endif = i;
    else if (mem.get(i + 3) == IENDIFELSE)
    reg.inif[reg.extrai.get(i)].type.endelse = i;
    else
    crash((char *)"Invalid IF.");
  }
  break;

The loop now seems to work, but the code doesn't execute right still. This:

Code:

VERSION TVOID 0V


ALOAD TBOOLEAN true
IF TVOID 0V
IFBEGIN TVOID 0V
PRINTLN TSTRING "if..."

ALOAD TBOOLEAN false
IF TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif..."

IFEND TVOID 0V
ENDIF TVOID 0V
EIF TVOID 0V


ALOAD TBOOLEAN true
IF TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif2..."

ALOAD TBOOLEAN false
IF TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif2 subif..."

IFEND TVOID 0V
ENDIF TVOID 0V
IFELSE TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif2 subelse..."

IFEND TVOID 0V
ENDIFELSE TVOID 0V
EIF TVOID 0V

IFEND TVOID 0V
ENDIF TVOID 0V
EIF TVOID 0V

IFEND TVOID 0V
ENDIF TVOID 0V
IFELSE TVOID 0V
IFBEGIN TVOID 0V
PRINTLN TSTRING "else..."
IFEND TVOID 0V
ENDIFELSE TVOID 0V
EIF TVOID 0V

QUIT TVOID 0


END TVOID 0V

...results in infinite ifs...

des_a 03-19-2019 08:16 PM

I should probably give one more code block:

Code:

  case IIF:
  {
    if (reg.type != TVOID || reg.operand != 0)
    crash((char *)"Invalid IF instruction.");

    if (reg.accumulator.to_boolean().get() == (char *)"true")
    {
    reg.inif[reg.extrai.get(i)].type.value = true;   
    }
    else
    {
    reg.inif[reg.extrai.get(i)].type.value = false;

    i = reg.inif[reg.extrai.get(i)].type.endif;
    j = i + 1;
    k = i + 2;

    i -= 3, j -= 3, k -= 3;
    }
    reg.ifflag2[reg.ifindex2] = 1;
  }
  break;
 
  case IENDIF:
  {
    if (reg.type != TVOID || reg.operand != 0)
    crash((char *)"Invalid ENDIF instruction.");

    if (reg.ninstruction != IIFELSE && reg.ninstruction != IEIF)
    crash((char *)"Invalid ENDIF instruction.");

    if (!reg.inif[reg.extrai.get(i)].type.value)
    {
    if (reg.inif[reg.extrai.get(i)].type.elseb != 0)
    {
      i = reg.inif[reg.extrai.get(i)].type.elseb;
      j = i + 1;
      k = i + 2;

      i -= 3, j -= 3, k -= 3;
    }
    else
    {
      i = reg.inif[reg.extrai.get(i)].type.endelse;
      j = i + 1;
      k = i + 2;

      i -= 3, j -= 3, k -= 3;
    }
    }
  }
  break;
 
  case IIFELSE:
  {
    if (reg.type != TVOID || reg.operand != 0)
    crash((char *)"Invalid IFELSE instruction.");

    if (reg.inif[reg.extrai.get(i)].type.value)
    {
    if (reg.inif[reg.extrai.get(i)].type.endelse != 0)
    {
      i = reg.inif[reg.extrai.get(i)].type.endelse;
      j = i + 1;
      k = i + 2;

      i -= 3, j -= 3, k -= 3;
    }
    else
    {
      i = reg.inif[reg.extrai.get(i)].type.endelse;
      j = i + 1;
      k = i + 2;

      i -= 3, j -= 3, k -= 3;
    }
    }
  }
  break;
 
  case IENDIFELSE:
  {
    if (reg.type != TVOID || reg.operand != 0)
    crash((char *)"Invalid ENDIFELSE instruction.");

    if (reg.ninstruction != IEIF)
    crash((char *)"Invalid ENDIFELSE instruction.");
  }
  break;
 
  case IEIF:
  {
    if (reg.type != TVOID || reg.operand != 0)
    crash((char *)"Invalid EIF instruction.");

    ++reg.ifindex;
  }
  break;

  case IIFBEGIN:
  {

  }
  break;

  case IIFEND:
  {

  }
  break;


rtmistler 03-19-2019 09:53 PM

Quote:

Originally Posted by des_a (Post 5975218)
What references are still missing?

You hadn't until now defined what reg.ecount was.

You've got this class reg containing methods and variables which are not defined, nor described here. Same thing for the mem class. One can only infer what things mean if they come close in descriptive names, however that's not the way it should be because mistakes can be made by way of incorrect assumptions.

Further, there are tons of if-test result conditions where you are using definitions, macros, or type defines; once again, none of these are referenced or defined.

At this point I don't understand what, if any, question remains. You've posted so much additional code of similar lack of background explanation.

astrogeek 03-19-2019 11:47 PM

des_a, I know that you have been pointed here previously, but I ask you again to please review the Site FAQ for guidance in asking well formed questions.

The file signature, more blocks of code and your PNF language syntax are not relevant nor helpful to others taking their time to try to understand and answer your question.

If you are troubleshooting a loop problem, then begin by defining a simplest case which will reproduce the problem, with well defined loop parameters and entry and exit conditions. Then try to troubleshoot it using printf statements to show the state of those parameters on each pass and use gdb to help figure it out. If you cannot figure it out, then you will have at least collected the necessary information to post here when asking for help.

Please refrain from posting blocks of code and asking others to first try to understand how it should all work, then why it may not be working. That is not a proper use of this forum and is not respectful of the time others contribute to help with your problem.

Help others help you by presenting a minimal test case with well defined parameters relevant to a clearly stated question.

des_a 03-20-2019 12:44 AM

It looks like I didn't define the question well enough. The problem I'm facing may not be the loop at all anymore. The problem may be somewhere else in the code, probably in my PNF::execute() function.

des_a 03-20-2019 12:49 AM

Code:

VERSION TVOID 0V


ALOAD TBOOLEAN true
IF TVOID 0V
IFBEGIN TVOID 0V
PRINTLN TSTRING "if..."

ALOAD TBOOLEAN false
IF TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif..."

IFEND TVOID 0V
ENDIF TVOID 0V
EIF TVOID 0V

ALOAD TBOOLEAN true
IF TVOID 0V
IFBEGIN TVOID 0V

PRINTLN TSTRING "subif2..."

IFEND TVOID 0V
ENDIF TVOID 0V
EIF TVOID 0V

IFEND TVOID 0V
ENDIF TVOID 0V
IFELSE TVOID 0V
IFBEGIN TVOID 0V
PRINTLN TSTRING "else..."
IFEND TVOID 0V
ENDIFELSE TVOID 0V
EIF TVOID 0V

QUIT TVOID 0


END TVOID 0V

This is the simplest program that reproduces the error. In my most recent version of it, it doesn't print "subif2...".

Clearly it's jumping to the wrong part of the if. Why???

des_a 03-20-2019 12:52 AM

1 Attachment(s)
Documentation on the language so far.

des_a 03-20-2019 12:53 AM

Any other registers are new, so they are "scratch registers" for the current time. mem, is the program's memory.

des_a 03-20-2019 12:56 AM

If this is still not clear, I will just close this thread. I have one other possible source I can think of to find more information on what's going on, besides "luck". If I need to, I will do that, and then see what that produces, and then if needed still, THEN come back here, with hopefully a better question. If you need to tell me whether I should do that or not. Thanks!

des_a 03-20-2019 12:57 AM

P.S. - The problem is probably that I didn't phrase the question right, so I'm not getting as good of help as if I'd thought that through better...

rtmistler 03-20-2019 09:42 AM

Quote:

Originally Posted by des_a (Post 5975736)
If this is still not clear, I will just close this thread. I have one other possible source I can think of to find more information on what's going on, besides "luck". If I need to, I will do that, and then see what that produces, and then if needed still, THEN come back here, with hopefully a better question. If you need to tell me whether I should do that or not. Thanks!

I rather feel you could mark this as solved. This effectively closes the discussion
Quote:

Originally Posted by des_a (Post 5975734)
Documentation on the language so far.

Well aware of your history here and I'm not interested in investing my time and energy with helping you to create a language where you seem to be the sole proponent of it, and I do not agree with the premise for this language.

Meanwhile, your first post here used code in the C language, which is what I was addressing.

Your proposed language is mostly C, or very similar.

Quick review of that syntax tells me that there's nothing I can't do in the C language and that you've just written a wrapper for the C language.

To me this is a supporting architecture which I'd use for an R&D project. That's how things are done, you create customized macros, enumerations, type definitions, and functions to help the form of your architecture be what you intend it to be.

As Astrogeek says, you should review the forum guidelines about how to ask an effective question.

If you are going to persist with discussions about your invented language, then literally every thread you start should have a couple of things (a) a clear statement at the top of the first post which states this is what it is about, not "I have this loop" followed by a bunch of code and then continued discussion on your part with little direct questions, and (b) reference links for those interested in reviewing the language in general, such as your grammar document, and other information about this language.

Otherwise you will be wasting your time and the time of others

des_a 03-20-2019 12:26 PM

Quote:

To me this is a supporting architecture which I'd use for an R&D project. That's how things are done, you create customized macros, enumerations, type definitions, and functions to help the form of your architecture be what you intend it to be.
I agree. It's not what I intend it to be yet. But every working piece gets closer to what I intend it to be.


All times are GMT -5. The time now is 12:50 AM.