Oxygen Basic
Programming => Bugs & Feature Requests => Topic started by: Mike Lobanovsky 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:
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 :)
-
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 :)
-
...it will try to convert the string content into an integer. (internal val)
This ain't kosher. :(
-
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
-
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? :)
@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
-
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 ::)
-
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
.
-
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
-
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?
-
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
-
[EDIT] Oh, thanks for the update, Charles!
Now you have caught a real bug
Nope. Aurel spotted it, but his was a voice in the wilderness. :D
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?
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:
.
-
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
-
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.
-
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.
/*
% 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