638 lines
10 KiB
Plaintext
638 lines
10 KiB
Plaintext
|
|
/*
|
|
* Multi-Process within a single threaded-process.
|
|
* How to embed in a single threaded web server
|
|
*
|
|
*
|
|
* moo_exec
|
|
* VM(shceduler) ---> Context1(obj1,method1)
|
|
* ---> Context2(obj2,method2)
|
|
* ---> Context3(obj3,method3)
|
|
*
|
|
* all functions must be asynchronous
|
|
* blocking functions will block scheduler.
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
class Stix::Stix # Namespace name is indicated by ::
|
|
{
|
|
}
|
|
|
|
class Stix::Array
|
|
{
|
|
+ makeSymbol: aString
|
|
{
|
|
| s |
|
|
|
|
s := Symbol new: aString. # Symbol belongs to the Stix namespace.
|
|
^s.
|
|
}
|
|
}
|
|
|
|
|
|
A name space is stored in the namespace table of Stix.Namespaces.
|
|
|
|
|
|
Stix.Symbols - symbols are global. not affected by namespaces.
|
|
Stix.Sysdict -
|
|
(#QSE => Namespace( Another Sysdict))
|
|
(
|
|
|
|
class Stix::Namespace
|
|
{
|
|
}
|
|
|
|
class Stix::Class
|
|
{
|
|
}
|
|
|
|
Stix.Namespaces is a system dictionary
|
|
|
|
class QSE::Array
|
|
{
|
|
}
|
|
|
|
class QSE::Tiara::Array
|
|
{
|
|
|
|
}
|
|
|
|
|
|
Stix.Namespaces -> 'QSE'
|
|
'QSE::Tiara'
|
|
|
|
|
|
|
|
------------------------------------------------------------
|
|
|
|
ARRAY CONSTANT TO ALLOW DYNAMIC VALUES.
|
|
|
|
#( ...... ) array literal
|
|
in original smalltalk, a block can't be placed inside the array literal
|
|
arrayConstant := '#' array
|
|
array := "(" { number | string | symbol | array | characterConstant }* ")".
|
|
So #(1 2 [^20]) is illegal.
|
|
|
|
if a block is there, treat it as a valid moo expression and evaluate it.
|
|
|
|
#(1 2 [1 + 2] 5)
|
|
t = Array new: 4.
|
|
t at: 1 put: 1.
|
|
t at: 2 put: 2.
|
|
t at: 3 put: (1 + 2).
|
|
t at: 4 put: 5.
|
|
|
|
Evaluate the expressions in the array first
|
|
Create an array
|
|
Put the right element.
|
|
|
|
-----------------------------------------------
|
|
command line
|
|
|
|
libmoo.a
|
|
|
|
moo moo.im Class1.st Class2.st Main.st Main
|
|
--> load the image, compile Class1.st, compile Class2.st compile Main.st
|
|
-->
|
|
|
|
|
|
moo moo.im
|
|
--> load the image
|
|
|
|
-------------------------------------------------------------------------
|
|
|
|
#!/usr/bin/moo
|
|
|
|
###################################
|
|
## Main.st
|
|
###################################
|
|
|
|
#include 'Class1.st'
|
|
#include 'Class2.st'
|
|
|
|
#class(#byte) Association(Magnitude)
|
|
{
|
|
declare a, b, c.
|
|
declare(#classinst) x.
|
|
declare(#class) MAX_SIZE.
|
|
|
|
function(#class) initialize
|
|
{
|
|
MAX_SIZE := 20.
|
|
|
|
true whileTrue: [
|
|
Stdout print: 10.
|
|
].
|
|
}
|
|
|
|
function(#class) new: anInteger
|
|
{
|
|
Stix error: 'invalid message'.
|
|
}
|
|
}
|
|
|
|
#main
|
|
| a |
|
|
|
|
a := Class1 new.
|
|
Stdout format: #( 1 2 [a toInteger] ) with: '%.5d %.6d\n'.
|
|
^0.
|
|
|
|
-------------------------------------------------------------------------
|
|
The statements after the #main directives are compiled as a class method of Stix.
|
|
That is, 'Stix::main'. It becomes the entry point.
|
|
|
|
-------------------------------------------------------------------------
|
|
|
|
If no #main directive is found, there is no official entry point.
|
|
However, if you have the initialize class method, it's invoked when a class
|
|
is compiled, the statement in the class is executed before #main.
|
|
if the statement creates a certain loop, it can act as a entry point as well.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
Top level directive
|
|
#main, #class, #include,
|
|
|
|
#include is avaialble everywheren. It doesn't have to be in the top level.
|
|
Do i need #import?
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
if there are multiple #main, do i need to concatenate all?
|
|
or disallow only 1 #main??
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
#namespace directive?
|
|
|
|
#namespace Stix::Compiler
|
|
|
|
naming convention for multiple ?? . conflicts with the statement terminator.
|
|
:: is ok a single : is used for various purpose but more than 1 is illegal in smalltalk.
|
|
so use :: as a namespace separator.
|
|
|
|
|
|
Relative naming and absoluate naming?
|
|
Stix::Compiler <- is Stix the absolute top or a subname class under the current space?
|
|
::Stix::Compiler <- i don't like this
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"
|
|
Stix
|
|
Class
|
|
NilObject
|
|
Object
|
|
NilObject
|
|
Collection
|
|
IndexedCollection
|
|
FixedSizedCollection
|
|
Array
|
|
ByteArray
|
|
String
|
|
Symbol
|
|
Set
|
|
Dictionary
|
|
SystemDictionary
|
|
SymbolSet
|
|
Magnitude
|
|
Association
|
|
Character
|
|
Number
|
|
Integer
|
|
SmallInteger
|
|
LargeInteger
|
|
"
|
|
|
|
|
|
class Stix
|
|
{
|
|
|
|
|
|
+ alloc
|
|
{
|
|
<primitive: 1>
|
|
}
|
|
|
|
+ new
|
|
{
|
|
^self alloc init.
|
|
}
|
|
|
|
- init
|
|
{
|
|
^self.
|
|
}
|
|
|
|
- finalize
|
|
{
|
|
}
|
|
|
|
+ findClass: aString
|
|
{
|
|
|
|
| a b c |
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class Class extends Stix
|
|
{
|
|
}
|
|
|
|
class NilObject extends Stix
|
|
{
|
|
}
|
|
|
|
class Object extends Stix
|
|
{
|
|
}
|
|
|
|
|
|
|
|
-----------------------------------------
|
|
class variable
|
|
and class instance variable
|
|
-----------------------------------------
|
|
|
|
A CV X Y
|
|
CIV x y
|
|
|
|
B CV Z
|
|
civ z
|
|
|
|
C civ q
|
|
|
|
|
|
A: getX
|
|
return x (return instance variable 1)
|
|
|
|
B getX
|
|
return A'X (return invance variable 3)
|
|
|
|
x is index 1.
|
|
y is index 2.
|
|
z is index 3.
|
|
X is index 3 of A.
|
|
Y is index 3 of A.
|
|
Z is index 2 of B.
|
|
q is index 4 of C.
|
|
|
|
|
|
A has x y X Y
|
|
B has x y z Z
|
|
C has x y z q
|
|
|
|
place class intance variables before class variables.
|
|
|
|
-------------------------------------------
|
|
|
|
|
|
class Magnitude extends Stix
|
|
{
|
|
}
|
|
|
|
%include 'Association.st'
|
|
|
|
%class Association(Magnitude)
|
|
{
|
|
%category(Association class)
|
|
|
|
%constant
|
|
ABC := XXX
|
|
BCD := KKK
|
|
TTT := 20
|
|
|
|
%self(private)
|
|
|
|
|
|
%self(instance creation)
|
|
|
|
| Key Value | "class variables" <--- index
|
|
| xxx yyy | "class instance variables" <--- index
|
|
|
|
key: aKey
|
|
{
|
|
^self key: aKey value: nil.
|
|
}
|
|
|
|
key: aKey value: aValue
|
|
{
|
|
| ass |
|
|
ass := self new.
|
|
ass key: aKey value: aValue.
|
|
^ass.
|
|
}
|
|
|
|
%instance(initialization)
|
|
| key value | "instance variables"
|
|
|
|
key: aKey value: aValue
|
|
{
|
|
key := aKey.
|
|
value := aValue.
|
|
}
|
|
|
|
key
|
|
{
|
|
^key
|
|
}
|
|
|
|
value
|
|
{
|
|
^value
|
|
}
|
|
|
|
value: value
|
|
{
|
|
self->value := aValue
|
|
}
|
|
|
|
= anAssociation
|
|
{
|
|
^self->key = anAssociation key.
|
|
}
|
|
|
|
hash
|
|
{
|
|
^self->key hash
|
|
}
|
|
}
|
|
|
|
|
|
|
|
"Creates a new class Association inheriting nil"
|
|
%class Association(nil)
|
|
{
|
|
%func more
|
|
{
|
|
^self
|
|
}
|
|
}
|
|
|
|
|
|
"Extends an existing Association class"
|
|
%class Association
|
|
{
|
|
}
|
|
|
|
|
|
class Character extends Magnitude
|
|
{
|
|
}
|
|
|
|
class Number extends Magnitude
|
|
{
|
|
}
|
|
|
|
class Integer extends Number
|
|
{
|
|
}
|
|
|
|
class SmallInteger extends Integer
|
|
{
|
|
}
|
|
|
|
class LargeInteger extends Integer
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Association
|
|
{
|
|
%class
|
|
| x y z |
|
|
|
|
value: xxx
|
|
{
|
|
}
|
|
}
|
|
|
|
Association: Magnitude
|
|
{
|
|
}
|
|
|
|
Association: <- for extending
|
|
{
|
|
}
|
|
|
|
Association:
|
|
{
|
|
}
|
|
|
|
Association key: xxx
|
|
{
|
|
}
|
|
|
|
Association key: xxx
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
----------------------------------------------------------------
|
|
class ByteArray(FixedSizeCollection): #byte
|
|
{
|
|
fun at: anIndex put: aValue
|
|
{
|
|
^self basicAt: anIndex put: aValue.
|
|
}
|
|
}
|
|
|
|
class(#byte) ByteArray(FixedSizedCollection)
|
|
{
|
|
}
|
|
|
|
class(#byte) ByteArray(Stix)
|
|
{
|
|
}
|
|
|
|
class Association(Magnitude) -> new Association inheriting Magnitude
|
|
class Association() -> new Association inheriting Stix
|
|
class(#byte) Association() -> new Association class inheriting Stix, but it's byte indexed.
|
|
class(#word) Association() -> new Association class inheriting Stix, but it's word indexed.
|
|
class(#pointer) Association() -> new Association class inheriting Stix, but it's oop indexed. (it can have the variable part on top of the fixed part. response to the 'new: aSize' message)
|
|
class(#word) Association(Magnitude) -> new Association class inheriting Magnitude, but it's word indexed.
|
|
class(#character) Association(Magnitude)
|
|
|
|
|
|
class Association -> revisit the Association class defined previsously. Revisiting can add new methods.
|
|
|
|
#include 'Magnitude.st'
|
|
|
|
#class(#byte) Association(Magnitude)
|
|
{
|
|
## class variables can be accessed by class methods and instance methods.
|
|
## methods of subclasses can also access them.
|
|
declare(#class) a b c.
|
|
|
|
## class instance variable can be accessed inside the class method only.
|
|
|
|
declare(#classinst) d, e, f
|
|
|
|
## All instance variables are protected by default.
|
|
declare key, value.
|
|
|
|
|
|
##
|
|
## declare(#class) a, b, c. ## class variables
|
|
## declare(#classinst) a, b, c. ## class instance variables
|
|
## declare(#instance) a, b, c. ## isntance variables
|
|
## declare a,b, c. ## instance variables
|
|
|
|
## function(#class) ## class method
|
|
## function(#instance) ## instance method
|
|
## function ## instance method
|
|
|
|
## dcl(#class) a, b, c. ## short form
|
|
## dcl(#classinst) a, b, c
|
|
## fun(#class)
|
|
|
|
|
|
## var and fun are not keywords. they can be a method name or a variable name.
|
|
## Casing is not used to differentiate variable kinds like global local temporary etc.
|
|
|
|
## other modifiers (EXPERIMENTAL. JUST THINKING).
|
|
## declare(#class #public #rw) x. x can be accessed by other classes in read-write mode.
|
|
## function(#private) xxx xxx is a private method
|
|
## function(#class #private) xxx xxx is private class method.
|
|
|
|
function(#class) initialize
|
|
{
|
|
## This is the initilizer for the class object.
|
|
## executed when this class is added to the system.
|
|
## initialize the class variables and class instance variables.
|
|
SIZE := 20.
|
|
}
|
|
|
|
function(#class) key: aKey
|
|
{
|
|
^self key: aKey value: nil.
|
|
}
|
|
|
|
function(#class) key: aKey value: aValue
|
|
{
|
|
| ass |
|
|
ass := self new.
|
|
ass key: aKey value: aValue.
|
|
^ass.
|
|
}
|
|
|
|
function key: aKey value: aValue
|
|
{
|
|
key := aKey.
|
|
value := aValue.
|
|
}
|
|
|
|
function key
|
|
{
|
|
^key
|
|
}
|
|
|
|
function value
|
|
{
|
|
^value
|
|
}
|
|
|
|
function value: value
|
|
{
|
|
self->value := aValue
|
|
}
|
|
|
|
function = anAssociation
|
|
{
|
|
^self->key = anAssociation key.
|
|
}
|
|
|
|
function hash
|
|
{
|
|
^self->key hash
|
|
}
|
|
|
|
function value: aBlock
|
|
{
|
|
|a |
|
|
|
|
a := [ :t1 | t1 value ] with: 10.
|
|
^a + 10.
|
|
}
|
|
}
|
|
|
|
|
|
; message cascading
|
|
. steatement terminator or flaoting point if in number and followed by a digit.
|
|
^ return
|
|
[ ] block
|
|
# symbol or array
|
|
() grouping
|
|
$ character constant
|
|
| temporary variable or end of block arguments.
|
|
|
|
"" comment
|
|
'' string
|
|
: at the of the keyword or before block argument name.
|
|
|
|
-------------------
|
|
avaialbel
|
|
' !
|
|
|
|
--------------------------------------------------
|
|
#! for comment
|
|
## for comment
|
|
-----------------------------
|
|
|
|
@ binarySelector for coordianate number @ number.
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
Single line comment
|
|
## comment text
|
|
#! comment text (easy handling to skip hash bang)
|
|
|
|
Multi-line comments - double quoted as in smalltalk
|
|
" comment text "
|
|
|
|
|
|
|
|
#class X(Y)
|
|
{
|
|
#dcl a b c.
|
|
#fun print
|
|
{
|
|
}
|
|
}
|