Author Topic: Bug in Case or If?  (Read 5043 times)

0 Members and 1 Guest are viewing this topic.

Mike Lobanovsky

  • Guest
Bug in Case or If?
« on: May 26, 2014, 01:57:50 AM »
Hi Charles,

It seems the following code fails to evaluate elseif is_alpha(cur_ch) then in case else with the latest Oxygen.dll:

Code: [Select]
const as long sym_unknown = 0, sym_eoi = 1, sym_string_const = 2, sym_lparen = 3, sym_rparen = 4
const as long sym_multiply = 5, sym_plus = 6, sym_comma = 7, sym_minus = 8, sym_divide = 9
const as long sym_integer_const = 10, sym_ident = 11, sym_print = 12, sym_while = 13
const as long sym_do = 14, sym_end = 15, sym_halt = 16, sym_if = 17, sym_then = 18
const as long sym_else = 19, sym_integer_var = 20, sym_equal = 21, sym_mod = 22, sym_or = 23
const as long sym_and = 24, sym_neq = 25, sym_lss = 26, sym_leq = 27, sym_gtr = 28
const as long sym_geq = 29, sym_neg = 30, sym_not = 31, sym_whtspc = 32

function is_alpha(ch as string) as long
dim as long asc_uc_ch = asc(ucase(ch))
return ch <> "" and asc_uc_ch >= asc("A") and asc_uc_ch <= asc("Z")
end function

function is_numeric(ch as string) as long
dim as long asc_ch = asc(ch)
return asc_ch >= asc("0") and asc_ch <= asc("9")
end function

sub next_sym() ' determine the next symbol
    dim as string DQ = chr(34)
    dim as long sym

cur_ch = "A" // ALPHA!!!
select case cur_ch
case ""
sym = sym_eoi
case "+"
sym = sym_plus
case "-"
sym = sym_minus
case "*"
sym = sym_multiply
case "/"
sym = sym_divide
case ","
sym = sym_comma
case "("
sym = sym_lparen
case ")"
sym = sym_rparen
case "="
sym = sym_equal
case "<"
sym = sym_lss
if cur_ch = ">" then
sym = sym_neq
elseif cur_ch = "=" then
sym = sym_leq
end if
case ">"
sym = sym_gtr
if cur_ch = "=" then
sym = sym_geq
end if
case DQ ' a double quote
            print "DQ"
case else
if is_numeric(cur_ch) then
                print "numeric"
elseif is_alpha(cur_ch) then
                print "alpha"
else
                print "error"
end if
end select
    print "char is '" cur_ch "'"
end sub

next_sym


Mike "Bug Magnet" Lobanovsky :)

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #1 on: May 26, 2014, 03:49:34 AM »
this should fix it, Mike:

select case asc cur_ch

without asc, it will try to convert the string content into an integer. (internal val)

For your powerful magnetism, I bestow upon you the Order of Neodymium :)
« Last Edit: May 26, 2014, 03:57:45 AM by Charles Pegge »

Mike Lobanovsky

  • Guest
Re: Bug in Case or If?
« Reply #2 on: May 26, 2014, 04:10:01 AM »
...it will try to convert the string content into an integer. (internal val)

This ain't kosher.  :(

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #3 on: May 26, 2014, 04:23:23 AM »
Oxygen likes to convert its types to match the destination type. Most Basics do automatic type conversion in print statements, but Oxygen will do it wherever it is needed.

thus:

double d="4.125" 'd is 4.125

conversely:

string s=4.125  's is "4.125"




For doing char work on a string, I recommend using a byte overlay and working in bytes:

byte b at (strptr s)

b can then be used as an array b[n] or as an implicit pointer b, where the b address can be incremented  @b++ or calculated: @b+=1

Mike Lobanovsky

  • Guest
Re: Bug in Case or If?
« Reply #4 on: May 26, 2014, 04:45:11 AM »
Oxygen likes to convert its types to match the destination type.
Yup, I know the Variant data type idea is attractive but there are very few BASIC dialects that are fully consistent with it - I can name VB and FBSL. Can you name more? :)

Quote
@b++
This isn't permitted in C AFAIK - it's ambiguous.

Thanks for the overlay hint BTW!

P.S. Charles, I'm facing a difficult challenge which is to complete the FBSL BASIC manual. IMHO your task of writing the OxygenBasic manual is next to impossible; you'll have to take a 12 months long vacation to make it. :D
« Last Edit: May 26, 2014, 04:55:41 AM by Mike Lobanovsky »

Aurel

  • Guest
Re: Bug in Case or If?
« Reply #5 on: May 26, 2014, 04:52:43 AM »
May iask since when const is a keyword for constant ?
I always use % ... ???

hmm it looks to me that this conversion looks harder than i think ::)

Mike Lobanovsky

  • Guest
Re: Bug in Case or If?
« Reply #6 on: May 26, 2014, 05:01:07 AM »
hmm it looks to me that this conversion looks harder than i think ::)

Yeah, Oxygen as such is a good candidate for an own page on the DeviantArt website. :D

