April 30, 2024, 08:17:47 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


IWBasic v2.0 progress: compiler

Started by sapero, May 16, 2010, 02:48:12 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

billhsln

I was thinking more in the line of w1.hWnd and other things that are already predefined.

We do:

WINDOW w1

under that w1.hWnd is valid, but w1.hwnd is not.  That is the list I was wondering about, since we have no control over those field names.

Thanks,
Bill
When all else fails, get a bigger hammer.

sapero

July 01, 2010, 01:11:58 PM #51 Last Edit: July 01, 2010, 01:14:36 PM by sapero
The compiler will search in all possible locations (using case insensitive method) to give you a hint, with the proper case: "did you meant TheSymbol ?"

sub b()
point p
endsub

Error message: File: x.eba (19) unknown type point, did you meant POINT ?

Ficko

Quote from: sapero on July 01, 2010, 01:11:58 PM
to give you a hint with the proper case: "did you mean hWnd ?"

And propably you have some enchanced Intellisense for the enchanced compiler in your mind as well ?  ;D ;)

sapero

July 03, 2010, 04:43:34 AM #53 Last Edit: July 03, 2010, 11:53:33 AM by sapero
The compiler could generate intellisense database for use in the IDE, why not?

New additions:
* variable = new type
* variable = new type[count]
* typedef newtype structureName
* typedef newtype className
* typedef newtype interfaceName
* interface name, base_interface interface IMyInterface, IUnknown ... endinterface
* LEN(className)

If A in "typedef A B" is already defined as something other than B, the compiler will show an error:
typedef MYPOINT POINT
typedef MYPOINT POINTL ' Error: MYPOINT already defined as struct POINT



Added NOVTABLE option for classes:
$option "novtable on" ' yes, enable, on, 1
class CClass
int m_value
endclass
$option "novtable off" ' no, disable, off, 0

I am planning to add support for classes with the base on a structure, so novtable will be a great feature:
class CRect, WINRECT
"declare virtual" will be automatically disabled while novtable option is active, because a class without virtual functions table cannot have virtual methods.

LarryMc

OK, time for me to be the 'village idiot' again.

What does the NOVTABLE option do for me as a regular IWBasic user?
How does it benefit me and/or why would I want to use it?

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

July 03, 2010, 01:14:55 PM #55 Last Edit: July 03, 2010, 01:32:00 PM by sapero
It is used when you want to create a class compatible with a structure, where size of the class must be eual to size of structure.

It does not shift all class variables by 4 bytes forward.
Currently if you build a class compatible with WINRECT, and will access Left member, you need to cast the 'this' pointer to WINRECT

class CWinRect ' compatible with WINRECT
' pointer _VTABLE_  ' hidden class member at offset +0
' int left -> not possible, we are at offset +4 where is WINRECT.top
int top
int right
int bottom
declare GetLeft(),int
declare GetTop(),int
endclass

sub CWinRect::GetLeft(),int
return*<WINRECT>this.left ' same as *<int>this
endsub

sub CWinRect::GetTop(),int
return top ' or return*<WINRECT>this.top
endsub


When you turn off vftable, the first variable in our class will be at offset +0, as it is in regular structure:
$option "novtable on"
class CWinRect
int left ' -> possible, we are at offset +0
int top
int right
int bottom
endclass

Or without $option:
class CWinRect, WINRECT
endclass


In Aurora you could define a class with the same name as previously defined structure, but still to access structure members in a method of your class, you needed to cast 'this' pointer.
class RECT
{
declare width(),int {return *(RECT)this.right - *(RECT)this.left;}
}


So, to make it easier and remove the casting, use novtable option, and access all members directly.


Example program:
class CWinRect
int left
int top
int right
int bottom
endclass

CWinRect c

c.left  = 1
c.top   = 2
c.right  = 3
c.bottom = 4

