Author Topic: Preprocesser == MisParsed  (Read 369 times)

Robert

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Preprocesser == MisParsed
« on: January 18, 2020, 11:06:20 AM »
Code: [Select]

CONST ValueZero 0

$IF ValueZero == 0
  PRINT "Nothin' from nothin' leaves nothin'"
$ENDIF


The above compiles, although with a warning

bad.cpp(184): warning C4067: unexpected tokens following preprocessor directive - expected a newline

but will not function as expected because

Code: [Select]

$IF ValueZero == 0


is translated to

Code: [Select]

#if ValueZero = = 0// --FP2--


instead of

Code: [Select]

#if ValueZero == 0// --FP2--


MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 538
    • View Profile
Re: Preprocesser == MisParsed
« Reply #1 on: January 18, 2020, 01:43:28 PM »
There are likely several ways to kill that bug. 
Below is my solution.   
If anyone has a better solution, please share.

INSTRUCTIONS:

Replace the entire  FUNCTION  Emit_ConditionalCompilation () with these 2 functions   ( 1 new and 1 revised )


Code: [Select]

FUNCTION Emit_Conditional_Operator_Repair$(szArg$)
  LOCAL szTmp$
  szTmp$ = TRIM$(szArg$)
  REPLACE "= =" WITH "==" IN szTmp$
  REPLACE "! =" WITH "!=" IN szTmp$
  REPLACE "< =" WITH "<=" IN szTmp$
  REPLACE "> =" WITH ">=" IN szTmp$
  FUNCTION = szTmp$
END FUNCTION


FUNCTION Emit_ConditionalCompilation(sWord$, FuncRetnFlag AS PINT)
  SELECT CASE sWord$

    CASE "~ifndef"
    InIfDef$ = "#ifndef "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~ifdef"
    InIfDef$ = "#if defined "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$

    IF InFunc <> eNotInOne THEN
      FPRINT Outfile, InIfDef$,"// OUTFILE"
      InIfDef$ = "FP3"
    ELSE
      IF InMain THEN
        FPRINT Outfile, InIfDef$, "// --FP2--"
      END IF
    END IF

    CASE "~if"
    InIfDef$ = "#if "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne THEN
      FPRINT Outfile, InIfDef$,"// OUTFILE"
      InIfDef$ = "FP3"
    ELSE
      IF InMain THEN
        FPRINT Outfile, InIfDef$, "// --FP2--"
      END IF
    END IF

    CASE "~else"
    InIfDef$ = "#else"
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~elseif"
    InIfDef$ = "#elif defined "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~endif"
    IF InIfDef$ = "FP3" THEN
      FPRINT FP3, "#endif  // FP3"
    ELSE
      FPRINT Outfile, "#endif  // Main"
    END IF

    IF ConstLastDef$ = "FP_CST" THEN
      FPRINT FP_CST, "#endif  // FP_CST"
    END IF
    InIfDef$ = "#endif  // other"

    IF InConditional = 0 THEN
      InIfDef$ = ""
      ConstLastDef$ = ""
    END IF

    CASE "~pragmaoptimizeon"
    FPRINT Outfile, "#ifdef __POCC__"
    FPRINT Outfile, "#pragma optimize(time)"
    FPRINT Outfile, "#endif"

    FPRINT Outfile, "#ifdef __LCC__"
    FPRINT Outfile, "#pragma optimize(1)"
    FPRINT Outfile, "#endif"

    CASE "~pragmaoptimizeoff"
    FPRINT Outfile, "#ifdef __POCC__"
    FPRINT Outfile, "#pragma optimize(none)"
    FPRINT Outfile, "#endif"

    FPRINT Outfile, "#ifdef __LCC__"
    FPRINT Outfile, "#pragma optimize(0)"
    FPRINT Outfile, "#endif"

    CASE ELSE
    CALL EmitOld(FuncRetnFlag)

  END SELECT
  FUNCTION = 0
END FUNCTION ' Emit_ConditionalCompilation



Robert

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Preprocesser == MisParsed
« Reply #2 on: January 18, 2020, 03:44:51 PM »
There are likely several ways to kill that bug. 
Below is my solution.   
If anyone has a better solution, please share.

INSTRUCTIONS:

Replace the entire  FUNCTION  Emit_ConditionalCompilation () with these 2 functions   ( 1 new and 1 revised )


Code: [Select]

FUNCTION Emit_Conditional_Operator_Repair$(szArg$)
  LOCAL szTmp$
  szTmp$ = TRIM$(szArg$)
  REPLACE "= =" WITH "==" IN szTmp$
  REPLACE "! =" WITH "!=" IN szTmp$
  REPLACE "< =" WITH "<=" IN szTmp$
  REPLACE "> =" WITH ">=" IN szTmp$
  FUNCTION = szTmp$
END FUNCTION


