Oxygen Basic
Programming => Bugs & Feature Requests => Topic started by: Petr Schreiber on December 18, 2010, 08:15:03 AM
-
Hi Charles,
I had finally free afternoon, so I thought I will dive to Oxygen finally! I must say the impressions are very positive, but I have few problems and suggestions.
Exciting stuff
- OOP syntax in Oxygen is the best seen in BASIC language
- C-like variable declaration is very useful
- It compiles fast!
Problems of compiler:
- The error messages Oxygen gives during compilation are very hard to understand, I would say even harder than output of C compiler
- Syntax checking is too tollerant, I can write nonsense like "dim myVar as dword on steroids" and it still compiles without complaining
- The code below crashes on assignment to dword ptr variables, maybe my fault, but it compiled
'
' Stack Allocator class [WIP]
' Petr Schreiber, 2010
'
' Based on code from Game Engine Architecture by Jason Gregory
' page 208
'
' Platform specific declares
DECLARE FUNCTION GetProcessHeap LIB "KERNEL32.DLL" ALIAS "GetProcessHeap" () AS DWORD
DECLARE FUNCTION HeapAlloc LIB "KERNEL32.DLL" ALIAS "HeapAlloc" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL dwBytes AS DWORD) AS DWORD
DECLARE FUNCTION HeapFree LIB "KERNEL32.DLL" ALIAS "HeapFree" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL lpMem AS DWORD) AS DWORD
HEAP_NO_SERIALIZE = &H00000001
HEAP_GENERATE_EXCEPTIONS = &H00000004
HEAP_ZERO_MEMORY = &H00000008
HEAP_ALLOC_FLAGS = HEAP_ZERO_MEMORY or HEAP_GENERATE_EXCEPTIONS
HEAP_FREE_FLAGS = 0
' Stack allocator marker: Represents the top of the
' stack. You can only roll back to a marker, not to
' arbitrary locations within the stack
typedef DWORD cStackAllocatorMarker
class cStackAllocator
private DWORD startOfBlock
private DWORD topOfStack
private cStackAllocatorMarker marker
' Constructs a stack allocator with the given total size
public method constructor(sys stackSizeBytes)
startOfBlock = HeapAlloc (GetProcessHeap(), HEAP_ALLOC_FLAGS, stackSizeBytes)
topOfStack = startOfBlock + stackSizeBytes
marker = startOfBlock
end method
' Allocates new block of the given size from stack top
public method alloc(dword sizeBytes) as dword
if marker+sizeBytes > topOfStack then
print "Stack overflow, please initialize with bigger value next time"
exit method
end if
method = marker
marker += sizeBytes
end method
' Returns a marker to the current stack top
public method getMarker() as cStackAllocatorMarker
method = marker
end method
' Rolls the stack back to a previous marker
public method freeToMarker(cStackAllocatorMarker m)
marker = m
end method
' Clears the entire stack (rolls the stack back to zero)
public method clear()
HeapFree (GetProcessHeap(), HEAP_FREE_FLAGS, startOfBlock)
end method
public method destructor()
clear()
end method
end class
' ----------------------------------------------------------------------------------
' Main program body
' ----------------------------------------------------------------------------------
' Create allocator with space for 12 bytes
cStackAllocator allocator
allocator.constructor(12)
' 3 DWORDs will fit to 12b perfectly
dword ptr a
dword ptr b
dword ptr c
' This makes it GPF, sadly, I just wanted to initialize the pointers
a = allocator.alloc(4)
b = allocator.alloc(4)
c = allocator.alloc(4)
' I want to put values there
&a = 1
&b = 2
&c = 3
' And print them back
print @a
print @b
print @c
allocator.destructor()
Problems of SciTe
- I would like to have language keywords, like "class", highlighted, it prevents typos
- It let me save file as TXT by default, I was confused where my code got lost, maybe forced o2bas extension would be nice
- I would like to have some kind of navigation between routines, like in ThinAIR
- I would like to see dedicated IDE for Oxygen, I know it means too much time and it is better to focus on the language at the moment, but for "serious use" it would be great thing to have in future
Problems of Help
- It looks so empty! What a surprise that it contains lot of information after using context sensitive help
- I would suggest to group commands and list them all somehow in the help file (String handling, File IO, ...)
Let me know Charles if you want me to split this post to multiple feature suggestions.
Thanks for all your work on Oxygen, it was very easy to write the StackAllocator class, very pleasant smooth coding experience.
Petr
-
Hi Petr,
Here is the solution for your program:
The trick is to assign adresses to pointer variables like this:
& pv=GetSomeAddress
Then treat the pointered variable like any other.
'
' Stack Allocator class [WIP]
' Petr Schreiber, 2010
'
' Based on code from Game Engine Architecture by Jason Gregory
' page 208
'
' Platform specific declares
DECLARE FUNCTION GetProcessHeap LIB "KERNEL32.DLL" ALIAS "GetProcessHeap" () AS DWORD
DECLARE FUNCTION HeapAlloc LIB "KERNEL32.DLL" ALIAS "HeapAlloc" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL dwBytes AS DWORD) AS DWORD
DECLARE FUNCTION HeapFree LIB "KERNEL32.DLL" ALIAS "HeapFree" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL lpMem AS DWORD) AS DWORD
HEAP_NO_SERIALIZE = &H00000001
HEAP_GENERATE_EXCEPTIONS = &H00000004
HEAP_ZERO_MEMORY = &H00000008
HEAP_ALLOC_FLAGS = HEAP_ZERO_MEMORY or HEAP_GENERATE_EXCEPTIONS
HEAP_FREE_FLAGS = 0
' Stack allocator marker: Represents the top of the
' stack. You can only roll back to a marker, not to
' arbitrary locations within the stack
typedef DWORD cStackAllocatorMarker
'====================
class cStackAllocator
'====================
private DWORD startOfBlock
private DWORD topOfStack
private cStackAllocatorMarker Marker
' Constructs a stack allocator with the given total size
'--------------------------------------------
public method constructor(sys stackSizeBytes)
'============================================
startOfBlock = HeapAlloc (GetProcessHeap(), HEAP_ALLOC_FLAGS, stackSizeBytes)
topOfStack = startOfBlock + stackSizeBytes
marker = startOfBlock
end method
' Allocates new block of the given size from stack top
'--------------------------------------------
public method alloc(dword sizeBytes) as dword
'============================================
if marker+sizeBytes > topOfStack then
print "Stack overflow, please initialize with bigger value next time"
exit method
end if
method = marker
marker += sizeBytes
end method
' Returns a marker to the current stack top
'-------------------------------------------------
public method getMarker() as cStackAllocatorMarker
'=================================================
method = marker
end method
' Rolls the stack back to a previous marker
'--------------------------------------------------
public method freeToMarker(cStackAllocatorMarker m)
'==================================================
marker = m
end method
' Clears the entire stack (rolls the stack back to zero)
'--------------------
public method clear()
'====================
HeapFree (GetProcessHeap(), HEAP_FREE_FLAGS, startOfBlock)
end method
public method destructor()
clear()
end method
end class
' ----------------------------------------------------------------------------------
' Main program body
' ----------------------------------------------------------------------------------
' Create allocator with space for 12 bytes
cStackAllocator allocator
allocator.constructor(12)
' 3 DWORDs will fit to 12b perfectly
dword ptr a
dword ptr b
dword ptr c
' This makes it GPF, sadly, I just wanted to initialize the pointers
'solution: oxygen uses invisible "byref" pointering. variables are assigned addresses like this: & a=...
'---------
& a = allocator.alloc(4)
& b = allocator.alloc(4)
& c = allocator.alloc(4)
' I want to put values there
a = 1
b = 2
c = 3
' And print them back
print a
print b
print c
allocator.destructor()
This illustrates where Basic syntax comes into conflict with C at a fundamental level, and I came down on the side of Basic :)
More later!
Charles
-
On SciTE:
This is very much a temporary solution. But the two files which control the customisation of SciTE are:
SciTEGlobal.properties
Oxygen.properties
They are both plain text files and I would welcome any improvements of these.
In the longer term I will base Oxide development on OpenGL including the Edit control I've been working on. (PortViewer2 press F7. see notes). Ok its ambitious but a good investment in technology - it will yield some very useful components as well as an IDE.
Charles
-
On the Manual:
This is rather Spartan at present, but I've done a bit more streamlining and fully implemented the tools\ManualCreate program. This takes the information contained in the keywords source file src\o2keyw.bas and a few other files. This links in with some of the programs in the examples folder.
The output of ManualCreate is a set of cross-linked HTML files ready for CHM compiling.
So all we need now is more content. :)
o2keyw.bas is essentially a database with some of its lines containing basic. The layout of the records is strict with regard to fieldnames and content spacing but it is quite easy to follow.
Charles
PS:
In addition to the manual, the same system could be used to generate content for the Wiki.
-
Hi Charles,
thanks a lot for the explanations, now I see where I did my mistake :)
Petr
-
I hope the pointer syntax proves to be satisfactory Petr. It works in exactly the same way as any Basic function using parameters passed ByRef.
On syntax tolerance:
Syntax checking is too tollerant, I can write nonsense like "dim myVar as dword on steroids" and it still compiles without complaining
If you think that is tolerant then you must try this! :)
{
'override reserved words
def with
def to
dim as sys
Sun arise, she bring in the morning,
Sun arise, bring in the morning, fluttering her skirts all around,
Sun arise, she come with the dawning,
Sun arise, come with the dawning, spreading all the light all around,
Sun arise, on the kangaroo paw,
Sun arise, on the kangaroo paw, glistening the dew all around,
Sun arise, filling all the hollows,
Sun arise, filling all the hollows, lighting up the hills all around,
Sun arise, come with the dawning,
Sun arise, she come every day,
Sun arise, bring in the morning,
Sun arise, every, every, every, every, day,
She drive away the darkness, every day,
Drive away the darkness,
Bringing back the warmth to the ground,
Sun arise, oh, oh,
Sun arise, oh, oh,
Spreading all the light all around,
Sun arise, bring in the morning,
Sun arise, bring in the morning, spreading all the light all around
}
print "okay!"
'Rolf Harris classic 1962
'http://www.youtube.com/watch?v=lwtnBm8glPE
All the variables are legitimate and dimmed as sys. Most of them (except for some reserved words) are usable.
Unfortunately there is no well defined principle for trapping errors and it has to be taken on a case by case basis, but my main priority is to catch syntax errors before they fall into the Assembler and trigger cryptic messages.
Charles
-
Sun arise, oh, oh,
Spreading all the light all around.
cool Charles!
-
;D That is great Charles