pointer p = &c
print "values:", *<int>p[0], *<int>p[1], *<int>p[2], *<int>p[3]
print "offsets: ", &c.left-&c, &c.top-&c, &c.right-&c, &c.bottom-&c

Output:
values:4206666 1 2 3
offsets: 4 8 12 16


With vtable disabled:
values: 1 2 3 4
offsets: 0 4 8 12

LarryMc

So, would the default would be "novtable off" ?

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

July 03, 2010, 06:12:23 PM #57 Last Edit: July 03, 2010, 06:16:37 PM by sapero
Yes, vtable by default will be enabled (novtable off).
The new compiler must be compatible with previous versions, so any changes will be enabled only at user request.

Additional tools like NEW without braces, or derieved interfaces, which do not interfere with the official syntax, are available at any time.

---
Improved error tracking:
* duplicate declaration is now detected better than proviously, and the (clickable) location of original definition will be shown
File: new.eba (8) Error: duplicate definition of variable or label: bottom
File: new.eba (7) See previous declaration

* whenever possible, the word (variable/function/class/method/typedef) name will be displayed, if it causes an error. Example: duplicate definition/class/interface.

With the new improvement, I have found two duplicates in rpc includes: a symbol was defined as pointer in file A, and as structure in file B.

sapero

July 04, 2010, 10:27:11 AM #58 Last Edit: July 05, 2010, 01:11:45 PM by sapero
Added structured exceptions handling:
$include "windowssdk.inc" ' need EXCEPTION_POINTERS and EXCEPTION_RECORD
int a=0
try
print "dividing by zero"
print 1/a
print "divide ok"
endtry

catch
print "exception code: 0x", hex$(GetExceptionCode())

pointer pep = GetExceptionInformation()
settype pep,EXCEPTION_POINTERS

print "exception address: 0x", hex$(*pep.*<EXCEPTION_RECORD>ExceptionRecord.ExceptionAddress)
endcatch

Output:dividing by zero
exception code : 0xC0000094
exception address: 0x40141E
finished


LEAVE will immediatelly quit from try-endtry block.
THROW requires an argument (a pointer, number, string) - generates in-place exception with code=0, passing the pointer to use in the next catch block:
try
throw "unable to divide by zero"
endtry

catch
pointer pep = GetExceptionInformation()
settype pep,EXCEPTION_POINTERS
settype *pep.ExceptionRecord, EXCEPTION_RECORD
' optional validation
' *pep.*ExceptionRecord.ExceptionCode must be 0
' *pep.*ExceptionRecord.NumberParameters must be >0
if (!*pep.*ExceptionRecord.ExceptionCode and *pep.*ExceptionRecord.NumberParameters)
' get the first integer from ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
int pText = *pep.*ExceptionRecord.ExceptionInformation[0]
'print hex$(&"unable to divide by zero")
'print hex$(pText)
print *<string>pText
endif
endcatch


Some internals for advanced users:
Pointer to EXCEPTION_POINTERS structure is stored at ThreadEnvironmentBlock->UserReserved[0]. It will be allocated once, when handling the first exception.
The format of data stored in TEB->UserReserved[0] is:
type SEH_TLS ' custom structure
EXCEPTION_POINTERS ep ' to make GetExceptionInformation compatible with MSDN
EXCEPTION_RECORD er
CONTEXT ctx
BOOL HadException ' if TRUE, next CATCH will execute
endtype

GetExceptionInformation will return a direct pointer to this structure, initialized to the snapshot of thread state, when an exception occured.
Because EXCEPTION_POINTERS is the first member, GetExceptionInformation can be used to gain access to EXCEPTION_POINTERS and SEH_TLS.
When entering TRY block, the HadException member will be set to FALSE, if the SEH_TLS structure has been allocated.
When entering CATCH block, there will be a check if HadException is TRUE. If SEH_TLS is not allocated (no exception) or when HadException is FALSE, execution will continue at ENDCATCH.

