Skip to content

Version 13 Revision 44

Choose a tag to compare

@M2000Interpreter M2000Interpreter released this 01 Mar 15:10
· 176 commits to main since this release

M2000Setup removed due to the fault on Select Case (use revision 46)

  1. Now we can change value r or i of a complex number in a list.
a=list
a(100)=(10, 3i)
a(100)|r=1000
Print a(100)|r, a(100)|i
  1. See at info then HashList object. Now we can put Biginteger and Complex numbers.

Version 13 Revision 43
Now we can use each() iterator for static variables of type tuple, list and stack:
'the each function has two types:using comma after object like a function, and anohter one using only space to pass START or END or number then TO then START or END or Number. For each type a negative number -1 means last item, and -2 one before the last.

Rem : clear ' this clear can reset all static variables by erase them
module inner {
	static a=(10,20,30,40,50), b=(LIST:=1,2,3,4,5), c=(STACK:=-1,-2,-3,-4,-5)
	' need () because if c exist as static interpreter need to skip expression
	' so we need to  use (  ) because the := isn't part of expression but is part of STACK
	k=each(a 1 to  3)
	while k
		print array(k),
	end while
	print
	k=each(b, -1,  -3)
	while k
		print eval(k),
	end while
	print
	k=each(c start to  -2)
	while k
		print stackitem(k),
	end while
	print
}
inner

Version 13 Revision 42
Fixed a bug for these functions (ATN and TAN for Radians): rATN(), rTAN()
Updated help file

Version 13 Revision 41
Fix the second, when was array when we read the read only array, we expect to get a copy and not the actual object whis is a read only:

' first
const alfa=(,)
push alfa
read z as array  'we say array so we get a copy from constant
print len(z)=0 ' ok
push (1,2,3)
read z ' now is ok
print len(z)=3
clear
' second
const alfa=(,)
push alfa
z=(1,2,3)
read z
print len(z)=0 ' ok
push (1,2,3)
read z ' now is ok
print len(z)=3
clear
' third
const alfa=(,)
push alfa
read z          ' z get first value, so get the constant
print type$(z)="tuple" ' but is a read only tuple.
print len(z)=0 ' ok
push (1,2,3)
try {
	read z ' now is ok
	print len(z)=3
}
Print Error$
clear
' forth
const alfa=(,)
push alfa
read z as const
Print type$(z)="Constant"
Print type$((z))="tuple"  ' but read only
' let m=z ' this get the Constant
m=z ' this get a copy
print m is z = false
push (1,2,3)
read m ' ok

Version 13 Revision 40

  1. Fix a problem with module MULSH from INFO file. This has to do with a change on Array() function before some two-three revisions.
  2. Check a lot of modules in INFO file.
  3. Fix Font statement to read string variables without suffix $ on name.
  4. Addition/Changes for some modules in INFO file.

Version 13 Revision 39
Image control text property now display name of image control using unicode.

Version 13 Revision 38
Update for ucchartArea, ucchartBar, ucPieChart controls

Version 13 Revision 37

  1. Fix: Edit A() as B() (rename a function from M2000 CLI)
  2. Adding ucChartBar user control
  3. Addition of some properties for ucChartArea

Version 13 Revision 36

  1. Fix a problem when we pass an enumerator value and we wish to hold the value non the object, and the parameter has non enumerator type and has an optional value. So now this work:
MODULE tst {
	MODULE SOMETHING (VAL1, VAL2=0&, VAL3="OK") {
		LIST ' show variables
		? VAL2=10, TYPE$(VAL2)="Long"	
	}
	ENUM ALFA {X=10}
	'call module SOMETHING
	SOMETHING 0, X
	'call sub SOMETHING()
	SOMETHING(0, X)
	
	SUB SOMETHING(VAL1, VAL2=0&, VAL3="OK")
		LIST ' show variables
		? VAL2=10, TYPE$(VAL2)="Long"
	END SUB
}
tst
  1. Non close lines for curves, circles and polygons using last character the semicolon.
