BBC BasicSDL2 Diary Program

Discussions about the BBC BASIC language, with particular reference to BB4W and BBCSDL
RNBW
Posts: 38
Joined: Thu 05 Apr 2018, 21:41

BBC BasicSDL2 Diary Program

Post by RNBW »

I'm developing a diary program in BBC BASIC SDL 2.0 (version 1.44a on Windows). I have a small program that works when it's minimal, but when I add more code I get "Syntax error" with ERL = 0.

Here is the minimal program:

Code: Select all

      INSTALL @lib$ + "dlglib"
      PROC_setdialogpalette

      DIM DayView$(300)
      FOR I% = 0 TO 300
        DayView$(I%) = ""
      NEXT
      DayView$(1) = "Testing the update procedure"

      dlg% = FN_newdialog("Test", 80, 60)

      PROC_static(dlg%, "Day View", 101, 4, 4, 70, 10, 0)
      DayListID% = FN_setproc(PROCdummy())
      PROC_listbox(dlg%, "", DayListID%, 4, 16, 70, 30, 0)

      PROC_setlistboxarray(dlg%, DayListID%, DayView$(), DIM(DayView$(),1))

      PROC_button(dlg%, "Close", 1, 20, 48, 40, 10, 0)

      result% = FN_showdialog(dlg%, &80000000, &80000000)
      PROC_closedialog(dlg%)
      CLS
      END

      DEF PROCdummy()
      ENDPROC     
But when I extend it with helper functions defined after END, I get Syntax error with ERL = 0. Can you tell me the exact rules for where DEFs must be placed in relation to (a) the main program, (b) other DEFs, and (c) END? The manual doesn't seem to say explicitly and I'm struggling.

It would be useful if someone could give me a working template or an example of a dialog box plus some helper functions.

I am trying to build the Diary Program and this was my last attempt to get runnable code, which gives me a syntax error:

Code: Select all

      REM ================================================================
      REM MY DIARY - BBC BASIC SDL 2.0
      REM Phase 3 Step 6: Full diary with correct definition order
      REM ================================================================

      INSTALL @lib$ + "dlglib"
      PROC_setdialogpalette

      OfflinePath$ = "C:/Users/raywo/Documents/DiaryData_BBCSDL2/"

      DIM MonthName$(12)
      MonthName$(1)  = "January"
      MonthName$(2)  = "February"
      MonthName$(3)  = "March"
      MonthName$(4)  = "April"
      MonthName$(5)  = "May"
      MonthName$(6)  = "June"
      MonthName$(7)  = "July"
      MonthName$(8)  = "August"
      MonthName$(9)  = "September"
      MonthName$(10) = "October"
      MonthName$(11) = "November"
      MonthName$(12) = "December"

      DIM DayView$(300)
      DIM MonthView$(3000)

      Year%  = 2026
      Month% = 9
      Day%   = 17

      dlg% = FN_newdialog("My Diary", 160, 140)

      PROC_static(dlg%, "Day View", 101, 4, 20, 60, 10, 0)
      DayListID% = FN_setproc(PROCdummy())
      PROC_listbox(dlg%, "", DayListID%, 4, 32, 70, 90, 0)

      PROC_static(dlg%, "Month View", 103, 80, 20, 60, 10, 0)
      MonthListID% = FN_setproc(PROCdummy())
      PROC_listbox(dlg%, "", MonthListID%, 80, 32, 76, 90, 0)

      PROC_button(dlg%, "PrevYear",  FN_setproc(PROCprevYear()),  4,   126, 24, 12, 0)
      PROC_button(dlg%, "PrevMonth", FN_setproc(PROCprevMonth()), 30,  126, 24, 12, 0)
      PROC_button(dlg%, "Today",     FN_setproc(PROCtoday()),     56,  126, 24, 12, 0)
      PROC_button(dlg%, "NextMonth", FN_setproc(PROCnextMonth()), 82,  126, 24, 12, 0)
      PROC_button(dlg%, "NextYear",  FN_setproc(PROCnextYear()),  108, 126, 24, 12, 0)
      PROC_button(dlg%, "Close",     1,                            136, 126, 20, 12, 0)

      PROC_button(dlg%, "Open",    FN_setproc(PROCopen()),    4,  140, 20, 12, 0)
      PROC_button(dlg%, "New",     FN_setproc(PROCnew()),     26, 140, 20, 12, 0)
      PROC_button(dlg%, "Refresh", FN_setproc(PROCrefresh()), 48, 140, 28, 12, 0)

      PROC_button(dlg%, "Search", FN_setproc(PROCsearch()), 4,  154, 20, 12, 0)
      PROC_button(dlg%, "Export", FN_setproc(PROCexport()), 26, 154, 20, 12, 0)
      PROC_button(dlg%, "Recent", FN_setproc(PROCrecent()), 48, 154, 20, 12, 0)
      PROC_button(dlg%, "Sync",   FN_setproc(PROCsync()),   70, 154, 20, 12, 0)

      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()

      result% = FN_showdialog(dlg%, &80000000, &80000000)
      PROC_closedialog(dlg%)
      CLS
      END

      REM ================================================================
      REM DEFINITIONS IN DEPENDENCY ORDER
      REM ================================================================

      DEF PROCdummy()
      ENDPROC

      DEF FN_TwoDigits$(n%)
      IF n% < 10 THEN = "0" + STR$(n%) ELSE = STR$(n%)
      ENDPROC

      DEF FN_FourDigits$(n%)
      LOCAL s$
      s$ = STR$(n%)
      WHILE LEN(s$) < 4
        s$ = "0" + s$
      ENDWHILE
      = s$

      DEF FN_GetField$(s$, field%, sep$)
      LOCAL i%, p%, endpos%
      p% = 1
      FOR i% = 1 TO field%-1
        p% = INSTR(s$, sep$, p%) + 1
      NEXT
      IF p% = 0 THEN = ""
      endpos% = INSTR(s$, sep$, p%)
      IF endpos% = 0 THEN = MID$(s$, p%) ELSE = MID$(s$, p%, endpos%-p%)
      ENDPROC

      DEF FN_DayOfWeek%(y%, m%, d%)
      LOCAL a%, yy%, mm%
      yy% = y% : mm% = m%
      IF mm% < 3 THEN mm% += 12 : yy% -= 1
      a% = d% + (13*(mm%+1)) DIV 5 + yy% + yy% DIV 4 + yy% DIV 100 + yy% DIV 400
      a% = (a% + 6) MOD 7
      = a%

      DEF FN_DayName$(dow%)
      LOCAL names$
      names$ = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday"
      = FN_GetField$(names$, dow%+1, ",")

      DEF FN_DiaryFile$()
      LOCAL d$
      d$ = OfflinePath$
      d$ = d$ + FN_FourDigits$(Year%) + "/"
      d$ = d$ + FN_TwoDigits$(Month%) + "/"
      d$ = d$ + FN_FourDigits$(Year%) + "-"
      d$ = d$ + FN_TwoDigits$(Month%) + "-"
      d$ = d$ + FN_TwoDigits$(Day%) + ".txt"
      = d$

      DEF PROC_updateviews()
      LOCAL items%
      items% = DIM(DayView$(),1)
      PROC_setlistboxarray(dlg%, DayListID%, DayView$(), items%)
      items% = DIM(MonthView$(),1)
      PROC_setlistboxarray(dlg%, MonthListID%, MonthView$(), items%)
      ENDPROC

      DEF PROC_FillDayView()
      LOCAL i%, line%, f%, t$, d$
      FOR i% = 0 TO 300
        DayView$(i%) = ""
      NEXT
      d$ = FN_DiaryFile$()
      line% = 1
      DayView$(line%) = FN_DayName$(FN_DayOfWeek%(Year%,Month%,Day%)) + ", "
      DayView$(line%) = DayView$(line%) + FN_TwoDigits$(Day%) + " " + MonthName$(Month%) + " " + FN_FourDigits$(Year%)
      line% += 1
      DayView$(line%) = "----------------------------------------"
      line% += 1
      f% = OPENIN(d$)
      IF f% = 0 THEN
        DayView$(line%) = "  (No entry for this day)"
        line% += 1
      ELSE
        WHILE NOT EOF#f%
          t$ = GET$#f%
          IF LEN(t$) > 0 THEN
            IF LEN(t$) > 66 THEN t$ = LEFT$(t$, 66) + "..."
            DayView$(line%) = "  " + t$
            line% += 1
            IF line% > 290 THEN EXIT WHILE
          ENDIF
        ENDWHILE
        CLOSE #f%
      ENDIF
      ENDPROC

      DEF PROC_FillMonthView()
      LOCAL i%, line%
      FOR i% = 0 TO 3000
        MonthView$(i%) = ""
      NEXT
      line% = 1
      MonthView$(line%) = "Month: " + MonthName$(Month%) + " " + FN_FourDigits$(Year%)
      line% += 1
      MonthView$(line%) = "----------------------------------------"
      line% += 1
      MonthView$(line%) = "Selected: " + FN_TwoDigits$(Day%) + " " + MonthName$(Month%) + " " + FN_FourDigits$(Year%)
      ENDPROC

      DEF PROCprevYear(D%, I%)
      Year% -= 1
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCprevMonth(D%, I%)
      Month% -= 1
      IF Month% < 1 THEN Month% = 12 : Year% -= 1
      IF Day% > 28 THEN Day% = 28
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCtoday(D%, I%)
      Year% = 2026 : Month% = 9 : Day% = 17
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCnextMonth(D%, I%)
      Month% += 1
      IF Month% > 12 THEN Month% = 1 : Year% += 1
      IF Day% > 28 THEN Day% = 28
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCnextYear(D%, I%)
      Year% += 1
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCopen(D%, I%)
      PRINT "Open clicked"
      ENDPROC

      DEF PROCnew(D%, I%)
      PRINT "New clicked"
      ENDPROC

      DEF PROCrefresh(D%, I%)
      PROC_FillDayView()
      PROC_FillMonthView()
      PROC_updateviews()
      PROC_refreshdialog(D%)
      ENDPROC

      DEF PROCsearch(D%, I%)
      PRINT "Search clicked"
      ENDPROC

      DEF PROCexport(D%, I%)
      PRINT "Export clicked"
      ENDPROC

      DEF PROCrecent(D%, I%)
      PRINT "Recent clicked"
      ENDPROC

      DEF PROCsync(D%, I%)
      PRINT "Sync clicked"
      ENDPROC
