Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 19:04 17 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Strange subroutine behaviour

Author Message
BrianP
Senior Member

Joined: 30/03/2017
Location: Australia
Posts: 292
Posted: 07:11pm 17 Aug 2017
Copy link to clipboard 
Print this post

Hi all

I'm having a very strange (to me) issue with a very simple subroutine in a current program development. If set as a subroutine (sub xxx / end sub) structure it will not work (doesn't get called - but no errors. An END or PAUSE statement as the first line is never executed).

The calling method is by the name only DATESWAP as in the manual & all other subroutines in the program do work correctly using this method. I've tried renaming it without success. Again, all other subroutines in the program work fine this way.

If I set it as a Label & call it with gosub DATESWAP it works!

As will be obvious the purpose of this routine is solely to convert the DATE$ format to display as European format (yyyy-mm-dd).

Try as I might I cannot get it to work as a subroutine - only as a label. No big deal, but curious as to why? I'm probably missing something very basic (no pun) but this is as per the example in the MMBasic v.5.4 manual. Current version is 5.405 on an E28 MK2. (But I am anal retentive...)

Losing more of the already thinning hair... (age 74)

Examples below...

Cheers

Brian P.

'if called as a label - gosub DATESWAP - it works as intended
'
DATESWAP:
edate$=right$(date$,4)+mid$(date$,3,3)+"-"+left$(date$,2)
RETURN
'
'
'if called as a sub - DATESWAP - it never happens (or should I use GOTO DATESWAP?)
'
SUB DATESWAP
edate$=right$(date$,4)+mid$(date$,3,3)+"-"+left$(date$,2)
END SUB
'

 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 07:34pm 17 Aug 2017
Copy link to clipboard 
Print this post

Hello Brian

I copied your code got the following:


> list
Dim edate$
Print edate$ 'just to show the variable is ok
dateswap
Print edate$ ' after the Sub


'if called as a label - gosub DATESWAP - it works as intended
'
'DATESWAP:
'edate$=Right$(Date$,4)+Mid$(Date$,3,3)+"-"+Left$(Date$,2)
'Return
'
'
'if called as a sub - DATESWAP - it never happens (or should I use GOTO DATESWAP?)
'
Sub DATESWAP
edate$=Right$(Date$,4)+Mid$(Date$,3,3)+"-"+Left$(Date$,2)
End Sub
'
> RUN

2000-01-01
>



which I think is what you are after(?). Can you try the simple bit above like I did?

if that works then the problem lies elsewhere

As an aside, be careful here - if this code runs across midnight you could get weird edates - best to copy the date to a local variable in the SUB and use that

hEdited by CaptainBoing 2017-08-19
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 08:37pm 17 Aug 2017
Copy link to clipboard 
Print this post

Good day Brian,
I too have seen this behaviour in MM for DOS, and it turned out to be a structural problem with my program.

As CaptainBoing has shown, the code works, so of itself, that code is not the problem.

I use Jim's MMEDIT - it has some checking tools available, and using MM for DOS (if possible) as it saves write cycles.

It was either DIM statements within the subroutine or badly nested loops and IF statements that a full tidy up using MMEDIT fixed.

Hope this helps

Regards Phil.
 
BrianP
Senior Member

Joined: 30/03/2017
Location: Australia
Posts: 292
Posted: 08:50pm 17 Aug 2017
Copy link to clipboard 
Print this post

@CaptainBoing - thanks for the input. The issue is not that the routine doesn't work as designed, but that when it is called from earlier in the program as a sub, eg.

DATESWAP:event$(logcount)=edate$+" | "+time$

it doesn't work (if I put a PAUSE or END as the first line in the routine it is ever executed so either it not being called or it exits immediately when called).

If structured as a Label (DATESWAP: / RETURN format) & called from the program it works, eg.

gosub DATESWAP:event$(logcount)=edate$+" | "+time$

All the other subs in the program (SUB XXX / END SUB format) work as intended when called. So why doesn't this particular one?

BTW this routine is only used to timestamp an event log entry so a random corruption at midnight wouldn't be an issue, particularly as the log creation is purely on demand & would only take <100msec (I would think). Point taken tho...

I've worked around the issue by calling it as a label. but I want to know WHY?

Thanks for thinking about it

B



 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 09:05pm 17 Aug 2017
Copy link to clipboard 
Print this post

Brian,
This code works as you want:
Dim edate$
Print edate$
Gosub DateSwap
Print edate$
End
If x$="" Then
DateSwap:
edate$=DATE$
Return

but this doesn't...
Dim edate$
Print edate$
DateSwap
Print edate$
End
If x$="" Then
Sub DateSwap
edate$=DATE$
End Sub

The reason one works and one doesn't is because of the extraneous If statement around the code.

This is only one way it can stuff up...without seeing all the code hard to say but if you look around your sub for IF statements or loops that might 'hide' the routine from the interpreter

EDIT !! this didn't exactly do it but I am sure I'm onto the track
Regards,
PhilEdited by flip 2017-08-19
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 09:05pm 17 Aug 2017
Copy link to clipboard 
Print this post

I would put it into a function
  Quote   today$ = DATE$

PRINT today$
PRINT edate$(today$)

FUNCTION edate$(aday$)
edate$=
MID$(aday$,7)+"-"+MID$(aday$,4,2)+"-"+MID$(aday$,1,2)
END FUNCTION


JimEdited by TassyJim 2017-08-19
VK7JH
MMedit   MMBasic Help
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 09:11pm 17 Aug 2017
Copy link to clipboard 
Print this post

Without seeing more of your code I am not sure but try putting a space after DATESWAP and before the colon.
DATESWAP:event$(logcount)=edate$+" | "+time$

Change to:
DATESWAP :event$(logcount)=edate$+" | "+time$


