Oxygen Basic
Programming => Problems & Solutions => Topic started by: Mike Lobanovsky on September 22, 2014, 02:54:47 PM
-
Charles,
I need to overload Oxygen's console PRINT with printf() from the msvcrt.dll runtime. Its super-precision style is certainly not suitable for OxyLISP console output due to too many insignificant trailing digits that are blurring simple input and maths.
The problem is printf() is a fully variadic function. Are there any handy and elegant means or ways to trick Oxygen into calling a variadic function in an external library without argument type and quantity checks -- besides assembly calls to its GetProcAddress pointer, of course?
.
-
Mike,
You can limit the number decimal places by using a second param with str: str(v, dp). It will automatically round up or down. It might be easier than going for printf().
Oxygen's print() takes a char*, and float_to_ascii conversions are made before calling print.
I'll try to conjure some overloading examples ....
-
You must first override the core print with a function that has the same number of params. Then you are free to create a series of overloaded print functions of varying type and param count.
'include "$/inc/console.inc"
function print(string s)
========================
#ifdef AllocConsole
output s + cr
#else
mbox s
#endif
end function
function print(sys v)
=====================
print "integer " v
end function
function print(double v)
========================
print "floating-point: " v
end function
function print(string fmt, double v)
====================================
'test code
print "format: " fmt " value: " v
end function
'TEST OVERLOADS
===============
print "hello planet " 3
print 123
print 123.25
print "%f", 1.25
#ifdef AllocConsole
waitkey
#endif
-
Charles,
Then you are free to create a series of overloaded print functions of varying type and param count.
Impractical. :(
You can limit the number decimal places by using a second param with str: str(v, dp). It will automatically round up or down. It might be easier than going for printf().
Wow! It works! :D
And of course it is much more practical than calling printf() disguised as overloaded PRINT. Printing numbers in OxyLISP is an isolated "routine" so str(v, dp) does the job perfectly. Thanks for the tip!
P.S. Can an Oxygen macro be variadic?
And also, is this
type COORD
short X,Y
=
long c
end type
an oxy-union? If yes then: i) how many equalities can there be? ii) can composite UDT's have several unions in them? iii) if yes then how would they be separated from the other UDT members in the definition or should they be defined separately?
-
Hi Mike,
The Oxygen macro currently requires definite parameters, but they can, of course, be of any type.
Types can be discerned within macros, and used to create new variables etc.
typeof c a,b
if typeof c="coord" then ...
Types can have any number of Oxy-unions. (messy C-style unions are also supported.)
The '=' sign resets the offset. That is all it does, so you are free to innovate :)
The overall size of the type is the maxumum offset rounded up to the widest primitive used within the type (C rules)
type COORD
short x,y
=
long c
=
byte x8,y8,z8,w8
end type
-
The Oxygen macro currently requires definite parameters, but they can, of course, be of any type.
...............
if typeof c="coord" then ...
Oh, so an Oxy-macro is a compile time feature.
The '=' sign resets the offset. That is all it does :)
Hehe, so the "equality" is just a delimiter. But it has certain logic (a = b = c = ...) and hence elegance too. :)
OK then, my last question in this topic will be: is there anything at all in Oxygen that is run time variadic besides an asm call?
-
Variadics:
function f(n,...)
function f(...) 'extremist!
The params are read as a predefined sys array param, which you can overlay, or pointer or cast to get the required type. But beware 64bit issues!
The calling convention is automatically cdecl.
param[1], param[2] ...
optional params are also available
function f( sys n, optional sys a,b,c)
-
Fantastic!!!
Are param[1], param[2], ... affected by indexbase?
-
Yes, you can set it locally inside the function.
Indexbase 0 is good:
function f(n,...)
indexbase 0
' n param[0]
for i=1 to n
print cast(float) param[ i ]
next
end function
-
Thanks Charles! :)
The very-very last one: what's inside the mysterios zip within the zip that's downloadable from the wizard above?
-
Sounds very strange. I have no uploaded again. So the wizard has no excuse.
-
Charles,
There is some mysterious ZIP called Oxygen.zip inside the distro archive downloadable from the wizard at the top of this page. It contains Oxygen.dll dated September 19. Probably this is an older version that shouldn't come in the archive that already contains a newer version of the same library. :)
.
-
Now I understand, Mike. It will be vanished.