GetExceptionCode and GetExceptionInformation are intrinsic, so there is no function call, just inline code. GetExceptionInformation can return NULL, if there was no exception previously, but inside catch-endcatch it will always return a valid pointer.

Nesting level for TRY block is unlimited, each level takes 44 bytes from stack memory to save important CPU registers, and the code address of ENDTRY, where a jump is made on exception.

TODO:
* handle goto inside try-endtry.
sub function1()
try
try
goto     ' todo
break    ' handled
breakfor ' handled
return   ' handled
end      ' handled
endtry
endtry
endsub

sapero

July 05, 2010, 04:17:17 PM #59 Last Edit: July 05, 2010, 05:37:03 PM by sapero
Added construction and destruction for classes defined in a structure (any level)
class myclass
declare myclass()
declare _myclass()
endclass

type child
myclass c
endtype

type mytype
myclass a
child   b
endtype

mytype t
end

sub myclass::myclass()
print "constructor"
endsub

sub myclass::_myclass()
print "destructor"
endsub


Output:
constructor
constructor
destructor
destructor


EDIT: the same applied to new and delete.

sapero

There are the latest updates:
* New "strict"option - the compilerwill be showing all possible typos. For example, if you use undefined variable type in function declaration, you will be notified about.
declare mysub(MYTYPE p) ' use of undefined type
typedef MYTYPE int ' declaration

* ebstd.incc header will be parsed first, then all other incc files, using the default sorting algo from FindNextFile.
* Added additional location for include-directory list: INCLUDE environment variable. The search order for searching files accessed by $INCLUDE is:
  1. The directory of currently parsed file
  2. The Include directory
  3. User directory list added in the /i command lines witch or "IncludePath" option
  4. The Bin directory
  5. The list from INCLUDE environment variable. The format is same as in PATH variable: "c:\dir1;d:\dir2;e:\dir2\dir 5; ... z:\last dir".

IDE updates:
* Clicking a keyword with CONTROL key pressed with select the whole word.
* Added fold points to do-until, for-next, while-endwhile, if-else-endif, select-endselect.

There is an additional tool for configuring per user global (default) settings. You can choose which options should be ON/OFF: case sensitive compilation, default state for autodefine, state for strict option, ..., additional preprocessor definitions and additional include directories.
This is a small property sheet program.

Brian

Looking good, Sapero - I will certainly be ordering the new version
when it surfaces

Can't be left behind...

Brian

Barney

Hopefully I will be getting my new credit card just in time to purchase v2.0 :) It's looking very nice. I also hope that one day (sooner rather than later) we'll also have a 64-bit version, too.

Barney

LarryMc

Quote from: sapero on July 03, 2010, 06:12:23 PM
Yes, vtable by default will be enabled (novtable off).
The new compiler must be compatible with previous versions, so any changes will be enabled only at user request.

Additional tools like NEW without braces, or derieved interfaces, which do not interfere with the official syntax, are available at any time.

---
Improved error tracking:
* duplicate declaration is now detected better than proviously, and the (clickable) location of original definition will be shown
File: new.eba (8) Error: duplicate definition of variable or label: bottom
File: new.eba (7) See previous declaration

* whenever possible, the word (variable/function/class/method/typedef) name will be displayed, if it causes an error. Example: duplicate definition/class/interface.

With the new improvement, I have found two duplicates in rpc includes: a symbol was defined as pointer in file A, and as structure in file B.
When you get this error
File: new.eba (8) Error: duplicate definition of variable or label: bottom
File: new.eba (7) See previous declaration

the See Previous line # is one greater then the actual line.

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

November 29, 2010, 05:23:56 PM #64 Last Edit: November 29, 2010, 05:39:06 PM by sapero
Thanks for this info!
Fixed.

I have added two special return types: FPU and __m128. The names are temporary (I am open for suggesions).

The FPU type marks a function as returning a float/double in the ST0 FPU register (for Bass users).
type FPU
endtype

declare GetFpu(),FPU

print GetFpu()
end


