Menu

An idea: Feedback needed

Anobium
2021-06-22
2021-06-25
1 2 > >> (Page 1 of 2)
  • Anobium

    Anobium - 2021-06-22

    I have an idea but I am not sure of the requirement.


    Background

    The other day there was a post where a program had been created that had a missing prerequisite command. The example was for hardware I2C. Where you cannot use HWI2CSend ( as this example ) without having HWI2CMode MASTER | SLAVE. So, if HWI2CSend is used and HWI2CMode is missing the code is compile but the program does not work.

    Potential Solution

    See https://sourceforge.net/p/gcbasic/discussion/579125/thread/ce0f6cfd8e/#7f2d the conversation has moved on.

    *This is a potential solution of this example and others examples (however, I can only think of two examples at the moment).

    We add syntax checking for prerequisite commands. Like this.

    'HWI2C syntax checker
    cmd = HI2CSend, required = HI2CMode, error = "Missing command HI2CMode"
    'HW Serial syntax checker
    cmd = HSerPrint, required = USARTBAUDRATE, error = "Missing Constant USARTBAUDRATE"
    

    Where the compiler could check the user program for the use of HI2CSend and the syntax prerequisite is HI2CMode. If HI2CMode is not present in the user code then issue the error "Missing command HI2CMode".

    Same for serial. Where the compiler could check the user program for the use of HSerPrint and the syntax prerequisite is a constant called USARTBAUDRATE. If USARTBAUDRATE is not present in the user code then issue the error "Missing Constant USARTBAUDRATE".


    Does this add value ? What else could this cover?

    Can you think of other uses?

    Evan
    *

     

    Last edit: Anobium 2021-06-23
  • mkstevo

    mkstevo - 2021-06-22

    Both your examples make good sense, it would be enlightening to have some indication of a potential eror.

    If I could add another possible case to consider, that of "printing" to an LCD scren. On some projects I've made the LCD optional by surrounding it with conditional define statements. Should I accidentally leave any commands which are contained in the LCD header (and library) an error is raised but it makes an obscure reference to LCDSYSTEMP.0 and doesn't show the source of any error - a remaining Locate or print command usually in my case. Not sure if this could be easily fixed, and now I'm aware of it, I can track it down mostly, but it was very confusing and difficult to find the first few times when I've copied and passted "working" code from one program to another.

     
    • Anobium

      Anobium - 2021-06-22

      @mkstevo

      LCD should be resolvable.

      We will need a single item to check. Like a single constant we can check against. What would you advise? Remember, we there are many different LCD configs.

      We could have more than one prereq.

      Evan

       
  • Anobium

    Anobium - 2021-06-22

    This approach may have to an extension to the current source. Something like

    PSUEDO CODE - expand this

    function PreRequisitesMet ()
        dim  PreRequisitesMetState as Integer
         PreRequisitesMetState = 0
    
         if IsNOTUserProgramCode then return -1 'true
    
         'HWI2C
         if  methodused(HI2CSend)  and NOT methodused(HI2CMode) then return 0 'false
    
         'SERIAL
         if  methodused(HSERPRINT)  and NOT constantdefined(USART_BAUD_RATE) then return 0 'false
    
         'LCD ???
         if  methodused(PRINT)  and NOT (  constantdefined(LCD_IO = 4) AND constantdefined(LCD_RW) etc. [Evan.. I need this defining] then return 0 'false
    
    end function
    

    The concept code.

     
  • mkstevo

    mkstevo - 2021-06-22

    Edited as we cross posted.

    Locate and (or) Print are the two that I find trip me up.

    Would that make sense?

     

    Last edit: mkstevo 2021-06-22
  • Chris Roper

    Chris Roper - 2021-06-22

    A laudable idea but a potential can of worms.
    @mkstevo has just highlighted one of the issues I was thinking of as a potential trap.

    Print and Locate are two of the most commonly used BASIC methods but GCBASIC has them dedicated to LCD.

    As a result it is common to use #Define to redirect i.e.

        #define Print HSerPrint
    

    This is especially useful when talking to a VT100 Terminal emulation which responds to commands such as Locate.

    Those are the fist two command that come to mind but I am sure there are many others that have been used outside of the original GCBASIC intended context.

     
  • Anobium

    Anobium - 2021-06-23

    @caroper You are correct. Trying to trap HWSerial with this approach will fail. Too many traps like the one you highlighted.

    May be HWSerial is in the too hard category.

     
  • Anobium

    Anobium - 2021-06-23

    So, thinking aloud.

    An alternative approach.

    1. Make 'HWI2CMode MASTER' the default. At the moment there is no default hence the issue.
    2. Add HWI2C port direction to the DAT files. So, we can make the setting of the ports automatic.
    3. For HSerPrint operations. Get the compiler to examine the generated ASM. If the sub INITUSART has no code.. then, the HWUSART is not setup ie there is no USART_BAUD_RATE
    4. For LCD. Get the compiler to examine the error generated by not having the LCD setup correctly. There are specific error messages that could be issued when the LCD ports are not defined. So, rather than (as-is) lcd.h (559): Error: SYSLCDTEMP.0 is not a valid I/O pin or port change to something like (could-be) lcd.h (559): Error: LCD_RW is not a valid I/O pin or port please ensure you have defined LCD_RW port constant in your program (this is one example).

    This approach is a lot more work than a generic handler but we need to resolve this traps for users.

    What are the other traps?

     

    Last edit: Anobium 2021-06-23
  • mkstevo

    mkstevo - 2021-06-23

    It isn't a big problem for me, now I understand the cause(s) of it. If I could wave a magic wand, the error message raised would not point to "lcd.h", but to the position in my code that caused "lcd.h" to be built into my code when I wasn't expecting it. Or an optional Delphi like "Uses" clause. Where only units (or headers) declared as being "Used" were built and assembled?

    As I say, it isn't a big problem, though it has confused me from time to time.

     
    • Anobium

      Anobium - 2021-06-23

      I may be able to point to the incorrect constant but today the libraries do not any concept of what was called to create the error.

      So, I am thinking of adding a 'clue' to the library to aid the messaging when an error happens.

      No promises this will happen yet. Just gathering requirements at the moment.

       
  • mkstevo

    mkstevo - 2021-06-23

    Thanks for your consideration.

    Would enabling or allowing an optional "Uses" clause {similar in my mind to "Option Explicit"} to prevent automatic inclusion of system libraries and headers be more than a few lines of code?

     
    • Anobium

      Anobium - 2021-06-23

      How would this help?

      The GCB libraries are only included if the user program calls a sub, function or macro (the methods) within that specific library file.

      Example LCD.h it is automatically '#included' however the methods are not compiled unless the user calls one of the methods. Like PRINT. So, then, the #startup is called, which in turn will call the INITLCD.

      Example HEF.F it is automatically '#included' however the methods are not compiled unless the user calls one of the methods. As very few programs call the HEF methods no code is compiled.

       
  • mkstevo

    mkstevo - 2021-06-23

    Thanks for giving some clarity on how that works in some greater detail.

    The way my mind works, I would prefer to see no methods compiled (or made available) at all, unless I requested them.

    When a new unit was created in Delphi, it automatically added some of the 'standard' libraries to a default "Uses" clause - a little like this:

    uses Windows, Messages, SysUtils;
    

    Most programs would require the 'Windows' unit, but in very rare TSR non-GUI cases this could possibly be removed and then not compiled. Likewise 'Messages' and SysUtils. If a procedure then attempted to utilise something that was within 'SysUtils' , an error would be raised - hopefully at, or near to, the section of code which tried to call the missing library.

    I concede that it is almost certainly just me that would benefit from a methodology which put the onus on the programmer to decide which libraries would potentially be included (or excluded), but it would be on my wish list.

     
    • Anobium

      Anobium - 2021-06-23

      Great Cow BASIC is smart. The only methods compiled are the methods used. It is highly optimised and therefore I see no benefit of the 'uses'.

      To clarify. There are 100s of methods in the core libraries and very few are compiled.

      Think that Great Cow BASIC optimises for you. Because, it does.

       

      Last edit: Anobium 2021-06-23
      • mkstevo

        mkstevo - 2021-06-23

        As I said, it is something I'd quite like. I realise almost no-one else will.

         
        • Anobium

          Anobium - 2021-06-24

          @mkstevo

          Am I missing the point?

          I will provide more insights to try to show you that that Great Cow BASIC does what you want automatically.


          Using the code below as the example.

          #chip 16f877a
          #option UserCodeOnly BASPROGRAMSTART:
          #option Noconfig
          
          BASPROGRAMSTART:
          

          Compile this and you will see in the ASM as follows. Note there is NO real program ASM, no config, no INITSYS. Just the ORG statement and the PAGESEL. This is the highest level of optimisation. There is essentially no real code.

          ;Program compiled by Great Cow BASIC (0.98.07 2021-05-25 (Windows 64 bit)) for Microchip MPASM
          ;Need help? See the GCBASIC forums at http://sourceforge.net/projects/gcbasic/forums,
          ;check the documentation or email w_cholmondeley at users dot sourceforge dot net.
          
          ;********************************************************************************
          
          ;Set up the assembler options (Chip type, clock source, other bits and pieces)
           LIST p=16F877A, r=DEC
          #include <P16F877A.inc>
          
          ;********************************************************************************
          
          ;VECTORS
              ORG 0
              PAGESEL BASPROGRAMSTART
              GOTO    BASPROGRAMSTART
          
          ;********************************************************************************
          
          ;ORG 5
          
          
          ;START OF THE MAIN PROGRAM
          BASPROGRAMSTART
          
          ;********************************************************************************
          
          ;ORG 2048
          ;ORG 4096
          ;ORG 6144
          
           END
          

          Now, change to, compile.

          #chip 16f877a
          #option Noconfig
          

          You will see that INITSYS is called. INITSYS is part of system.h so the compiler 'uses' system.h automatically. How?


          Find this file C:\GCB@Syn\GreatCowBasic\Include\lowlevel.dat. Take a copy of all the entries in this file. Now remove all the entries. Save. Compile the program.

          #chip 16f877a
          #option Noconfig
          

          You will see INITSYS is missing. Because the compiler cannot find a method called INITSYS - so, it does not add.


          So, what is lowlevel.dat? It is essentially a set of multiline #include statements.

          Proof. Add the #include for system.h

          #chip 16f877a
          #option Noconfig
          
          #include "C:\GCB@Syn\GreatCowBasic\Include\lowlevel\system.h"
          

          Compile, review the ASM and you will see the INITSYS is now present.


          Now revert lowlevel.dat and save.


          So, lowlevel.dat contains all the default includes. These entries MUST NOT and CANNOT be removed as there are dependencies between these include files and I truly dont know what these dependencies are - you will simply break the compiler.

          Think of lowlevel.dat being the equivalent of uses i.e.

          uses picas.h, a-d.h, pwm.h, rs232.h, eeprom.h, sound.h, stdbasic.h, 7segment.h, lcd.h, ps2.h, timer.h, system.h, hwspi.h, keypad.h, random.h, string.h, usart.h, i2c.h, hwi2c.h, hwi2c2.h, pwm16.h, saf.h, hef.h, spisram.h

          Remember, removal of any of the entries in lowlevel.dat WILL NOT reduce the code generated. Code is only generated from any of these lowlevel include files when a method is called (for every library 'used' the #startup [if present] is called to initialise the library).

          And, if any of these libraries add program code when not 'used' then this would be a bug and we would resolve.


          Hugh has done a wonderful job on the optimisation and the simplicity of solution with respect to these include files. The compiler does a many things to make the programming experience simple.

          Lowlevel library support is an example of ease of use.

           

          Last edit: Anobium 2021-06-24
  • mkstevo

    mkstevo - 2021-06-24

    It isn't that I don't appreciate the optimisation the the compiler does, and how well it is able to determine which libraries or parts of libraries are compiled.

    I have no issue with the size of the compiled programs nor how minimal the footprint of compiled code is, the compiler is the work of many geniuses, far cleverer than me and much better programmers too.

    It was just a thought that ran through my head.

    It was a feature of Delphi that I used extensively as I modified and extended the original libraries.

     
    • Anobium

      Anobium - 2021-06-24

      Not a problem. You can adapt Great Cow BASIC also. ;-)

       
      • mkstevo

        mkstevo - 2021-06-24

        I can, but with the proviso that I only update an existing library, I've not found a way to have both. The altered library can't seem to be renamed as 'My_extendedLibrary.h' and used alongside the original, switching between the two with a 'Uses' clause, as the original library appears to always be called if any of the functions and subroutines have the same names - which they would.

        It is at this point I felt a 'Uses' clause would be benefficial. I could see at a glance what libraries I was, and wasn't using - modified or not.

        As I' said, it was a thought that popped into my head. Something I liked and used a lot.

         
        • Anobium

          Anobium - 2021-06-24

          Oh. That is what you want to do.

          Can I clarify? You want to change/replace/update an existing method?

           
          • mkstevo

            mkstevo - 2021-06-25

            Given that it would break the compiler and it isn't anything that is required by anyone else, I think the thought should be popped back into my head, shoved to the back and not let out again. Ever!

             

            Last edit: mkstevo 2021-06-25
            • kent_twt4

              kent_twt4 - 2021-06-25

              Oh, I can sympathize with the dilemma on alt libraries. Valid reasoning all around. Ultimately I have had to rename the methods within my alt libraries so as to coexist with existing libraries, kind of a hassle, but thankfully not used much.

              It is an Easter egg hunt when I need to use one when last used 5 compiler revisions ago.

               
              • Anobium

                Anobium - 2021-06-25

                You can replace any method with your own method. Then, you can upgrade the compiler with some ease. Do this in your user code leaving the original library method intact.

                #define UsartInit myUsartInit
                

                where the first parameter is the original method, and, the second parameter the new target method.

                 
                • kent_twt4

                  kent_twt4 - 2021-06-25

                  For sure, that is another way to handle it. Whatever it takes to keep things straight in our own individual minds :-)

                   
                  • Anobium

                    Anobium - 2021-06-25

                    This is the method I use to develop Great Cow BASIC. So, I can develop new capabilities.

                     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.