Πέμπτη 8 Μαρτίου 2018

Αναθεώρηση 54, Έκδοση 9.0 - Currency Type

Σε αυτήν την αναθεώρηση έβαλα το Currency, και τώρα μαζί με το Decimal, η Μ2000 έχει τους καλύτερους τύπους για πράξεις.
Ρύθμισα και την Στρογγ() ή Round() για να επιστρέφει τον ίδιο τύπο.
Σε αριθμούς βάζουμε το @ για Decimal, # για Currency, & για Long
Το αποτέλεσμα των υπολογισμών μπορεί να βγει σε άλλο τύπο αν δεν μπορεί να βγει αλλιώς αποτέλεσμα.
Παρακάτω είναι ένα πρόγραμμα επίδειξης των νέων δυνατοτήτων της γλώσσας.

Στο πρόγραμμα κάνω πολλαπλασιασμό για να βγει υπερχείλιση. Στους Long (Μακρύς) θα βγει λάθος όπως και να έχει. Στους Decimal και Currency θα γίνει μετατροπή σε Double.



Bold 0
Form 80, 55
Cls 5 : Pen 14
Const CenterJustify=2
Double : Bold
Report CenterJustify, "Demo for using numeric types in M2000 programming language"
Normal : Bold
Print
Print $(4, 20),  \\ 20 char width - using proportional printing
Print "Decimal, Currency, Long:", 112212321231231231323@, 23432432434234.32#, 44554&
Long A
A=100
Print Type$(A) ' long
B=A
Print Type$(B) ' New if 54
\\ Long variables stay Long
Z=123123
Print Z
Print Type$(Z) ' double
Z=21321.1532131231232132@
Print Z
Z1=Round(Z, 1)
Print Type$(Z) ' Decimal
Print Z1
Print Type$(Z1) ' Decimal

Z=2321213133.25#
Print Z
Z1=Round(Z, 1)
Print Type$(Z) ' Currency
Print Z1
Print Type$(Z1) ' Currency
Bold
Report CenterJustify, "Array fill with a value of some type"
Bold
Dim A(10)=0@
Print "Array Item Type:";Type$(A(3)), ' Decimal
Dim A(10)=0&
Print "Array Item Type:"; Type$(A(3)),  ' Long
Dim A(10)=0#
Print "Array Item Type:"; Type$(A(3)),  ' Currency
Dim A(10)=0
Print "Array Item Type:"; Type$(A(3)),  ' Double
Bold
Report CenterJustify, "For Loops with Decimal, Currency, Long"
Bold
\\For  loop with Decimal
N=Row
For i=12312122121212212.1212@ to 12312122121212222.1212@ step 2 {
      Print i, " "+type$(i)
}
Cursor 0, N
\\For  loop with Currency
For i=1231212.12# to 1231222.12# step 2 {
      Print @(Tab(1)), i, " "+type$(i)
}
Cursor 0, N
\\For  loop with Long  (need to declare i as long)
\\ using Long or using i=0&
Long i
For i=1231212& to 1231222& step 2 {
      Print @(Tab(2)), i, " "+type$(i)
}
Bold
Report CenterJustify, "Overflow control for Long type"
Bold
Try {
      i=1212112112122 ' Long can't converted
}
Print "Report Error"+Error$ ' overflow long
Report CenterJustify, "Auto convertion for types to double, on overflow"
Z=3223423424423423423@
Print "Try on:"; Type$(Z), Z;"@*";"5000000000000000@"  ' Decimal
Z*=5000000000000000@ ' overflow bur converted to double
Print "Result:"; Type$(Z) , Z ' Double
Z=32234234212244.23#
Print "Try on:"; Type$(Z), Z;"#*";"5000000000000000@"  ' Currency
Z*=5000000000000000@ ' overflow bur converted to double
Print "Result:"; Type$(Z) , Z ' Double