Help will be appreciated, because I seem to be going around in circles.
Phil_Thatcham
Posts: 13
Joined: Tue 03 Apr 2018, 11:59

Re: BBC BasicSDL2 Diary Program

Post by Phil_Thatcham »

The ERL for your Syntax error is not helpful because your program lines are not numbered.

Numbering (Utilities/Renumber...) is useful when writing/debugging.

Numbering conventionally (start at 10, increment in 10s) reveals that the error emerges in line 580 when you call PROC_FillDayView().

I can't help with the dialog box / Syntax error themselves.

In another post I referred you to the manual for its explanation of where to place procedures.

They must go somewhere they won't be executed accidentally, but only when called. The safest place to put them is after END.

I don't think the order is important. If PROC_A calls PROC_B, you don't need to define PROC_B before PROC_A.

PT
User avatar
JeremyNicoll
Posts: 95
Joined: Sun 26 Jul 2020, 22:22
Location: Edinburgh

Re: BBC BasicSDL2 Diary Program

Post by JeremyNicoll »

Two of your /function/ definitions wrongly have ENDPROC statements after them. That's in FNs: FN_TwoDigits$ and FN_GetField$.

I don't know if they could cause errors - nothing should try to execute them... but it's careless coding.
svein
Posts: 61
Joined: Tue 03 Apr 2018, 19:34

Re: BBC BasicSDL2 Diary Program

Post by svein »

You can't define or use PROC with empty parentheses.

Either you use:

PROCdummy(list, of, variables)
END

DEF PROCdummy(list, of, variables)
ENDPROC

OR

PROCdummy
END

DEF PROCdummy
ENDPROC

Svein