April 30, 2024, 06:07:52 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


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.

sapero

May 16, 2010, 02:48:12 AM Last Edit: February 16, 2011, 02:10:19 PM by LarryMc
Hello,
I am the new IWBasic compiler coder. In this topic I will share with you what changes are made, and what I'm working on.
This topic will be modified as I'm progressing with the compiler.

Command line:

  • syntax: /[option][parameter] without space between option name and parameter. Option name is not case sensitive.
  • option /As - Compile and assemble. Optional s is passed to nasm.
  • option /Bpath - include file <path> before parsing the main file.
  • option /C number - change default codepage from Ansi (CP_ACP) to number. This option ensures that unicode strigs L"" are properly converted from multibyte character set (controlled by your text editor) to unicode binary data. If your editor is working with utf-8, set this option to /C65001 (CP_UTF8).
      You will be warned if a codepage is not valid for you system.
  • option /D name{=value} - define a numeric constant.
  • option /E number - show up to number errors; default is 5. Does not apply to syntax errors.
  • option /H or /? displays this help.
  • option /I path - add a search path for include files. Pass full path, or a relative path to current file (\..\ is supported)
  • option /Lname.dll - Loads a plugin (TODO).
  • option /P defines arguments and local variables for use in inline assembly. Take care of variable names, so that they don't interfere with assembler registers or instructions.
sub sum(int a, int b),int
int c
_asm
mov eax,[a]
add eax,[b]
mov [c],eax
_endasm
return c
endsub

  • option /R - Inputfile specifies a path to response file, where each line is a pathname to an IWBasic source file.
  • option /W number - disable warnings. 1: uninitialized variable, 2: unreferenced variable, and 5 more for advanced users. If not specified then all warnings are enabled.

You can set command line options directly from the source code:
$option "name=value"
$option "name value"


Where name can be one of: /c or Codepage, /e or ErrorLimit, /i or IncludePath, /p or AsmVariables, /w or Warning, Return, Intrinsic, Optimization, CaseSensitive, novtable, oldlibslocation, strict, ZeroVariables, /m, /a, LibPath, QuoteLibPaths, ResolveLibs.
Value depends on the current option, and can be:

  • Codepage - push,pop,utf8,ansi,number. Sets the codepage for unicode strings.
  • ErrorLimit - push,pop,number. Sets the upper limit for compiler error messages.
  • IncludePath - string. Add a search path for include files.
  • AsmVariables - push,pop,0,1,yes,no,on,off,enable,disable. Define formal and local variables for inline assembly code.
  • Warning - push,pop,default,number,enable:number,disable:number. Sets a new or modifies the current filter for warning messages.
  • Return - push,pop,0,1,yes,no,on,off,enable,disable. Force the compiler to not alter eax,edx when returning from a subroutine. The automatic "return 0" will be inactive, so be sure to return zero from window handlers.
  • Intrinsic - push,pop,0,1,yes,no,on,off,enable,disable. Enable/disable intrinsic functions.
  • Optimization - push,pop,0,1,yes,no,on,off,enable,disable. Enable/disable Optimizations.
  • CaseSensitive - push,pop,0,1,yes,no,on,off,enable,disable. Enable/disable case sensitive compilation.
  • NoVtable - push,pop,0,1,yes,no,on,off,enable,disable.
  • OldLibsLocation - push,pop,0,1,yes,no,on,off,enable,disable. Controls where the compiler should create $$$lib.link file. Previously the /bin directory was used, and the new IWBasic will use project directory.
  • strict - push,pop,0,1,yes,no,on,off,enable,disable. Show any possible problems, for example unknown type in DECLARE (even unused).
  • ZeroVariables - push,pop,0,1,yes,no,on,off,enable,disable. If active, local variables will be initialized to zero.
  • /m - push,pop,0,1,yes,no,on,off,enable,disable. The same as command line /m switch, but it can be canceled.
  • /a - push,pop,0,1,yes,no,on,off,enable,disable. Compile and assemble.
  • LibPath - directory. Add a search path for .lib files. Used with ResolveLibs option to write full lib paths to $$$lib.link file.
  • QuoteLibPaths - push,pop,0,1,yes,no,on,off,enable,disable. Quote spaces in $$$lib.link file. Useful option if you want to use another linker.
  • ResolveLibs - push,pop,0,1,yes,no,on,off,enable,disable. Convert all relative paths passed to $USE, to full paths.
  • DimOrder - push,pop,left,right,default - change the order of variables definition
