hcl/lang.txt
2022-03-22 14:45:56 +00:00

216 lines
3.7 KiB
Plaintext

## dictionary list (DIC)
{ 1 2 3 4 }
{ 1: 2, 3: 4}
{} -> empty dictionary
{ 1 } -> error, no value. dictionary requires even number of items.
## array list
[ 1 2 3 4]
[ 1, 2, 3, 4 ]
[] -> empty array
## byte array list
#[ 1 2 3 4 ]
#[ 1, 2, 3, 4 ]
each item must be in the byte range.
if a given value is not a number in the allowed range, an exception error is raised.
(try
(set a 20)
#[ 1 2 3 (+ a 300)] ; this throws an catchable exception.
catch(e)
(printf "EXCEPTION - %O\n" e)
)
## non-executable list (QLIST)
#(1 2 3 4)
#(1 2 3 4 . 5)
#() -> same as null
comma not allowed to seperate items.
## varaible declaration list (VLIST)
| a b c |
## class declaration with methods.
(defclass X
| x y | ; instance variables
::: | bob jim | ; class variables
; instance variables and class variables must not collide with those of parent classes.
; they must not collide with method names of parent classes
(set bob "Bob") ; can access class variables. disallowed to access instance variables
(defun setX (a)
(set x a)
)
; instance method. a method name must not collide with instance variable names and class variable names.
; the name can be the same as method names of parent classes.
(defun K (a b)
(:self Y a)
(return (+ a b x y))
)
(defun Y (a)
(printf "Y=>%d [%s]\n" a bob)
)
(defun ::: KK (a b)
(printf "K=>%s\n" bob) ; a class method can access class variables but not instance variables
(return (+ a b))
)
(set jim (lambda (a b) (+ a b))) ; an anonymous function created
)
(set r (object-new X))
(:r Y 10)
(printf ">>%d\n" (:X KK 77 99))
## method invocation
send the message aaa to the receiver
(:self aaa)
send the message aaa to the receiver but let it resolve the method in the superclass side.
(:super aaa)
send the message dump to the object pointed to by x with arguments 1, 2, 3.
(:x dump 1 2 3)
## method types
- class method
- class instantiation method
(defclass P
| x y |
(defun ::* new ()
(set x 1)
(set y 1)
(return self)
)
(defun get-x() x)
(defun get-y() y)
)
(defclass X ::: P
| x y |
(defun ::* new (a b)
(:super new)
x = a
y = b
(return self)
)
(defun get-xx() x)
(defun get-yy() y)
)
(set t (:X new 10 20)) ;t is an instance of X
(printf "%d %d %d %d\n" (:t get-x) (:t get-y) (:t get-xx) (:t get-yy)) ; must print 1 1 10 20
(:t new 100 300) ;the x, y in the X part get reset to 100 and 300. doesn't create a new instance
(printf "%d %d %d %d\n" (:t get-x) (:t get-y) (:t get-xx) (:t get-yy)) ; must print 1 1 100 300
- instance method
## dynamic dispatching by method name
(defclass X
(defun t1 (x) (printf "t1 = %d\n" (+ x x x)))
(defun t2 (x) (printf "t2 = %d\n" (* x x x)))
)
(defun get-name-1() "t1")
(defun get-name-2() "t2")
(set x (object-new X))
(:x (get-name-1) 100) ; must be same as (:x t1 100)
(:x (get-name-2) 100) ; must be same as (:x t2 100)
## Something to look into..
normal function call
(f arg1 arg2 arg3)
(rcv f arg1 arg2)
## dynamic method invocation???
(:X (f) arg1 arg2)
as long as f returns a symbol, it can also invoke a method??
(defun getX() X) ; ->it must return an object
((getX)->show "hello")
X.Y
push X
push_symbol Y
lookup
(X.Y)
push X
push_symbol Y
lookup
call 0
X.Y.Z
push X
push_symbol Y
lookup
push_symbol Z
lookup
--- if this is within a method, it must become push_instvar
self.x
push self
push symbol x
lookup
fun f(a, b)
{
}
fun f(a, b) -> (c, d)
{
}
class X
{
var x, y, z
var! printer;
printer := Printer.new();
fun! new(a, b)
{
return super.new().init(a, b);
}
fun init(a, b)
{
}
fun show(a, b)
{
Printer.dump(a, b);
}
}
x := X.new(10, 20);
x.show (40, 50);
---------------