Category:M2000 Interpreter: Difference between revisions

no edit summary
mNo edit summary
No edit summary
 
(22 intermediate revisions by 3 users not shown)
Line 1:
{{language|M2000 Interpreter
|exec=interpreted
|site=https://georgekarras.blogspot.com/}
|strength=both
|checking=dynamic
Line 8:
|compat=duck
|gc=allowed
|hopl=no
}}
M2000 is an interpreter running on its own Environment written in Visual Basic 6, as an open source project and can be findfound in GitHub[https://github.com/M2000Interpreter/Version9]. Current version is 9.4 and12, revision 2213. See [[M2000 Interpreter Implementation]]
{{language programming paradigm|Imperative}}
{{language programming paradigm|Object-oriented}}
Line 19 ⟶ 20:
 
 
M2000 start as an experimental interpreted language, using a Module in Module idea (like a Procedure in Procedure) where each inner Module is closed for modification, but open for expansion, by replacing code at run time. CodeSource code executed in one pass. Thereas is, awithout pre-passsecond to determine the major typeinterpretation of an expression, a numbersimple orform, aalthough string.block Lookof thiscode paradigm:arranged Wefor call inner Betaexecution in twoa stages.manner Atof theconsuming secondcode stage(code wewhich changeexecuted innerdeleted, Thetacode within Theta2.a Thisloop is the decoration of Beta with Thetakept as Theta2. This is a temporarycopy decorationfor becausenext Beta after execution erase any new identifier including Thetaiteration). So each time we call Beta, statement Module Theta make this module unless a decoration stop it.
 
==English Vocabulary==
Module's may be Global, or local to other modules. We can define global modules in a module, and all these definitions deleted at the end of module execution. Because we have to execute the definition of a module, we can select definition, or load definition before we call the module. Also modules can be part of object's of type Group. A module can't call itself unless we use Call module_name. The standard call is by using only the name of module. So from a module we can call local modules or global, but we can't call parent module (if isn't global). In a group we can call anything like a module plus the modules of the groups.
<lang >Module Beta {
 
We can change a inner module at the calling of a module, see the example: We call inner Beta in two stages. At the second stage we change inner Theta with Theta2. This is the decoration of Beta with Theta as Theta2. This is a temporary decoration because Beta after execution erase any new identifier including Theta. So each time we call Beta, statement Module Theta make this module unless a decoration stop it.
 
====English Vocabulary====
<syntaxhighlight lang="m2000 interpreter">Module Beta {
Module Theta (x){
Print "This is Theta, we get x=";x
Line 31 ⟶ 37:
Print "This is Theta2, we get x=";x
}
Beta ; Theta as Theta2</lang>
</syntaxhighlight>
==Greek Vocabulary==
====Greek Vocabulary====
<lang >Τμήμα Βήτα {
<syntaxhighlight lang="m2000 interpreter">Τμήμα Βήτα {
Τμήμα Θήτα (χ){
Τύπωσε "Αυτό είναι το Θήτα, θα πάρουμε το χ=";χ
Line 43 ⟶ 50:
Τύπωσε "Αυτό είναι το Θήτα2, θα πάρουμε το χ=";χ
}
Βήτα ; Θήτα ως Θήτα2</langsyntaxhighlight>
 
 
As we can see from code, some statements are like BASIC, except the use of curly brackets {}. Check the code below. We have a Module (as a Procedure), where we define some functions and some variables, as entities. These entities defined in every call to CheckIt, and erased when execution return from CheckIt. By default every parameter in M2000 pass by value. We define two functions, Alfa() where we set type for parameter x and ExpType$() where we not set type for x, and we wish to return the name of type when we make a call. Using DEF we can define variables and functions (in one line).
 
<syntaxhighlight lang="m2000 interpreter">Module CheckIt {
\\ We can't call something out of this module
Function Alfa(X as double) {
Line 55 ⟶ 62:
Print Alfa(5) ' we pass a double type number
Print Alfa(12121221121.1212@) ' we pass a Decimal type
\\ M get type from first assingmentassignment
M=Alfa(3)
Print Type$(M) ' Double
\\double Defz can create once// Znew (secondfrom timeversion raise error)12
Def Z as Double
\\ If a variable get a type then any number convert to that type before assign to it
Z=121212112.11212@
Print Type$(Z)
Def Currency Z1=212.12, Z2=323233.12, Z3=223212323323.12
Print Z1, Z2, Z3
Def ExpType$(x)=Type$(x)
Line 76 ⟶ 82:
\\ We call it
CheckIt
\\ Now FuntionFunction Alfa and all variables erased.
\\// We can call it again
CheckIt</langsyntaxhighlight>
 
 
For small programs, for learning algorithms there is no need to use types, except the major types, Numeric and StringStrings, plus one more: Integer. Integers can be number types like Long and Integer types, or can be any numeric type using without decimal part. So Integer variables are variables with % atsuffix the end ofon their name. String Variable needcan use a $ atsuffix. From version 12 we can use string variables without suffix. Although the endinterpreter ofown namestring functions use suffix $ (like str$()).
 
For Expressions before execution automatic check by names if the result can be for strings names, or for numeric names. A string name has $ at the end of name. Maybe a string name isn't a string, because with same name we can define groups which get or and return strings values. A statement Input Alfa$ can input characters for a string or for object typed group with that name. Interpreter implicitly use the appropriate method. If name has no $ at the end then this can be an object or a numeric value. A Input Beta may return error if Beta has no numeric value to set.
 
Types are strong for values with a name (variables, constants), but weak for items in containers. In a container (Array, Inventory and Stack) we can place anything including other containers. We can bypass the "strong" capability but this isn't a practice for good programming. Internal or variables are of type of Variant, so we can make a reference of A to A$ and we can save a string "1212" and read from A the number 1212.
 
<syntaxhighlight lang="m2000 interpreter">
<lang >
Module AKindOfMess {
a=10@
Line 95 ⟶ 101:
Print a$
Let a$=str$(500.12, "")
Rem : a++ ' error can't aplyapply ++ to a string type
Print type$(a)="String" ' true
' Error a=a+a
Line 122 ⟶ 128:
Print Valid(12/0)=false ' evaluate expression and return true if is ok (errors trapped always)
Print Error$=""
</syntaxhighlight>
 
</lang>
 
So check this for proper use of types.
 
<syntaxhighlight lang="m2000 interpreter">Module CheckInt {
A%=1212212.12@
Print A% ' 1212212
Line 143 ⟶ 148:
Print B% ' 122121213
}
CheckInt</langsyntaxhighlight>
 
So we say about Integer Variables, and no Integer Numeric Type. Like in Basic, M2000 is not case sensitive (except for labels), so A% and a% is the same. We may have A, A$ and A% as three variables, or A(), A%(), A$() as arrays or and functions. We can use name(@ ) to call function and not array if we have each with same name.
 
<syntaxhighlight lang="m2000 interpreter">Dim A(10)=1
Def A(x)=x**2
Print A(3), A(@ 4)</langsyntaxhighlight>
 
 
Line 166 ⟶ 171:
As we see alfa has no read statement, because before get the first number need to make two modules, and then pop one number and call a module passing current stack, so if choose beta, then the second value feed y from a read y statement.
 
<syntaxhighlight lang="m2000 interpreter">
<lang >
module alfa {
module beta (y) {
Line 189 ⟶ 194:
}
print sumall(1,2,3,4,5,6,7)=28
</syntaxhighlight>
</lang >
 
 
Line 199 ⟶ 204:
 
 
<syntaxhighlight lang="m2000 interpreter">Module Delta {
\\ Make a group like a lambda
\\ A Class make a Global Function
Line 233 ⟶ 238:
Print Type$(P) ="Group"
}
Delta</langsyntaxhighlight>
 
 
We can place a lambda function as closure in a lambda function, and we can build a program as one "top" function, and many lambda as closures, which may have other lambda functions. Closures can be change values from lambda but not from outside unless they are pointers (so we may have same pointers outside of lambda, or in another lambda. A lambda variable can change function and closures in a new assignment. We can store lambda state (if we don't use pointers in closures) in a new variable which take as first value lambda (and then can take only lambda functions)
 
 
a class define a type too. We can make a class from other classes too. We can make inner classes too.
<syntaxhighlight lang="m2000 interpreter">
Form 80,50
\\ counters supposed we provide them from a file
global LastCustomerId=100, ReportId=80
\\
class person {
Private:
name$, address$, phone$, id
class:
module person (.name$, .address$, .phone$) {
LastCustomerId++
.id<=LastCustomerId
}
}
 
class customer as person {
Inventory sales
Class bill {
Private:
day$, time$, id
Public:
\\ read only property (is a group inside group)
Property euro {value}
Function Key$ {
=.day$+"/"+.time$+"#"+str$(.id,"")
}
class:
Module bill (.day$, .time$, .id, .[euro]) {
}
}
Module CustomerData {
ReportId++
Print "Report date:"; Date$(Today)
Print "ReportId:";ReportId
Print "Customer:";.id
Print "Name",.name$
Print "Address",.address$
Print "Phone", .phone$
Print "Transactions:";len(.sales)
m=each(.sales)
sum=0
While m {
bill=eval(m)
sum+=bill.euro
}
Print "Total Euro:";sum
}
Module InsertBill (bill as bill) {
try {
Print "New bill:";bill.key$();" for customer ";.id
Append .sales, bill.key$():=bill
}
}
Class:
Module customer (Where, m as person) {
this<=m
append where, .id:=This
}
}
 
Inventory Customers
Pen 15 {Print "Adding to Customers"}
For This {
\\ this is a block for temporary definitions
K=Customer(Customers, person("George","Athens","0912399"))
K.CustomerData
\\ after that group K deleted
}
Pen 15 {Print "Using key to customers to add bills"}
For Customers(LastCustomerId) {
.InsertBill .bill("20200522", "18:33", 1023, 100)
.InsertBill .bill("20200526", "09:10", 3129, 150)
.InsertBill .bill("20200530", "13:20", 5418, 25)
.CustomerData
}
Pen 15 {Print "Using Iterator 1 - working at original data"}
M=each(Customers)
While M {
\\ we extract key using eval$(M!)
\\ so we can work from original data
For Customers(eval$(M!)) {
.CustomerData
}
}
Pen 15 {Print "Using Iterator 2 - working at a copy of data"}
M=each(Customers)
While M {
\\ or using a copy of data
K=Eval(M)
For K {
.CustomerData
}
}
</syntaxhighlight>
 
 
Until now we see modules/functions/subs for procedural programming, Groups for OOP, Groups as lambda functions and lambda functions for functional programming. We can use events for groups and for COM objects, including GUI objects.
 
<syntaxhighlight lang="m2000 interpreter">Module Beta {
Group WithEvents Alpha {
Event "One"
Line 270 ⟶ 373:
Print M=111
}
Beta</langsyntaxhighlight>
 
 
Line 278 ⟶ 381:
Modules may have Threads, part of modules that can be executed in intervals, can be halted, or can be released, and can be erased. Each thread has own stack and may have own static variables (Modules and Functions also may have static variables), but can use modules variables and functions/modules/subs. Threads can run concurrent (thread return to task manager after execution of a statement or a block of statements) or sequential (a thread has to exit from interval to start other thread)
 
<syntaxhighlight lang="m2000 interpreter">Module Zeta {
k=10
Thread {
Line 286 ⟶ 389:
Main.Task 100 {
Print k
Refresh // new versions do not insert automatic refresh for output in threads, we have to include it to code
If keypress(32) then Exit
}
}
Zeta</langsyntaxhighlight>
 
 
Line 296 ⟶ 400:
 
 
<syntaxhighlight lang="m2000 interpreter">Module Kappa {
Function Theta(x) {
Structure Points_single {
Line 312 ⟶ 416:
Print Eval(P, 0!x)=1212.12~, Eval(P, 0!y)=21.1212~
}
Kappa</langsyntaxhighlight>
404

edits