int a,b,c,d ' the default is 'right', the 'd' variable is defined first.

Push/pop option value is to save/restore the current value. If you want to modify a option for a few lines in your code, use:
$option "name push" ' save current
$option "name new_value" ' modify
...
$option "name pop" ' restore

Numbers passed to $option can be formatted in decimal, or hexadecimal with 0x prefix.
$option "codepage 65001"
$option "codepage 0xFDE9"

Currently implemented warning filters:

  • 0x0001 uninitialized variables
  • 0x0002 unreferenced local variables
  • 0x0004 missing return value
  • 0x0008 size of local variables exceeded 32KB
  • 0x0010 variable/constant name collision
  • 0x0020 undeclared function
  • 0x0040 temporary string/udt assigned to pointer


Special constants:

  • __WARNINGFILTER__ returns the current warning filter
  • __CODEPAGE__ returns the current codepage
  • __FILE__ returns the current file path (a string)
  • __LINE__ returns the current line number
  • __IWVER__ returns a number with compiler version 0x02xxyyzz.
  • __CASESENSITIVE__ - not a constant, but will be defined if case sensitive mode has been enabled


Strings:

  • escape sequences \\, \", \t, \n, \octal, \xHEX. Where octal (number) can be up to 377 (377o=255), HEX up to FF.
      Example: "\377" - one character string, same as "\xFF"
      Example: "\400" - will generate two characters "\40" and "0", because 400o=256 (is greater than 255)
  • Operator & before "text" will return address of the string when assigning to non-string/pointer type
  • Added multiplication operator: string*boolean - will return string if boolean is true, and an empty string if the boolean is false
int count = 2
print "found ", count, " item", "s"*(count<>1)