$asm
align 4
GetFpu:
fld qword [mydata]
ret

segment .data
mydata:
dq 1.23456789
$endasm


The __m128 type marks a function as returning an array of 4 floats or two doubles in XMM0 register (SSE users). Because the data is 128-bit, it is copied to temporary heap memory, in the same way as you would return a structure or string.
union __m128
float m128_f32[4]
float f32[4]
double d64[2]
endunion

declare get_xmm_value(),__m128

__m128 v = get_xmm_value()

print v.m128_f32[0], v.f32[1], v.f32[2], v.f32[3]

end
$asm
align 4
get_xmm_value:
movups xmm0,[myvalue]
ret

segment .data
align 16

myvalue:
dd 1.0, 2.0, 3.0, 4.0
$endasm


I forgot to say in my previous reply, that console programs, when running from the IDE will be executed in the default command processor window, and the window will be paused when your program terminates. You don't need to wait for a key press before terminating.

Ficko


LarryMc

Sapero

This is why my INI file code was broke and not due to you new headers.
The IF statement in test one is what was in my existing code and worked fine in EB/IWB (ver prior to last).
It doesn't work in the current version.

test two works with all versions.

LarryMc

openconsole

string tp=getstartpath()+ "test.cfg"
string section= "position"
string key= "left"

print "start"
print
print "Len(tp) ",Len(tp)
print "Len(section) ",Len(section)
print "Len(key) ",Len(key)
print
print "test one"
If ((Len(tp) > 0) & (Len(section) > 0) & (Len(key) > 0))
print "success"
else
print "failure"
EndIf
print
print "test two"
If (tp<>"" & section<>"" & key<>"")
print "success"
else
print "failure"
EndIf
print
print "finished"
waitcon
closeconsole
end
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

Larry, your program displays twice Success. There was a bug in the "compare" code part (optimizations), but I have fixed it a week ago. You must still have the buggy parser.

int a=1, b=1
if ((a+1)>b) then action() ' BUG: never true

LarryMc

I downloaded the newest installer I could find (dated 11/23/10) and it has that bug in it.

Reckon LarryS hasn't gotten around to a newer installer with your latest.

So, to keep going forward with the Visual Designer 2.0 I just changed the comparisons to <>"".

Thanks Sapero

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

January 16, 2011, 04:35:43 AM #69 Last Edit: January 16, 2011, 04:51:46 AM by sapero
Added automatic string conversion (from/to unicode) when returning from a function:
$define UNICODE
$define WIN32_LEAN_AND_MEAN
$include "windowssdk.inc"

MessageBoxW(0, function1(), L"ansi->unicode")
MessageBoxA(0, function2(), "unicode->ansi")

sub function1(),wstring
return "hello" ' will be converted to unicode, using the current codepage
endsub

sub function2(),string
return L"hello" ' will be converted to ansi, using the current codepage
endsub


Added $ELIFDEF and $ELIFNDEF. All the $IF/$ELSE conditions can be mixed:
$IFDEF something
...
$elif VERSION>3
...
$elif !(VERSION<3)
...
$ELIFDEF DEMO_VERSION
...
$ELIFNDEF TIME_LIMITED
...
$ELSE
...
$ENDIF


Added single-byte initializer for structures (use it instead calling RtlZeroMemory):
sub ExecuteProcess()
STARTUPINFO si = 0 ' up to 255
STATDATA sdata

sdata.formatetc = 0


Added partial interface support for NEW command:
The CLSID and IID are automatically created from interface name: _CLSID_name, _IID_Iname, so it is not possible (yet) to create a new instance of an interface with different name as the class.
IProgressDialog unk = new IProgressDialog
'IProgressDialog unk = new IProgressDialog[1] ' count is ignored
'IProgressDialog unk = new(IProgressDialog,1) ' count is ignored