.
« Last Edit: May 26, 2014, 05:57:20 AM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #7 on: May 26, 2014, 05:03:23 AM »
Well, the Autoconversion protocol is fairly consistent. It applies to variable assignments, and function parameters, and also takes care of wide-string conversion.

Only primitives fall with the scope of the converter.

In the case of overloaded functions, the compiler first looks for a perfect match, before it tries conversion. It will do 3 passes before giving up. float/integer conversions have priority over number/string conversions.

Types and their conversion are fixed at compile-time, so variants are not required.

PS: I had a spot of bother with string constants this morning. Normally  use equates for strings. Fixed now
« Last Edit: May 26, 2014, 05:12:44 AM by Charles Pegge »

Mike Lobanovsky

  • Guest
Re: Bug in Case or If?
« Reply #8 on: May 26, 2014, 06:00:26 AM »
Well, the Autoconversion protocol is fairly consistent. It applies to variable assignments, and function parameters ... Only primitives fall with the scope of the converter.
This is what FBSL does too but only when initialization takes place at declare time. Thereafter, a simple data type Variant never maintains its declared type and matches that of the value that's being assigned to it - in fact doing the opposite to "ordinary" strong data type languages. That's also like Lua works BTW.

OTOH compound data types and arrays always follow their declarations strictly, and you may use this feature to emulate strong type variables in FBSL too. E.g.

Type StrongLong
    Default sl As Long
End Type

Dim L As StrongLong

L = 123.456
Print L


will print

123



Can you comment on array[CONSTANT] not working as expected, please?

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #9 on: May 26, 2014, 07:04:24 AM »
Now you have caught a real bug :)

I think you are the first to use constants intensively. I  see you put many onto a single line, which cannot be done with equates.

another possible single liner is enum: You may remove the curly braces if you so wish.

enum things {aa=1,bb=4,cc=42,...}

update with const array fixed:
http://www.oxygenbasic.org/o2zips/Oxygen.zip
« Last Edit: May 26, 2014, 07:16:30 AM by Charles Pegge »

Mike Lobanovsky

  • Guest
Re: Bug in Case or If?
« Reply #10 on: May 26, 2014, 08:59:10 AM »
[EDIT] Oh, thanks for the update, Charles!

Quote
Now you have caught a real bug
Nope. Aurel spotted it, but his was a voice in the wilderness. :D

Quote
I think you are the first to use constants intensively.
Nope again. That was Ed Davis. :D I would've used #define's as const's which in FBSL are in fact protected "variables" were deprecated long time ago but still stay for cases like this.

I just want to keep as close to traditional BASIC as possible. And I really can't do it elegantly with Oxygen's case's that are supposed to refer to one-character literals. I seem to be pushed to numeric values all the time or I crash. :-\ Can it be general memory corruption due to my abusage of const?

Quote
I  see you put many onto a single line, which cannot be done with equates.
But Charles, have a look at your own manual! How else was I supposed to understand the following:


.
« Last Edit: May 26, 2014, 09:20:37 AM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #11 on: May 26, 2014, 10:54:21 AM »
I meant the use of constants in Oxygen. They have not been properly exercised. It's really nice to have concise error reporting anyway. Thanks Mike :)

This works with the update:

const as sys aa=2,bb=4,cc=6,dd=8,ee=10

a=cc

select a
case aa : print "aa"
case bb : print "bb"
case cc : print "cc"
case dd : print "dd"
case ee : print "ee"
end select


Constants in OxygenBasic, unlike equates, have a specific type attributed to them, using the same entity-record as a primitive variable. When a type is not specified, the constants are assumed to be sys integers. The same with variables.

const aa=2,bb=4,cc=6,dd=8 ...

dim aa=2,bb=4,cc=6,dd=8 ...


Enumerations might be useful when you want to create a series of tokens, without being concerned with assigned values.

The default starting value is 0, as with C

Enumerations can be designated a type, but it is not enforced. They are handled a equates.

enum thing aa,bb,cc,dd,ee,ff

function f(it as thing) as thing
return it
end function

print f cc
  '2


« Last Edit: May 26, 2014, 11:46:39 AM by Charles Pegge »

Aurel

  • Guest
Re: Bug in Case or If?
« Reply #12 on: May 26, 2014, 01:23:45 PM »
Quote
And I really can't do it elegantly with Oxygen's case's that are supposed to refer to one-character literals.

Yes ...and Charles this limitation really sucks, i don't know any basic-like language with
such a ugly limitation.

Charles Pegge

  • Guest
Re: Bug in Case or If?
« Reply #13 on: May 26, 2014, 01:44:42 PM »
The const problems have now been fixed. I think the bug crept in, when I created new error traps to prevent expressions being used in case blocks.

So cases now  work nicely with both constants and equates.

Code: [Select]

/*
% aa 1
% bb 2
% cc 3
% dd 4
*/

const aa=1,bb=2,cc=3,dd=4

a=cc

select a
case aa : print "aa"
case bb : print "bb"
case cc : print "cc"
case dd : print "dd"
end select


select a
case aa to bb : print "aa to bb"
case cc to dd : print "cc to dd"
end select