Unicode strings:

  • escape sequences \\, \", \t, \n, \octal, \xHEX. Where octal (number) can be up to 177777, HEX up to FFFF.
      Example: L"\"string\"\0\n\tstring\\\x0string".
  • UTF-8 encoded strings are supported up to 6 bytes per character.
  • DBCS encoding is supported too (both encodings are supported in scintilla control: SCI_SETCODEPAGE.
  • UTF-8 BOM marker (at the beginning of source file) is now detected, and has higher precedence than the codepage switch /c
  • Operator & before L"text" will return address of the string when assigning to non-string/pointer type
  • Multiplication operator - see Strings above.

String Literals:

  • Added `expression` where expression can be up to 4 bytes (4 or less characters). `A` will return 65, the same as ASC("A") but without calling a command.
uint i = `abcd`

  • Added L`expression` (unicode version with utf-8 support) where expression can be up to 4 bytes (2 or less characters). L'A' is equal to 65.
iwstring w[4]
w[0] = L`ä`
w[1] = L`ó`
w[2] = L`æ­¦`
w[3] = L`\0` ' =0; =`\x0`; =L`\x0`

istring s[4]
s[0] = `A`,0

  • Both literals, ansi and unicode, support escape sequences, where \r returns 13, and \n returns 10.

Preprocessor:

  • $USE will search for libraries first in relative to current file path location, then in default locations.
  • added $undef, for undefining conditions or constants (defined by $define)
  • added $error and $warning directives
$ifndef UNICODE
$error "This file must be compiled with UNICODE condition"
$endif

  • added $typedef as an alias for typedef.
  • a space and/or tab (one or more) is allowed after the dollar character in $include, $ifdef, $ifndef, $else, $endif, $typedef.
  • added $if expression. You can use the following operators: =, ==, <>, !=, +, -, *, /, %, |, or, || (xor), &, &&, and, <<, >>, !, ~, >, >=, <, <=
    All the operators are handled also in CONST, ENUM and $DEFINE
  • added $elif, $elifdef, $elifndef
$if (VERSION > 0x0202) and (SUBVERSION <> 0)
...
$endif

$ifdef TRIAL_VERSION
$elifdef DEMO_VERSION
$else
$endif


Subroutines:

  • Use STATIC keyword to define static variables
sub function()
static POINT pt
static int x
static def y as int
static dim z as int

  • The CDECL modifier can be specified directly in the subroutine:
sub cdecl blah()
global sub cdecl blah()


Labels:

  • Labels defined inside a subroutine are private to that subroutine, that is, you can now use the same label in multiple subroutines (eg. LABEL cleanup). It is no more possible to GOTO into subroutine, or GOTO from a subroutine. If you really want to jump in/out, use inline assembly to define a label and the jump. Internally all local labels have unique names.
label outside
'goto cleanup <- undefined, unless defined in global namespace
'goto subroutine1 <- error

sub subroutine1()
'goto outside <- undefined
goto cleanup
cleanup:
endsub

sub subroutine2()
'goto outside <- undefined
goto cleanup
cleanup:
endsub


Language:

  • Names of variables, constants ($define, const, setid, enum), typedef, structures and subroutine (sub, export) can be of any size. Only when compiling in debug mode, subroutine names are truncated to 63 bytes (characters)
  • Passing arrays without operator "&" to a function or method with unknown number of arguments behaves now correctly, the array will be passed by reference.
char array[8]
declare extern function(...)
function(array)

  • VarArg operator (...) requires that at least one parameter is passes to a function or method.
  • PRINT function has a short version: ?
? 1,2,3
  • Variables can be imported
import __argc as int
import __wargv as pointer ' call __wgetmainargs to initialize
import __argv as pointer ' call __getmainargs to initialize

  • Methods can be imported
class CC
declare import CC()
declare import _CC()
declare import method()
endclass



New variable types:

  • TSTRING  - If UNICODE is defined, it will be WSTRING, else STRING
  • ITSTRING - If UNICODE is defined, it will be IWSTRING, else ISTRING

Inline assembler:

  • In case of an syntax error, the line number in Build window will be correct.
  • added $emit, $asm, $endasm
$emit nop

Mixing Basic with Assembler:

  • Added "DECLARE name AS type" for assember labels
type mytype
int a
int b
endtype

typedef DWORD uint
declare iVal as int
declare sVal as string
declare tVal as mytype ' TYPE/ENDTYPE
declare dVal as DWORD  ' typedef

print iVal, iVal[1]
print sVal
print tVal.a, tVal.b
print tVal[1].a, tVal[1].b
print dVal

_asm
segment .data
iVal: dd 6, 5, 4, 3, 2, 1
sVal: db "hello", 0
tVal: dd 100,101, 200,201
dVal: dd 500
segment .text
_endasm



Constants:

  • Added uq (unsigned quadword) modifier for decimal numbers: uint64 = 1234567890uq.
autodef = 1234567890uq
if (typeof(autodef) = @TYPEINT64)
print "type of 1234567890uq is INT64"
elseif (typeof(autodef) = @TYPEUINT64)
print "type of 1234567890uq is UINT64"
endif

  • Added binary numbers:
int     binary   =        /*  optional zero's-> */ 00000000000000000000000000011000b ' Bin
uint   ubinary   =                                 00000000000000000000000000011000bu ' Bin Unsigned
int64   binary64 = 0100000000000000000000000000000010000000000000000000000000011000bq ' Bin Quadword
uint64 ubinary64 = 1000000000000000000000000000000010000000000000000000000000011000buq ' Bin Unsigned Quadword

  • Enumerations can be created with operators:
enum myenum
minusone = -1
zero
one
two = one+1
six = 2+2*2
endenum

print minusone, zero, one, two, six


Operators:

  • Added a?b:c - inlined version of IIF function from Windows headers. The advantage of this operator is that b or c will be executed depending on the A condition.
    If A is true, and C is a function call, C will be not executed. Internally this operator generates IF A then return B else return C.
    If A is known at compile time, B or C will be removed from the code.
  • Added ==, !=, && operators:
if (a == b) then equal()
if (a = b) then equal() ' still there
if (a != b) then notEqual()
if (a && b) then BothTrue()
if (!a && !b) then BothFalse()

  • Added ~ operator (bitwise NOT), supported in constants and variables up to 32-bit: (s)char,(s)word,(u)int
SetWindowLong(hwnd, GWL_STYLE, styles & ~WS_VISIBLE) ' hide window
  • The following operators can be used to compare UDT's: =, ==, <>, !=, <, >, <=, >=
  • Added [pre|post][inc|dec]rement operators: a=b++ : a=b-- : b=--b : a=++b


Code generation:

  • Expressions with the following operators will be evaluated at compile-time, (when possibe):
+, -, *, /, %, and, &, or, |, ^ (aka XOR), <<, >>, = (or ==)

    The following example code will initialize the variable with precomputed value 0x2000F instead generating code to calculate it:
int a = 1+2|4|8|@MINBOX

    Supported contant types: numbers (decimal, hex, signed/unsigned, 32/64 bit), constants defined by CONST, SETID, $define


Intrinsic functions:

  • The compiler supports the following intrinsic functions: sin,sind,fsin,fsind,cos,cosd,fcos,fcosd,sqrt,tan,ftan,tand,ftand,log,log10,abs (and more in the future).
  • DEFINE_GUID for global and local variables has intrinsic form too, but only if you supply all the guid members as numbers.
    Globally defined GUID is successfully initialized with intrinsic DEFINE_GUID, will be allocated as raw data, without any code.
  • RGB function if used with numbers, will be replaced with precomputed value.


Loops:

  • Char and word (signed or unsigned) can be passed to WHILE stateent
  • Added BREAK keyword, to terminate the execution of the nearest enclosing loop (FOR-NEXT, DO-UNTIL, WHILE-ENDWHILE)


Other:

  • The temporary $$$out.a file will be automativally deleted.
  • The temporary $$$lib.link file will be created in current directory.
  • If an error occurs while procssing .incc file, the correct file name will be reported (instead .eba)
  • Invalid assignment, bad type errors will be more descriptive: unable to convert TYPE to TYPE, cannot assign TYPE to TYPE...

sapero

May 24, 2010, 06:39:42 AM #1 Last Edit: June 05, 2010, 04:59:01 PM by sapero
I am thinking to add a $pragma directive to the compiler. It will make possible to set the command-line options directly from your source code.
Examples:
$pragma compiler "include=..\\zlib" ' additional include search path, relative to current file path.
$pragma compiler "include=$(ProjectDir)\\..\\zlib" ' additional include search path, relative to project path.
$pragma pack "push{,number}|pop|default|number" ' change default structure packing
$pragma warning "disable=1234" ' disable warning 1234
$pragma compiler "codepage=65001" ' use utf-8 codepage for unicode strings

$pragma linker "libs=..\\zlib\\lib" ' add library search path, relative to current file path.


EDIT: The $OPTION keyword has been extended, so there is no need to add a new $PRAGMA keyword.

aurelCB

That would be great Sapero.
If i may say something abut backslash using.
Is it not enugh one backslash not two?

sapero

You can use single backslashes, but only if the next character is not one of 0,1,2,3,4,5,6,7,x,\,t,n," and optionally r,` characters inside character constants.
If you invite me for a beer, I'll add a option to disable escape sequenes ;)

LarryMc

If it were me I'd leave it as \\.

If you add an option to disable it then you need to make sure it doesn't break existing code that is using \\.

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

aurelCB

Ok guys i understand, i just ask..

Steven Picard

Or, you could do something similar to C#:

String myVar = "c:\\directory\\something";

Sting myVar = @"c:\directory\something";

Of course, in the last option you cannot include escape sequences like "\n\r".

sapero

May 24, 2010, 04:17:09 PM #7 Last Edit: May 25, 2010, 05:21:35 AM by sapero
I am now working on optimized operations on constants.
int a = 1 + 2
This simple program currently will generate code to add 1 and 2, but in the future it will evaluate the expression at compile time.

I have already a working idea, the implementation can handle basic operators like +, -, *, /, %, and, &, or, |, ^ (known as xor), <<, >>. It handles integers and floating point constants, with exception for shifts.

sapero

Done, ID's are now recognized and evaluated, if possible.

There is also POWER operator. A simple "2^8" expression could be evaluated too.
I think to evaluate only integers, because the raw floating point result ("1.2^3.4") can be controlled by the end-user (FPU precision), and the user should have full control over it.

sapero

May 25, 2010, 04:17:44 AM #9 Last Edit: May 26, 2010, 02:53:08 PM by sapero
Shifts added for 32 and 64 bit integers. Any idea how to handle floats?
1. do nothing, forward to default handling    // current
2. convert to int or int64, shift, convert back
3. shift the raw float/double bits, keep sign bit (or shift it too)
4. separately shift mantissa and exponent

Ficko

Honestly I don’t have any real life mock up why to shift a floating number at all  :P
but may someone can come up with some reason.
Just leave this question open for feedback for a while.

Otherwise I would vote for 3 (shift it too) but I can’t tell you why just sounds logical. ;D

sapero

May 26, 2010, 02:45:37 PM #11 Last Edit: May 26, 2010, 02:51:36 PM by sapero
Added missing interfacing between assembler raw data and Basic variables:
declare rectangles as WINRECT
'unsupported yet: declare name[2] as type
'unsupported yet: declare name1,name2 as type

print rectangles.left, rectangles.top, rectangles.right, rectangles.bottom
print rectangles[1].left

_asm
segment .data
rectangles: dd 1,2,10,11 ; rectangles[0]
           dd 3,4,30,31 ; rectangles[1]
segment .text
_endasm


This addition is planned:
declare rectangles as WINRECT = 1,2,10,11 {, next rectangle coordinates}

LarryMc

May 26, 2010, 03:17:30 PM #12 Last Edit: May 26, 2010, 03:47:06 PM by Larry McCaughn
I like that.
I could have really used this on the Visual Designer!!!
declare rectangles as WINRECT = 1,2,10,11 {, next rectangle coordinates}
                                                                                  ^
                                                                                  ||
Is it your intention to make a space a delimiter in the parameter list?
Just curious.


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

I used the same syntax as Paul in his help file: function(required, required {, optional {, optional}}).
I don't remember where I saw it. Spaces are optional, only comma character is the delimiter.
declare rectangles as WINRECT=1,2,3,4,5,6,7,8

LarryMc

My bad!
You had it exactly right.  I just misread it.
Senior moment!!! Sanctuary! Sanctuary! ;D

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

Ficko

I like that feature very much as well! :)

