Oxygen Basic

Programming => Bugs & Feature Requests => Topic started by: Petr Schreiber on December 18, 2010, 08:15:03 AM

Title: Opinions about Oxygen after spending afternoon with it finally :)
Post 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

Problems of compiler:
Code: [Select]
'
' 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

Problems of Help

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
Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Charles Pegge on December 18, 2010, 02:56:41 PM
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.

Code: [Select]
'
' 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
Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Charles Pegge on December 18, 2010, 03:27:49 PM

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

Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Charles Pegge on December 19, 2010, 05:27:04 AM
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.


Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Petr Schreiber on December 19, 2010, 06:44:29 AM
Hi Charles,

thanks a lot for the explanations, now I see where I did my mistake :)


Petr
Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Charles Pegge on December 22, 2010, 03:35:23 AM
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:

Quote
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! :)

Code: [Select]
{

 '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
Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Peter on December 22, 2010, 05:44:28 AM

 Sun arise, oh, oh,
 Spreading all the light all around.

 cool Charles!
Title: Re: Opinions about Oxygen after spending afternoon with it finally :)
Post by: Petr Schreiber on December 23, 2010, 10:56:48 AM
;D That is great Charles