The compiler created temporary files in /bin directory. This is no more true: the temporary $$$lib.link will be created in the current-directory by default, or it will append the data to a file specified in LIB_LINK_PATH environment variable. The IWBasic IDE, when compiling a project, initializes LIB_LINK_PATH environment variable to PROJECT_DIR\$$$lib.link before compiling all source files, so that the parser will append all referenced .lib files to PROJECT_DIR\$$$lib.link file.

When using the /P option (for easier variables access in inline assembly) the compiler will check all formal and local variable names for possible conflict with assembly reserved keywords. Use mixed case in variable names if you get a warning.
$option "/P"
sub asm_test(int ret) ' warning: 'ret' variable is conflicting with ret/retn instruction.
sub asm_test(int Ret) ' no warning


Added #define - very helpful for ResEdit fans. Converting #define to $define each time you save the resource script, is now optional.

Added "ZeroVariables" option - when active, all local variables will be initialized to zero.

Added a check to the part handling assignments - it will warn you if the number you want to assign exceeds the bounds of target variable:
SCHAR a = 128 ' warning
a = -129 ' warning
SWORD b = 32768 - warning
b = -32769 ' warning


Added a new item to Tools menu: Edit compiler options. It will open a property sheet where you can set the default state of 11 compiler options, define additional include paths, and specify some default conditions or constants.

Comments in inline assembler will have the color of a comment (green).

sapero

January 20, 2011, 05:31:35 PM #70 Last Edit: January 20, 2011, 05:47:27 PM by sapero
Added $REGION and $ENDREGION - just another version of 'REGION and 'ENDREGION.
The optimizer now includes tracking of esi,si,edi,di,ebx,bx,bl registers - if they are not modified in a subroutine, the assembly code will not include the code for saving and restoring them.

Working on a plugin system for the parser, which will make possible to generate code for any platform/cpu (Windows/Linux/Mac/Arm/Pic/Atmel...), assembler, or additional high level compiler.

LarryMc

Quote from: sapero on January 20, 2011, 05:31:35 PM
Working on a plugin system for the parser, which will make possible to generate code for any platform/cpu (Windows/Linux/Mac/Arm/Pic/Atmel...), assembler, or additional high level compiler.

NICE!!!!!!!!!!!!!!

LarryMc
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Doc

Ditto what LarryMc said for sure!

-Doc-

Barney

Quote from: sapero on January 20, 2011, 05:31:35 PMWorking on a plugin system for the parser, which will make possible to generate code for any platform/cpu (Windows/Linux/Mac/Arm/Pic/Atmel...), assembler, or additional high level compiler.
Now you are talking!  :)
Nice!

Barney

Logman

January 21, 2011, 06:35:10 AM #74 Last Edit: January 24, 2011, 05:14:58 AM by Logman
As always, you are doing a bang up job--good enough to keep me with you.

I do have a few thoughts about missing capabilities in IWBasic that I think would substantially improve the language:

1. Have we given any thought to adding a capability to use/create MACROS in IWBasic?

2. If I'm not mistaking, the IDE doesn't have an auto indent capability when writing code. I really miss this.

3. The IWBasic compiler doesn't remove unused code like other compilers I've used. Is this still true? Might be a consideration down the road.

4. One of the greatest features of the IWBasic compiler is that it is a multi-pass compiler, which means we can put code anywhere in the program and don't have to declare all subs and etc. beforehand. I hope IWBasic remains a multi-pass compiler.

5. I'd like to see built-in Mutex and Thread capability rather than having to use the Win API to build code to do these processes.

6. Since I habitually incorporate assembly code in my IWBasic programs, I'd like to be able to update the NASM compiler in the BIN directory to keep pace with NASM development.  

7. Probably still a long way off, but IWBasic really needs to be implemented in 64-bit over the next year.

Just some thoughts.

By the way, I'd be willing to help out by writing and maintaining an IWBasic User's Manual if no one else is doing this.

Logman ;D
Education is what you get when you read the fine print.<br />Experience is what you get when you don't!