sapero

I am working now on basic optimizations for function/method calls. If you pass a constant number, the value will be pushed on the stack without storing it first in register(s). Because we have floats and doubles, and you are not restricted to pass a float where a float should be. The compiler will convert types silently, if possible:

INT/UINT to int,uint,int64,uint64,float,double,comref,pointer,string,wstring
INT64/UINT64 to int,uint,int64,uint64,float,double
...
Example int->float:
declare go(float f)
go(1)

Integer 1 will be converted to 32-bit float value (0x3F800000) using processor specific FPU commands. Because there can happen data loss or rounding, you should be able to control how the processor should convert between integers and floats. I think I'll add additional command line switch (/F - from Float), where you just pass the "FCW" - Floating point Control Word, providing custom precision (24,53,64 bits) and one from four rounding modes.
It can be a number (0-15, 2bits:precision, 2bits:rounding), or a string: /Fnearest|up|down|toward,24|53|64.
Or should I just keep it as is, using some default settings from operating system, and then you could control the FPU mode by saving all constants in variables (to hide it from the optimization)? What do you think?

By the way, the first topic has been updated - Labels.

sapero

June 01, 2010, 12:58:21 PM #17 Last Edit: June 01, 2010, 01:10:13 PM by sapero
IWBasic 2 is now able to evaluate expressions in a new conditional keyword $IF:
$ifndef MYVERSION
 $warning "MYVERSION was not defined, assuming default value"
 $define MYVERSION 0