The interpreter might be getting confused with DATESWAP: at the start of the line looking too much like a label.

I still prefer a function.

Jim
VK7JH
MMedit   MMBasic Help
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 09:15pm 17 Aug 2017
Copy link to clipboard 
Print this post

@BrianP

Out of interest, is it still an issue if you split into two lines?

DATESWAP
event$(logcount)=edate$+" | "+time$


WW
For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 12:01am 18 Aug 2017
Copy link to clipboard 
Print this post

I was off track before, Jim is spot on (2 posts up)...if you put the space where he said or change the line
DATESWAP:event$(logcount)=edate$+" | "+time$
to 2 lines:
DATESWAP
event$(logcount)=edate$+" | "+time$
it works fine with Sub
For some reason it is confused by the statement separator (as it's thinking its a label)

I've confirmed problem with MMBasic for DOS:
Print edate$;"."
DateSwap:Print "Hello."
Print edate$;"."
SUB DATESWAP
edate$=right$(date$,4)+mid$(date$,3,3)+"-"+left$(date$,2)
END SUB
> RUN
.
Hello.
.
>

Following works OK (after splitting conjoined statement to 2 lines)
Print edate$;"."
DateSwap
Print "Hello."
Print edate$;"."
SUB DATESWAP
edate$=right$(date$,4)+mid$(date$,3,3)+"-"+left$(date$,2)
END SUB
> RUN
.
Hello.
2017-08-18.
>

So it needs a space before the statement separator, but arguably it might be more readable putting each statement on a separate line.
Regards,
PhilEdited by flip 2017-08-19
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 01:09am 18 Aug 2017
Copy link to clipboard 
Print this post

One thing of minimizing problems is to minimize the use of labels!. :)
Labels have a problem that code can 'fall through' them especially if you use them for subroutines. There is no way for the interpreter to match labels with return statements. Better use SUB/END SUB to prevent hard to find bugs.



Microblocks. Build with logic.
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3167
Posted: 05:26am 18 Aug 2017
Copy link to clipboard 
Print this post

  flip said  DATESWAP:event$(logcount)=edate$+" | "+time$
For some reason it is confused by the statement separator (as it's thinking its a label)

This is the problem, DATESWAP is interpreted to be a label because it meets the rules of a label (ie, an identifier followed by a colon). This also means that the colon is not a separator but part of the label.

A space before the colon is not valid in a label so that colon is treated as a separator.

Geoff
Geoff Graham - http://geoffg.net
 
BrianP
Senior Member

Joined: 30/03/2017
Location: Australia
Posts: 292
Posted: 03:43pm 19 Aug 2017
Copy link to clipboard 
Print this post

YES!

Geoff / Flip / WW / Jim / CaptainBoing's ideas / suggestions are spot on. Although, this issue only seems to arise when the sub is called from within another sub - I haven't the problem with other subs called from the main program (without the space).

This gives rise to another question though - what should we do as a preferred programming practice? Always use a space after a sub call? Or is this a bug, which might be sorted down the track?

@MicroBlocks - yes, I agree about using labels, Should only be used as a program section header or a goto destination (if you must!).

Jim - point taken on board re function - would a function call be noticeably faster than a sub call? Speed is not an issue in this case though.

Thanks everyone for your time & brain power on this - I don't like something happening without knowing WHY. (I did say I was anal retentive).

Brian P.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 04:07pm 19 Aug 2017
Copy link to clipboard 
Print this post

The interpreter would have difficulty differentiating between DATESWAP: the label and DATESWAP: a sub called DATESWAP followed by a : whenever they are at the start of a line.
It is not a bug.

I rarely use multi statement lines. When I do, I am careful about the spaces before and after the :
I usually put in plenty of white space (for readability rather than functionality).
I rarely use labels or goto's, but there are places for both.
I normally choose functions whenever there is a single item to be returned. They tend to be more portable. I doubt if there is much speed difference.

There is no right way, just plenty of wrong ways.

Jim



VK7JH
MMedit   MMBasic Help
 
BrianP
Senior Member

Joined: 30/03/2017
Location: Australia
Posts: 292
Posted: 04:30pm 19 Aug 2017
Copy link to clipboard 
Print this post

I guess I just don't like "waste" space(s)

Is this an issue that should be mentioned in the manual (or have I not seen it)?

B
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 09:59pm 19 Aug 2017
Copy link to clipboard 
Print this post

  BrianP said  

This gives rise to another question though - what should we do as a preferred programming practice? Always use a space after a sub call? Or is this a bug, which might be sorted down the track?

@MicroBlocks - yes, I agree about using labels, Should only be used as a program section header or a goto destination (if you must!).



time to divide the discussion: (INCOMING!!!!)

Some simple rules I have always followed that are based around speed of code + readability:

* nothing starts in column one except labels and comments (never use trim leading space).
* Indent your code with a bare minimum of white space required to nest nicely and uniformly (big topic - develop a style that you are happy with).
* avoid using reserved words in variable/procedure names where possible.
* avoid duplicate maths where you can i.e. don't do a formula 3 times, do it once and assign the value to a variable - perform time trials to determine the best method.
* Don't make a function/sub for something simple you are going to do lots of times from a single place.
* you can have it big and fast or small and slow - perform trials based on speed/trade-off to determine the best method for an algorithm i.e. do I calculate a SIN with a polynomial of from a look-up table?

For MMBasic I have augmented these with
* Use short Procedure/variable names where possible - Code runs faster - self-documenting names are great - for compiled languages but wading in treacle for interpreted.
* never put a space between a reserved word and its opening parenthesis - don't write ATN (0.5) - it's ATN(0.5).

loads more that other have - we should develop a manual but it would need trial by combat to make it to the final print Edited by CaptainBoing 2017-08-21
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024