SMOOTH ON  // WORKS WITH SMOOTH OFF
MODULE ALFA (N) {
	MOVE 5000, 8000
	PEN ,N{  ' N IS OPACITY (255-100%, 0 -0%)
		WIDTH 10 {CIRCLE FILL 10, 3000,2/1,, PI/2, PI;}
		WIDTH 10{COLOR 10{CURVE 0,2000,1000,-1000,3000,-3000;}}
		WIDTH 10{CURVE 0,2000,1000,-1000,3000,-3000;}
		WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0;}
		WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0}
		WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0;}
		COLOR 0,1{WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0;}}
		WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0;}
				
	}
	WIDTH 10 {POLYGON 1, 1000,0,0,1000,-1000,0, 0,-1000}
}
CLS, 0
DRAWING {
	PEN , 100 {GRADIENT 1, 2}
	ALFA 120
} AS SOMETHING
MOVE SCALE.X DIV 2, SCALE.Y DIV 2
IMAGE SOMETHING,SCALE.X DIV 2,,30
ALFA 100

Version 13 Revision 35
SGN() function is on now,,,

Version 13 Revision 34
Addition: #STUFF() see example. Also Array(Stack_type_object) now return type is tuple. (changed with not altering the use of, but only the underline object, a lighter mArray object, and the return value from Type$() function).

CLASS ALFA {
	X=10
}
DIM A(10)
Z=POINTER(ALFA())
A(3):="OK", 100, (1,2,3,4), Z
M=A()
? M#STUFF(6).X
Z=>X++
? M#STUFF(6).X
ZZ=M#STUFF(6)
? Z IS ZZ
? A(3)
? M#STUFF(3)="OK", M#VAL(3)=0, M#VAL$(3)="OK"
? M#STUFF(4)=100, M#VAL(4)=100, M#VAL$(4)="100"
? M#STUFF(5)#MAX()
' second change:
FLUSH
DATA 1,2,3
m=ARRAY([])
? TYPE$(m)="tuple"

Version 13 Revision 33
Fix an old program which uses properties of com objects with indexes saved to arrays and inventories.

This is an example which was ok for version 8.9 (2017) but not for later versions until now.

// Using Inventories (lists)
declare form1 form
declare list1(3) combobox form form1
inventory controls, Enabled
For i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      with list1(i),"MenuStyle", True, "MenuWidth", 3000,  "MenuEnabled" as new list1_enabled()
      with list1(i),"label", "Menu"+str$(i), "list" as new list$()
      Method list1(i), "MenuItem","Command 1",True
      Method list1(i), "MenuItem","Command 2",false
      Method list1(i), "MenuItem","Command 3",True
      Append controls, i:=list$()
      Append Enabled, i:=list1_enabled()
      controls$(i)(0)="ok"+str$(i)
      Print type$(Enabled(i)()), type$(controls$(i)())
      if i=1 then Enabled(i)(1)=true
      Print list$(0), "ok", controls$(i)(0), Enabled(i)(1)
}
method form1, "show",1
declare list1() nothing
declare form1 nothing

This is an example which work until version 11:

// using tuple
declare form1 form
declare list1(3) combobox form form1
controls=(,)
Enabled=(,)
link controls, Enabled to controls$(), Enabled()
For i=0 to 2 {
      Method list1(i), "move", 2000,1200+i*800, 5000,600
      with list1(i),"MenuStyle", True, "MenuWidth", 3000,  "MenuEnabled" as new list1_enabled()
      with list1(i),"label", "Menu"+str$(i), "list" as new list$(), "MenuGroup","group_a"
      Method list1(i), "MenuItem","Command 1",True
      Method list1(i), "MenuItem","Command 2",false
      Method list1(i), "MenuItem","Command 3",True
      Append controls, (list$(),)
      Append Enabled, (list1_enabled(),)
      Print Type$(list1_enabled())
      controls$(i)(0)="ok"+str$(i)
      Print type$(Enabled(i)()), type$(controls$(i)())
      if i=1 then Enabled(i)(1)=true
      Print list$(0), "ok", controls$(i)(0), Enabled(i)(1)
}
method form1, "show",1
declare list1() nothing
declare form1 nothing