$endif

$if (1=2) or (MYVERSION < 1)
$error "i'm sorry, but something here is wrong"
$endif


Unicode UTF8 file marker (BOM) is now handled for each parsed command/source/include file.
The CONST, $DEFINE and $IF keyword can handle more operators: =, ==, <>, !=, +, -, *, %, /, |, or, || (xor), &, &&, and, <<, >>, !, ~, >, >=, <, <=


Enum has been extended:
enum myenum
one
two = one+1 ' including all operators
three
minusone = -1
endenum

LarryMc

Meant to ask about this earlier:
$ifndef MYVERSION
  $warning "MYVERSION was not defined, assuming default value"
  $define MYVERSION 0
$endif

$if (1=2) or (MYVERSION < 1)
$error "i'm sorry, but something here is wrong"
$endif


What do the $warning and $error lines actually do?

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

$warning and $error will display a string in Build window, in the IDE (stderror file stream).
$warning does nothing more, $error terminates compilation.

Sometimes you need to stop the compilation if some conditions are invalid, for example outdated header:
$include "designer.inc"
$if designer_header_version < 2
  $error "this example requires an updated version (2) of designer.inc"

LarryMc

Makes perfectly good sense.
Thanks for the explanation.

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

June 04, 2010, 09:12:19 AM #21 Last Edit: June 18, 2010, 12:12:21 PM by sapero
For today, we have in addition:

  • Extended $OPTION keyword (to set or change selected command line options)
  • Four special constants __WARNINGFILTER__, __CODEPAGE__, __FILE__, __LINE__, __IWVER__