FUNCTION Emit_ConditionalCompilation(sWord$, FuncRetnFlag AS PINT)
  SELECT CASE sWord$

    CASE "~ifndef"
    InIfDef$ = "#ifndef "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~ifdef"
    InIfDef$ = "#if defined "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$

    IF InFunc <> eNotInOne THEN
      FPRINT Outfile, InIfDef$,"// OUTFILE"
      InIfDef$ = "FP3"
    ELSE
      IF InMain THEN
        FPRINT Outfile, InIfDef$, "// --FP2--"
      END IF
    END IF

    CASE "~if"
    InIfDef$ = "#if "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne THEN
      FPRINT Outfile, InIfDef$,"// OUTFILE"
      InIfDef$ = "FP3"
    ELSE
      IF InMain THEN
        FPRINT Outfile, InIfDef$, "// --FP2--"
      END IF
    END IF

    CASE "~else"
    InIfDef$ = "#else"
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~elseif"
    InIfDef$ = "#elif defined "
    FOR INT i = 2 TO Ndx
      InIfDef$ = InIfDef$ + Stk$[i] + " "
    NEXT
    InIfDef$ = Emit_Conditional_Operator_Repair$(InIfDef$)
    ConstLastDef$ = InIfDef$
    IF InFunc <> eNotInOne OR InMain THEN
      FPRINT Outfile, InIfDef$
    ELSE
      FPRINT FP_CST, InIfDef$
    END IF

    CASE "~endif"
    IF InIfDef$ = "FP3" THEN
      FPRINT FP3, "#endif  // FP3"
    ELSE
      FPRINT Outfile, "#endif  // Main"
    END IF

    IF ConstLastDef$ = "FP_CST" THEN
      FPRINT FP_CST, "#endif  // FP_CST"
    END IF
    InIfDef$ = "#endif  // other"

    IF InConditional = 0 THEN
      InIfDef$ = ""
      ConstLastDef$ = ""
    END IF

    CASE "~pragmaoptimizeon"
    FPRINT Outfile, "#ifdef __POCC__"
    FPRINT Outfile, "#pragma optimize(time)"
    FPRINT Outfile, "#endif"

    FPRINT Outfile, "#ifdef __LCC__"
    FPRINT Outfile, "#pragma optimize(1)"
    FPRINT Outfile, "#endif"

    CASE "~pragmaoptimizeoff"
    FPRINT Outfile, "#ifdef __POCC__"
    FPRINT Outfile, "#pragma optimize(none)"
    FPRINT Outfile, "#endif"

    FPRINT Outfile, "#ifdef __LCC__"
    FPRINT Outfile, "#pragma optimize(0)"
    FPRINT Outfile, "#endif"

    CASE ELSE
    CALL EmitOld(FuncRetnFlag)

  END SELECT
  FUNCTION = 0
END FUNCTION ' Emit_ConditionalCompilation


Thank you for the rapid response.

Perhaps

Conditional OR   ||
and
Conditional AND &&

should be added to the list?


MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 538
    • View Profile
Re: Preprocesser == MisParsed
« Reply #3 on: January 18, 2020, 04:28:13 PM »
Yep ... I just tested and && and || need to be handled as well.
 
I think that's all the scenarios one is likely to encounter.


Below is my updated function Emit_Conditional_Operator_Repair$ with && and || now handled.

Today's changes will be included in 7.4.0, barring any surprises.




Code: [Select]

FUNCTION Emit_Conditional_Operator_Repair$(szArg$)
  LOCAL szTmp$
  szTmp$ = TRIM$(szArg$)
  REPLACE "= =" WITH "==" IN szTmp$
  REPLACE "! =" WITH "!=" IN szTmp$
  REPLACE "< =" WITH "<=" IN szTmp$
  REPLACE "> =" WITH ">=" IN szTmp$
  REPLACE "| |" WITH "||" IN szTmp$
  REPLACE "& &" WITH "&&" IN szTmp$
  FUNCTION = szTmp$
END FUNCTION


Robert

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Preprocesser == MisParsed
« Reply #4 on: July 14, 2020, 03:00:32 PM »
Yep ... I just tested and && and || need to be handled as well.
 
I think that's all the scenarios one is likely to encounter.


Below is my updated function Emit_Conditional_Operator_Repair$ with && and || now handled.

Today's changes will be included in 7.4.0, barring any surprises.




Code: [Select]

FUNCTION Emit_Conditional_Operator_Repair$(szArg$)
  LOCAL szTmp$
  szTmp$ = TRIM$(szArg$)
  REPLACE "= =" WITH "==" IN szTmp$
  REPLACE "! =" WITH "!=" IN szTmp$
  REPLACE "< =" WITH "<=" IN szTmp$
  REPLACE "> =" WITH ">=" IN szTmp$
  REPLACE "| |" WITH "||" IN szTmp$
  REPLACE "& &" WITH "&&" IN szTmp$
  FUNCTION = szTmp$
END FUNCTION


Hi MrBCX:

Just a wild guess, based on lurking your $PP exchange with James, but maybe :: needs to be added to the list?

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 538
    • View Profile
Re: Preprocesser == MisParsed
« Reply #5 on: July 14, 2020, 03:10:47 PM »
Unnecessary ... as I reported earlier:

Code: [Select]
As a test, I substituted   "☼☼" with "::" just before it hits the pre-processor.
Not only was there no difference but it translated correctly when I changed

this ------> Function CWindow::Do_Events(nCmdShow = 0 As Long) As Long

to this ---> Function CWindow::Do_Events(nCmdShow  As Long) As Long

On a separate point, today's exercise has further convinced me that the leading
underscore on _ProcessLine needs to go.  I've made those changes in 7.5.0 and
have documented same in the upcoming Revisions.

I plan on releasing 7.5.0 this week.