\\ Integers from Decimal and Currency
A%=-12313123123123.52123123213123@
Print A%
Print Type$(A%) ' Decimal but hold only Integer value
A%=-123131231223.52#
Print A%
Print Type$(A%) 'Currency but hold only Integer value
A%=-121212121212121.5212
Print A%
Print Type$(A%) 'Double but hold only Integer value
A%=1212121&
Print A%
Print Type$(A%) 'Double  - can't take long

Module aName {
      Read A, B, C, D
      \\ Center to tab
      Pen 11 {
            Print Part $(6),Type$(A), Type$(B), Type$(C), Type$(D)
      }
      Print
}
aName 1000&, 638716387681736@, 8764873287.34#, 3478239744
Let A1=1000&, A2=638716387681736@, A3=8764873287.34#, A4=3478239744
aName A1, A2, A3, A4
aName ! (1000&, 638716387681736@, 8764873287.34#, 3478239744)
A=(1000&, 638716387681736@, 8764873287.34#, 3478239744)
Print "A is ";Type$(A);" type, a pointer to Array. We can add 20 to all items in a single statement"
Print A
A+=20& ' Add to all  numeric items a long  value
Print A ' so first long stay long
aName ! A \\ pass all values to aName module
A+=10000000000000000@
Print A
aName ! A
\\ Constants are objects.
Const K=121212212121211121212.121@
Print K, Type$(K) ' say Constant
M=K
Print M, Type$(M) ' say Decimal
Try {
      K++
}
Print "Report Error "+Error$
Print Key$ ' wait for a key




Αναθεώρηση 52 (Έκδοση 9.0)

Σε αυτή την αναθεώρηση έγινε αρκετή δουλειά για να μπουν οι αριθμοί τύπου Decimal με 29 ψηφία και κινητή υποδιαστολή.

 
Τοπικό 1033
Α=123123123213123213@
Τύπωσε Α, Α*2, Α*15
Τύπωσε Τύπος$(Α) \\ Decimal
Για ι= 123123123213123213@ έως 123123123213123213@+10 {
      Τύπωσε ι
}
\\ και οι ακέραιοι μπορούν να γίνουν
Α%=64563423412343@/2
Τύπωσε Α%, "???"
Α%=11@/2
Τύπωσε Α% ' δίνει 6  γιατί το 5.5 το κάνει 6
Α%=-11@/2
Τύπωσε Α% ' δίνει -6  γιατί το -5.5 το κάνει -6
Τύπωσε Τύπος$(Α%) ' decimal


Επιπλέον έχουμε νέο Demo με τα Vectors σε παράθυρο και με νήματα, άλλο να αλλάζει τις τιμές και άλλο να προβάλει την εικόνα.

Στο βίντεο είναι από δεύτερη οθόνη σε Linux, όπου παράλληλα τρέχουν σε VirtualBox τα Windows 7 και τρέχει το ίδιο πρόγραμμα στα 7 και στο Linux. Δείτε ότι τα παράθυρα που φτιάχνει η Μ2000 είναι ίδια και στα δυο λειτουργικά. Αυτό ισχύει και σε κάθε λειτουργικό που τρέχει, από Xp έως και 10, καθώς και με το Wine 1.8 σε Linux.





Demo1



Rem : Thread.plan sequential
\\ we can set Thread.plan before any thread created
Rem :
Thread.plan concurrent
\\ concurrent execute one by one statements
\\ except those in { }
\\ also from Revision 52 Part {} as variable works fine with it
local counter1, counter2
  Title "3D Graphics", 0 ' 0  to hide console
Set FAST !
\\ by api
Structure VecType {
          x As Double
          y As Double
          z As Double
}
\\ Program
Structure Variables {
      vRot1 As VecType
      vRot2 As VecType
      vRot3 As VecType
      vRot4 As VecType
      vBase As VecType
      vAxis As VecType
}
Buffer Clear Var As Variables
\\ utility function
VecAdr=Lambda Var (a$) -> {
      =Var(0,a$)
}
VecOff=Lambda Var, VecType (a$, b$) -> {
      =Var(0, a$, VecType(b$)!)
}
Class cLine {
      X1, Y1, X2, Y2, color
      Module Render {
            ' read Number from stack
            z=Round(Number,4)
            z1=Round(Number, 4)
            If z>=z1 Then {
                  Move .X1, .Y1
                  Width 3 {Draw to .X2, .Y2, .color}
                  Circle Fill #aa33cc, z/40+200
            } Else {
                  Move .X2, .Y2
                  Circle Fill #aa33cc, z/40+200
                  Width 3 {Draw to .X1, .Y1, .color}
            }
      }
Class:
      Module cLine (.color){
            If Match("NNNN") Then Read .X1, .Y1, .X2, .Y2
      }     
}

\\ find address
vBase=VecAdr("vBase")
vBase.x=VecOff("vBase","x")
vBase.y=VecOff("vBase","y")
vBase.z=VecOff("vBase","z")
vRot1=VecAdr("vRot1")
vRot1.x=VecOff("vRot1","x")
vRot1.y=VecOff("vRot1","y")
vRot1.z=VecOff("vRot1","z")
vRot2=VecAdr("vRot2")
vRot2.x=VecOff("vRot2","x")
vRot2.y=VecOff("vRot2","y")
vRot2.z=VecOff("vRot2","z")
vRot3=VecAdr("vRot3")
vRot3.x=VecOff("vRot3","x")
vRot3.y=VecOff("vRot3","y")
vRot3.z=VecOff("vRot3","z")
vRot4=VecAdr("vRot4")
vRot4.x=VecOff("vRot4","x")
vRot4.y=VecOff("vRot4","y")
vRot4.z=VecOff("vRot4","z")
vAxis=VecAdr("vAxis")

Form 80,40
Refresh 300
Declare Alfa Form
With Alfa, "Title", "Demo1"
\\ a string to hold static background
screen$=""
disp=False
Inventory Depth
aLine=Each(Depth)
once=False
Thread {
      part {
                  Method Math, "RotVectMult", 4, vRot1, vAxis, vRot1, dAngle
                  Push Eval(Var, vBase.y As double), Eval(Var, vBase.x As double)
                  \\ x is in top, y is after x
                  Over 2, 2 \\  copy two times from second, so double two top
                  Push Eval(Var, vRot4.x As double)+Number : Over 1, 2 \\ copy 2 times top only
                        Read Line1.X1, Line2.X1, Line3.X1
                        Push Eval(Var, vRot4.y As double)+Number : Over 1, 2
                        Read Line1.Y1, Line2.Y1, Line3.Y1
                        Over 2, 4 \\ now original 2 values copied 4 times
                        Line1.X2 = Eval(Var, vRot1.x As double)+Number
                        Line1.Y2 = Eval(Var, vRot1.y As double)+Number
                        Line2.X2 = Eval(Var, vRot2.x As double)+Number
                        Line2.Y2 = Eval(Var, vRot2.y As double)+Number
                        Line3.X2 = Eval(Var, vRot3.x As double)+Number
                        Line3.Y2 = Eval(Var, vRot3.y As double)+Number
                        DepthSort()
                        counter1++
      }  As once
} As Compute
Group All$ {
Private:
      Dim Base 1, A$(3)
Public:
      n=1
      Set (.n) {
            read .A$(.n)
      }
      Value {
            =.A$(.n)
      }
}
Layer Alfa {
      Window 12, 10000, 8000;
      Form 40, 20
      Line1=cline(#0000FF, scale.x/2, scale.y/2, scale.x/2, scale.y/2-2220 )
      Line2=cline(#FF0000, scale.x/2, scale.y/2, scale.x/2-2340, scale.y/2-60 )
      Line3=cline(#00FF00, scale.x/2, scale.y/2, scale.x/2-780, scale.y/2-1200 )
      All$(1)=Weak$(Line1.Render)
      All$(2)=Weak$(Line2.Render)
      All$(3)=Weak$(Line3.Render)
      Declare Math Math
      Method Math, "Vector", vBase,scale.x/2-1500, scale.y/2+1500, 1500 '  -1000
      Method Math, "Vector", vRot1, Line1.X2, Line1.Y2, -1000
      Method Math, "Vector", vRot2, Line2.X2, Line2.Y2, -1200
      Method Math, "Vector", vRot3, Line3.X2, Line3.Y2, 1700
      Method Math, "Vector", vRot4, Line1.X1, Line1.Y1, 0
      Method Math,  "VecDiffMult", 4, vRot1, vBase, vRot1
      Inventory Depth=Eval(Var, vRot1.z As double):=1, Eval(Var, vRot2.z As double):=2, Eval(Var, vRot3.z As double):=3
      Sort Depth As number
      Method Math, "Vector", vAxis, -.8, 1.6, .3
      Method Math, "UnitVect", vAxis
      Rad2Deg =Lambda pidivby180=pi/180 (RadAngle)->RadAngle / pidivby180
      dAngle =5
      Pen 0
      Cls 7
      Gradient 11, 13
      Move 0,0
      Cursor 0, Height-1
      Cls 7, Height-1
      Copy scale.x, scale.y to screen$
      Cursor 0,Height
      together=False
      ok1=true
      Thread {
            ok1~
      } as mm interval 1000/25
      tm=0
      Thread {
            static internal=1
            Refresh 0
            Move 0,0
            Copy 0,0 use screen$
            Part {
                  tm=timecount
            } as ok1
                  Print @(3,3); Round(tm,2)
                  Cursor 0,height-1

            Part {
                       Part {
                        aLine=Each(Depth)
                        push Eval(Var, vRot4.z As double) : Over 1, 2
                        while aline {
                                    All.n=eval(aLine)
                                    Call All$, Val(eval$(Depth, aLine^))
                        }
                        counter2++
                        } As disp
                   Print Part $(5,Width/4), counter1, counter2,internal, $(7),Str$(Now , "hh:mm:ss" )
                   Refresh ' execute together
            }  As together
            internal++
            Profiler
      } As PlayThis
}
\\ we set vatiables outside threads
State=False
blinking=False
Thread {
       If state Then disp~
} As blink
Thread blink Hold
ExitNow=False
Function Alfa.Unload {
      ExitNow=True
      threads erase
}
Function Alfa.Click {
                  State~
                  If State Then {
                         Thread compute Hold
                         Thread blink interval 1000/4
                         Thread blink Restart
                         blinking=true
                  } Else {
                        disp=False
                        If blinking Then Thread blink Hold : blinking~
                        Thread compute Restart
                  }
}
Thread PlayThis interval 1000/60
Thread compute interval 20
Wait 200
Method Alfa, "Show"
\\ Chane Task.Main with Every
\\ Task.Main is a Thread
\\ ExitNow needed If we have Every in place of Task.Main
Task.Main 50 {
\\      If counter1>1000 Then Threads Erase : Exit
      If ExitNow Then Exit
}
Threads Erase
Wait 100 \ some delay here
Method Alfa, "CloseNow"
Declare Alfa Nothing
Declare Math Nothing
Print counter1, counter2
Sub DepthSort()
             Inventory Queue Depth ' clear Depth, Then make keys As numbers
             Append Depth, Eval(Var, vRot1.z As double):=1, Eval(Var, vRot2.z As double):=2, Eval(Var, vRot3.z As double):=3
             Sort Depth As number
End Sub



The above code using pointers to groups, change statements with Yellow color. Group All$ change with an array All(). So we make All() array to hold pointers to lines. With green color is the statement to use GDI+ for antialiasing on lines, polygons, curves etc.



smooth on
Rem : 
Thread.plan sequential
\\ we can set Thread.plan before any thread created
Rem :  Thread.plan concurrent
\\ concurrent execute one by one statements
\\ except those in { }
\\ also from Revision 52 Part {} as variable works fine with it
local counter1, counter2
  Title "", 0 ' 0  to hide console
Set FAST !
\\ by api
Structure VecType {
          x As Double
          y As Double
          z As Double
}
\\ Program
Structure Variables {
      vRot1 As VecType
      vRot2 As VecType
      vRot3 As VecType
      vRot4 As VecType
      vBase As VecType
      vAxis As VecType
}
Buffer Clear Var As Variables
\\ utility function
VecAdr=Lambda Var (a$) -> {
      =Var(0,a$)
}
VecOff=Lambda Var, VecType (a$, b$) -> {
      =Var(0, a$, VecType(b$)!)
}
Class cLine {
      X1, Y1, X2, Y2, color
      Module Render {
            ' read Number from stack
            z=Round(Number,4)
            z1=Round(Number, 4)
            If z>=z1 Then {
                  Move .X1, .Y1
                  Width 3 {Draw to .X2, .Y2, .color}
                  Circle Fill #aa33cc, z/40+200
            } Else {
                  Move .X2, .Y2
                  Circle Fill #aa33cc, z/40+200
                  Width 3 {Draw to .X1, .Y1, .color}
            }
      }
Class:
      Module cLine (.color){
            If Match("NNNN") Then Read .X1, .Y1, .X2, .Y2
      }    
}

\\ find address
vBase=VecAdr("vBase")
vBase.x=VecOff("vBase","x")
vBase.y=VecOff("vBase","y")
vBase.z=VecOff("vBase","z")
vRot1=VecAdr("vRot1")
vRot1.x=VecOff("vRot1","x")
vRot1.y=VecOff("vRot1","y")
vRot1.z=VecOff("vRot1","z")
vRot2=VecAdr("vRot2")
vRot2.x=VecOff("vRot2","x")
vRot2.y=VecOff("vRot2","y")
vRot2.z=VecOff("vRot2","z")
vRot3=VecAdr("vRot3")
vRot3.x=VecOff("vRot3","x")
vRot3.y=VecOff("vRot3","y")
vRot3.z=VecOff("vRot3","z")
vRot4=VecAdr("vRot4")
vRot4.x=VecOff("vRot4","x")
vRot4.y=VecOff("vRot4","y")
vRot4.z=VecOff("vRot4","z")
vAxis=VecAdr("vAxis")

Form 80,40
Refresh 300
Declare Alfa Form
With Alfa, "Title", "Demo1"
\\ a string to hold static background
screen$=""
disp=False
Inventory Depth
aLine=Each(Depth)
once=False
Function DepthSort() {
                   Inventory Queue Depth ' clear Depth, Then make keys As numbers
                   Append Depth, Eval(Var, vRot1.z As double):=1, Eval(Var, vRot2.z As double):=2, Eval(Var, vRot3.z As double):=3
                   Sort Depth As number
}
Thread {
      part {
                  Method Math, "RotVectMult", 4, vRot1, vAxis, vRot1, dAngle
                  Push Eval(Var, vBase.y As double), Eval(Var, vBase.x As double)
                  \\ x is in top, y is after x
                  Over 2, 2 \\  copy two times from second, so double two top
                  Push Eval(Var, vRot4.x As double)+Number : Over 1, 2 \\ copy 2 times top only
                        Read Line1.X1, Line2.X1, Line3.X1
                        Push Eval(Var, vRot4.y As double)+Number : Over 1, 2
                        Read Line1.Y1, Line2.Y1, Line3.Y1
                        Over 2, 4 \\ now original 2 values copied 4 times
                        Line1.X2 = Eval(Var, vRot1.x As double)+Number
                        Line1.Y2 = Eval(Var, vRot1.y As double)+Number
                        Line2.X2 = Eval(Var, vRot2.x As double)+Number
                        Line2.Y2 = Eval(Var, vRot2.y As double)+Number
                        Line3.X2 = Eval(Var, vRot3.x As double)+Number
                        Line3.Y2 = Eval(Var, vRot3.y As double)+Number
                        call local depthsort()
                        counter1++
      }  As once
} As Compute
dim All(1 to 3)
Layer Alfa {
      Window 12, 10000, 8000;
      Form 40, 20
      Line1=cline(#0000FF, scale.x/2, scale.y/2, scale.x/2, scale.y/2-2220 )
      Line2=cline(#FF0000, scale.x/2, scale.y/2, scale.x/2-2340, scale.y/2-60 )
      Line3=cline(#00FF00, scale.x/2, scale.y/2, scale.x/2-780, scale.y/2-1200 )
      All(1)->Line1
      All(2)->line2
      All(3)->line3

      Declare Math Math
      Method Math, "Vector", vBase,scale.x/2-1500, scale.y/2+1500, 1500 '  -1000
      Method Math, "Vector", vRot1, Line1.X2, Line1.Y2, -1000
      Method Math, "Vector", vRot2, Line2.X2, Line2.Y2, -1200
      Method Math, "Vector", vRot3, Line3.X2, Line3.Y2, 1700
      Method Math, "Vector", vRot4, Line1.X1, Line1.Y1, 0
      Method Math,  "VecDiffMult", 4, vRot1, vBase, vRot1
      Inventory Depth=Eval(Var, vRot1.z As double):=1, Eval(Var, vRot2.z As double):=2, Eval(Var, vRot3.z As double):=3
      Sort Depth As number
      Method Math, "Vector", vAxis, -.8, 1.6, .3
      Method Math, "UnitVect", vAxis
      Rad2Deg =Lambda pidivby180=pi/180 (RadAngle)->RadAngle / pidivby180
      dAngle =5
      Pen 0
      Cls 7
      Gradient 11, 13
      Move 0,0
      Cursor 0, Height-1
      Cls 7, Height-1
      Copy scale.x, scale.y to screen$
      Cursor 0,Height
      together=False
      ok1=true
      Thread {
            ok1~
      } as mm interval 1000/25
      tm=0
      Thread {
            static internal=1
            Refresh 0
            Move 0,0
            Copy 0,0 use screen$
            Part {
                  tm=timecount
            } as ok1
                  Print @(3,3); Round(tm,2)
                  Cursor 0,height-1

            Part {
                       Part {
                        aLine=Each(Depth)
                        push  Eval(Var, vRot4.z As double) : Over 1, 2
                        while aline {
                                    pp=all(eval(aLine))
                                    pp=>render  Val(eval$(Depth, aLine^))

                        }
                        counter2++
                        } As disp
                   Print Part $(5,Width/4), counter1, counter2,internal, $(7),Str$(Now , "hh:mm:ss" )
                  Refresh ' execute together
            }  As together
            internal++
            Profiler
      } As PlayThis
}
\\ we set vatiables outside threads
State=False
blinking=False
Thread {
       If state Then disp~
 } As blink
Thread blink Hold
ExitNow=False
Function Alfa.Unload {
      ExitNow=True
      threads erase
}
Function Alfa.Click {
                  State~
                  If State Then {
                         Thread compute Hold
                         Thread blink interval 1000/4
                         Thread blink Restart
                         blinking=true
                  } Else {
                        disp=False
                        If blinking Then Thread blink  Hold : blinking~
                        Thread compute Restart
                  }
}
Thread PlayThis interval 1000/60
Thread compute interval 20
Wait 200
Method Alfa, "Show"
\\ Change Task.Main with Every
\\ Task.Main is a Thread
\\ ExitNow needed If we have Every in place of Task.Main
Task.Main 50 {
\\      If counter1>1000 Then Threads Erase : Exit
      If ExitNow Then Exit
}
Threads Erase
Wait 100  \ some delay here
Method Alfa, "CloseNow"
Declare Alfa Nothing
Declare Math Nothing
Print counter1, counter2