Version 13 Revision 32

  1. fix a mistake for function VAL() with negative values with exponent part.
  2. Some fine tuning for M2000 Editor and EditBox control when we click on parts of names with multiple parts separeted with dot (like aaa.bb.ccc.dd)
  3. Change the M2000.exe to start the M2000.dll if found it in the same folder, if there is no file with name M2000.vbp in the same folder, or no M2000.dll then m2000.exe expect the m2000.dll exist as a COM object on registry of Windows. (Experimental yet)

Version 13 Revision 31

  1. fix a mistake on validmove event of list control when the list is member of an array of lists.
  2. fix UseNoMove Method (mistake with greek letters inside name UseNoMove)
  3. FIELD now works also with string variable without suffix $.
  4. fix INPUT ! for text input on Array Items.

Version 13 Revision 30
Continue the work of revision 29 on select case
This example for case 4 we get

First "select" find case 4. But we have Break.
A break in the block on a block of a case means continue execute all cases until one block of a case execute Continue.
So "select" execute case 5 and case 6 which have continue, so skip case 7 (case else always if one case match the case)
A Break or a Continue or an Exit not using in a block on a case, goes to block which the select/end select exist..
So for this example if we place a REM before Continuw we get also the case 7
If we place a REM before break in case 4 we get only the 1. and no other case
if we place a second block or a statement and then a block we get error. After case we may have lines or a block. If you have lines but not in a block do not place loops For/While/Do. Place these on blocks only. The if statement can be used as one line statement or multilines using blocks: If then { multiline block } else { multiline block} etc.

select case 4
case 1
	? "not this"
case 2
	{
		' nothing
	}
case 4
	{
		? "1."
		break
	}
case 5
	? "2."
case 6
	{
		? "3."
		continue
	}
case 7
	? "not this too (1)"
case else
	? "not this too (2)"
end select

Version 13 Revision 29

  1. Fix select case for strings.
  2. Update Select case. Now we can use multiline strings literals. Before this release between two case statements we may have a line (using : to seperate statements) or a block. Now we can use more lines but not for loops or nested select cases, we have to use block of statements.

We get the second case...

select case {aa
}
case "k" to "z"
	print "no"
case >{a
}
	print "ok"
	print "------------"
case else
	print "line1"
	print "line2"
end select

previous (from version 10):

a$={aa
}
z$={a
}
select case a$
case "k" to "z"
	print "no"
case >z$   ' two statements in one line
	print "ok": print "------------"
case else
{ ' or using a block. Also here we may have nested select/case
	print "line1"
	print "line2"
}
end select
  1. Update GuiM20000 form. I have a mistake from revision 26, which not use enable property, so all controls get visible=true (which is not true for every case). So now fixed.
  2. Statement English and the same for Greek language now are colored as a statement (I have forgot to fix this).

Version 13 Revision 28
This was not an error but a lack of design:

To call a sub or a simple function before revision 28 the language for the definition at the first search was inferenced from the language of the name (checking the first letter). That works but some time you want to use f5 in editor to change names, so change a Greek name to an English one you will expect that code run as before, but not if the name you just replace is a sub's or simple function's name, because you have to alter the definition according to specific language of its identifier. So now this isn't a problem anymore. You can mix Greek/English.

After first search, the actual position recorded for subsequent call.

For modules/functions/lambda functions this was not a problem because the definition statement must be interpreted before the call. See here module testme {} is the definition and after this the testme is the call.