__FILE__ and __LINE__ macros you will probably love when compiling in debug mode, to display 'professional' info to your debug window.
print "current error filter: 0x", hex$(__WARNINGFILTER__)
print "current codepage: ", __CODEPAGE__
print "current file: ", __FILE__
print "current line number: ", __LINE__ :
print "compiler version: 0x", hex$(__IWVER__)


$option "warning push" ' optional: save current mask
$option "warning disable:0001"
sub mysub(int pValue)
int t
mysub(t)
endsub
$option "warning pop" ' optional: restore saved mask


$option "/p 1"
sub mysub3(int t)
_asm
mov eax,[t]
_endasm
endsub
$option "/p 0" ' optional: turn it off


I have planned to add new $PRAGMA keyword, but if we already have $OPTION, then why not to extend it?

sapero

June 06, 2010, 07:41:23 AM #22 Last Edit: June 18, 2010, 12:10:23 PM by sapero
The $USE directive has now additional feature: it will first search for the library in location(s) relative to current file path. If it finds one, the full path at compile time will be passed to linker, else the library will be accessed in defaut way.

Now if you want to share source code with .lib file, just put the library in the same directory where is the source or include file with $use directive. There is no need to copy it to installdir/libs.

$use "mylib.lib" ' if exists CurrentFileDir\mylib.lib - use it, else do default
$use "libraries\\mylib.lib" ' if exists CurrentFileDir\libraries\mylib.lib - use it, else do default
$use "..\\libraries\\mylib.lib" ' if exists CurrentFileParentDir\libraries\mylib.lib - use it, else do default



Imported variables:
You can now import variables form DLL's:import __argc as int
import __wargv as pointer ' call __wgetmainargs to initialize
import __argv as pointer ' call __getmainargs to initialize

$use "msvcrt.lib"
declare cdecl import, __getmainargs(pointer argc, pointer ppargv, pointer ppenv, int expand_wildcards, pointer new_mode)
declare cdecl import, __wgetmainargs(pointer argc, pointer ppwargv, pointer ppwenv, int expand_wildcards, pointer new_mode)

int argc, new_mode, a
pointer pargv, penv
pointer pwargv, pwenv

' initialize __argc and __argv
__getmainargs(&argc, &pargv, &penv, 0, &new_mode)
' initialize __argc and __wargv
__wgetmainargs(&argc, &pwargv, &pwenv, 0, &new_mode)

print "you passed ", __argc-1, "arguments"
for a=0 to __argc-1
print " arg ", a, "= ",*<string>(*<pointer>__argv[a])
print "warg ", a, "= ",*<wstring>(*<pointer>__wargv[a])
next a

Compile as varImport.exe (console target), open command prompt and type: varImport 123 abc "z:\program files"

Imported methods
You can now import methods from DLL's:
classdef.incclass CExporter
declare import CExporter()
declare import _CExporter()
declare import TestMethod()
endclass

DllMain.eba (dll code, compile and create import library)$include "classdef.inc"
export CExporter@CExporter
export CExporter@_CExporter
export CExporter@TestMethod

sub CExporter::CExporter()
print "CExporter constructor called"
endsub

sub CExporter::_CExporter()
print "CExporter destructor called"
endsub

sub CExporter::TestMethod()
print "CExporter TestMethod called"
endsub