MODULE TESTME {
	ΑΛΦΑ()
	IF VERSION>13 OR (VERSION=13 AND REVISION>27) THEN ALFA()
	IF VERSION>13 OR (VERSION=13 AND REVISION>27) THEN ΑΛΦΑ1()
	ALFA1()
	? @ΑΛΦΑ()
	IF VERSION>13 OR (VERSION=13 AND REVISION>27) THEN ? @ALFA()
	IF VERSION>13 OR (VERSION=13 AND REVISION>27) THEN ? @ΑΛΦΑ1()
	? @ALFA1()
	
	' ΡΟΥΤΙΝΑ/ΡΟΥΤΊΝΑ/ΣΥΝΑΡΤΗΣΗ/ΣΥΝΆΡΤΗΣΗ/SUB/FUNCTION ALIAS END ..
	' IF ENCOUNTERED AS NEXT STATEMENT BY INTERPRETER.
	ΡΟΥΤΙΝΑ ΑΛΦΑ()
		? 100
	ΤΕΛΟΣ ΡΟΥΤΙΝΑΣ
	ΡΟΥΤΙΝΑ ALFA()  ' NOT FOUND <28 GREEK/ENGLISH
		? 100
	ΤΕΛΟΣ ΡΟΥΤΙΝΑΣ
	SUB ΑΛΦΑ1()  ' NOT FOUND <28 ENGLISH/GREEK
		? 100
	END SUB
	SUB ALFA1()
		? 100
	END SUB
	ΣΥΝΑΡΤΗΣΗ ΑΛΦΑ()
		=101
	ΤΕΛΟΣ ΣΥΝΑΡΤΗΣΗΣ
	ΣΥΝΑΡΤΗΣΗ ALFA()  ' NOT FOUND <28 GREEK/ENGLISH
		=101
	ΤΕΛΟΣ ΣΥΝΑΡΤΗΣΗΣ
	FUNCTION ΑΛΦΑ1()  ' NOT FOUND <28 ENGLISH/GREEK
		=101
	END FUNCTION
	FUNCTION ALFA1()
		=101
	END FUNCTION
}
TESTME

Version 13 Revision 27

  1. FIX THE INPUT STATEMENT FOR GREEK SETTINGS (NOW INPUT FOR DECIMAL NUMBERS WORK FINE.
    WE PRESS 12.12 AND WE SEE 12,12 AND THAT RETURN TO 12.12 AND INSERT TO A
    This was broken from revision 17
    There was no problem for locale 1033 (Default English)
    The Locale 1032 statememt set the Greek Locale, for M2000 the keyboard key "." return "," at the Input process for Input statement.
LOCALE 1032 
KEYBOARD "12.12", 13
INPUT A
PRINT A=12.12

The other input variants have no problem:

LOCALE 1032
A=12.12
' THIS INPUT VARIANT NOT USE THE SAME KEYBOARD BUFFER
' THIS USE A CONTROL OVER THE CONSOLE TO MIMIC THAT IS THE CONSOLE
' WE CAN'T PASS KEYS USING KEYBOARD STATEMENT BUT WE CAN STOP THE INPUT
' AFTER MAKE A THREAD WHICH START 200msec after and STOP the input.
' IF WE GIVE MORE TIME (2000 FOR 2 SECONDS) WE CAN CHANGE THE VALUE.
AFTER 200 {INPUT END}
INPUT ! A, 10  ' 10 IS THE WITDH IN CHARACTERS FOR THE CONTROL
PRINT A
PRINT A=12.12

For User forms the input control for numbers also have no problem.

  1. FIX FOR FORMLABEL STATEMENT - ALSO THE HELP FILE UPDATED FOR FORMLABEL.

Version 13 Revision 26

  1. List com to A ' export ProgID/CLSID for objects
  2. Enum with comments as memebers of Groups (added use of comments)
  3. DropList from control box on user form, now can
DECLARE Form1 FORM
METHOD Form1, "MakeInfo", -10
METHOD Form1, "MenuItem", "First", TRUE, idD:=500, acc:="A", ctrl:=TRUE
METHOD Form1, "MenuItem", ""
METHOD Form1, "MenuItem", "Second", TRUE, IdD:=1000, acc:="F1"
WITH Form1, "id" AS Who()
FUNCTION Form1.infoClick(NEW V) {
	SELECT CASE VAL(Who(V))
	CASE 500
		PRINT "First", V
	CASE 1000
		PRINT"Second", V
	END SELECT
	REFRESH
}
FUNCTION Form1.MouseDown {
	READ NEW key, shift, x, y
	IF key=2 AND shift=0 THEN		
		METHOD Form1, "OpenInfoAt",x, y	
	END IF
}
METHOD Form1,"SHOW" , 1
DECLARE Form1 NOTHING

Version 13 Revision 25
fix greek term for OBJECT (from english letters to greek letters).

Version 13 Revision 24
A bug removed, now Down4 module in info.gsb run as expected.
The problem was at com objects, when reading array of properties, with $ suffix (when then name of array changed to not include suffix $ all was ok)
Also removed some code not used for a long time.

Version 13 Revision 23
Two upgrades for Image control

  1. Image control now can be inside another image control.
  2. Image control process accelerator keys when we use it as frame for controls.

Upgraded the buttonsonframe module in info.gsb (we use there the two upgrades for image control)

Version 13 Revision 22
Last fix.
The lambda$ break from version 12 revision 50
Because the second form (lambda vs lambda$) used, which had no problem. Before some versions, a string expression had only strings literals or and string functions with $ suffix like Mid$(). The last versions can use string variables and functions without $ suffix (but a name with $ suffix is different with the same name without the $ suffix).

Dim A$(3)
A$(1)=lambda$ (a$,wd)->field$(a$, wd)
? "["+A$(1)("hello", 10)+"]"
link A$() to A()
' this works on revision 21
A(2)=lambda (a$,wd)->field$(a$, wd)
? "["+(A(2)("hello", 10))+"]"

Version 13 Revision 21

  1. Fix how names print for list of modules and variables.
    You can check List statement for variables and modules ? for modules/functions.
  2. Fix for list/queue/stack which use := for subs
    (break from Version 13 Revision 17).
    2.1
alfa(list:=1,2,3)
sub alfa(a as list)
	? a
end sub

2.2

a=list := 1,2,3,4,5
beta(a,"string", 1)
sub beta(o as list, v1 as variant, v2 as double)
	? o
end sub
  1. Added AS BIGINTEGER for CONST. Added AS CONST for parameters:
CONST P AS BIGINTEGER=-1232312323423423423334234U
ALFA1(P)
ALFA2(P)
SUB ALFA1(K AS BIGINTEGER)
	? K
	? TYPE$(K)="BigInteger"	
END SUB
SUB ALFA2(K AS CONST)
	? K
	? TYPE$(K)="Constant"
END SUB
  1. Now we can make also CONST tuples
CONST P=(1,2,3,4)
CONST A=P#MAT("+=", 500)
PRINT A#SUM()=2010
PRINT TYPE$(P)="Constant"
PRINT TYPE$(A)="Constant"
Z=P
PRINT TYPE$(Z)="tuple"
PRINT Z IS P=FALSE
Z++
PRINT Z#SUM()
PRINT P#VAL(3)=4
PRINT A#VAL(3)=504
PRINT Z#VAL(3)=5
  1. EVALUATOR module in info.gsb now run as expected.

Version 13 Revision 20
a FIX for EMF files.
On a Windows 11 laptop I found that the reference device - as stored in emf- has a bug from the OS, so I do my own calculation and now the emf has the size I want. The reference device cx/cy values used for adjusting the size, so my image before get a 1.75 bigger size, so my drawing drawing smaller at the top left corner. This happen when I choose to declare a bounding rectangle. The bounding rectangle saved ok on the original header but not on the emf file header (although the original header also included in the emf file).
So the fix in vb6 was:

'  VB6 code: copy of the header to mheader
CopyMemory ByVal VarPtr(mHeader.iType), ByVal aPic.GetBytePtr(0), 88
If boundrect.Bottom > 0 Then
' then if we have a boundrect we get the pixels (which are ok)
' and calculate the milliimeters which aren't ok (fort Windows 10 are slight different, but for Windows 11 on a laptop with 1920X1080 screen was very bad)
mHeader.szlMillimeters.cx = mHeader.szlDevice.cx * 15 / 1440 * 25.4
mHeader.szlMillimeters.cy = mHeader.szlDevice.cy * 15 / 1440 * 25.4
' restore the bytes...on memory buffer
CopyMemory ByVal aPic.GetBytePtr(0), ByVal VarPtr(mHeader.iType), 88
End If

Version 13 Revision 19

  1. Addition to operator IS TYPE the operator IS NOT TYPE

  2. Addition to operator IS the operator IS NOT

  3. User Forms: when we hide the form's minimize button, we get disabled the minimize label on contol menu. When the minimize button hide we have also hidden title at task bar. We can use this for modal forms as dialogs over another form.

  4. SOUNDREC as readonly variable return msec of recorded sound

The last version of M2000 Interpreter.

Greek Manual and the English one, have to change. So I exclude them from setup. From now on I change the old version with new one here.