WinMain.eba (exe code)$include "classdef.inc"
$use "DllMain.lib"

CExporter c
c.TestMethod()


-------------------------------
June, 7th

The compiler supports intrinsic functions, currently hardcoded in the compiler. Maybe in the future the compiler will read instructions from special library, or from binary file.
Programs that use intrinsic functions are faster because they do not have the overhead of function calls, but may be larger because of the additional code created.

DEFINE_GUID has also intrinsic form, for global and local variables:
GUID _IID_ICustomGuid
DEFINE_GUID(_IID_ICustomGuid, 1, 2,3, 4,5,6,7,8,9,10,12) ' no function call, no code generation
blah()

sub blah()
GUID g
DEFINE_GUID(g, 1, 2,3, 4,5,6,7,8,9,10,11) ' only 4 simple assembly instructions

if (g==_IID_ICustomGuid) ' you can compare two UDT's of the same type
print "equal"
else
print "not equal"
endif
endsub


--------------
June, 17

Added pre-incrementation, post-incrementation, pre-decrementation, post-decrementation operators:
variable++
variable--
++variable
--variable

All the expressions are returning a value, which can be used directly in another expression:

Print numbers 3,2,1,0
int v = 4
while (v--) ' or --v
 print v
endwhile


int x = 4
print x++ ' will print 4, and x will be set to 5. Return current value, then modify
print ++x ' will print 6, and x will be set to 6; First modify, then return new value



Note: when used as function argument, the execution flows from right to left:
print x++,x++ ' will print x+1, x


-------------
Added operator & for strings and wstrings - will be usefull when passing an string as LPARAM in SendMessageA/W
int address = &"text"
address = &L"text"
SendMessageA(d1.hwnd, WM_SETTEXT, 0, &"caption")

sapero

June 18, 2010, 08:59:28 AM #23 Last Edit: June 19, 2010, 06:39:10 AM by sapero
Added BREAK keyword, to terminate the execution of the nearest enclosing loop (FOR-NEXT, DO-UNTIL, WHILE-ENDWHILE)

WHILE (ShouldEnterThisBlock)
 if (!InitializeDevice()) then break
 if (!SetDeviceParams()) then break

 for a=0 to 4
   if (a=1) then break ' quit from for. BREAK inside FOR will internally use BREAKFOR.
 next a

break
endwhile


Cosmetic change: (s)char and (s)word can be passed to WHILE condition.
char c = 2

while (c)
 print c



Added typecasting: word() schar() ... double(). Currently only casting to double is implemented. This is very usefull when you are using CRT string routines like sprintf, and need to output a float:
sprintf(buffer, "%f", double(VariableOrConst))


Optimizations
I have added some optimizations to code generation - when calling a subroutine/method, assigning a value, and in other places. This is in experimental phase, every day something is changed, and by default is disabled. To enable optimizations, put the line below, above the code you want to be optimized:$option "optimization=on"

I have also added some optimizations to the 'unoptimizable' code parts - removed operand size specifier in assembly instructions like "mov reg,value" or push value. If you want to use this optimization, add the following option to additional assembler options (in project options dialog): -O1. The assembler will find "push 0", and seeing -O1 option, will generate 2 instead 5 bytes of code for the push instruction. Previously the PUSH instruction included operand size specifier "push dword 0", and nasm was disallowed from optimizing it.

June, 19
Optimized DELETE, WHILE and UNTIL.
"WHILE number" and "UNTIL number" will not compare, if "number" is known at compile time.
do
  print
until 1

This example will generate code only for PRINT, as if do-until was not there.


Added T modifier for strings: T"". If you write unicode+ansi friendly programs, use T"string" to generate a string or wstring, based on the current UNICODE condition. If the condition is defined, T"" will generate unicode string, else an ansi string.
$ifdef UNICODE
declare import, testme alias testmeW(wstring p)
$else
declare import, testme alias testmeA(string p)
$endif

testme(T"hello")



Added two new variable types: TSTRING and ITSTRING
TSTRING = T"hello"
$ifdef UNICODE
   ' the first line was WSTRING = L"hello"
$else
   ' the first line was STRING = "hello"
$endif

Brian

Hi, Sapero,

Is there room for a REDIM command, or is that already in your plans?

Brian