First attempt at OOP

jotapapel
Posts: 4
Joined: Sun Jul 19, 2020 3:50 am

First attempt at OOP

This is my first attempt at coding a sort of object oriented programming, it's heavily influenced by LUA.

Code: Select all

``````' Dimension an array to hold all objects and their keys and values.
DIM _OBJECTS(100, 100)

' Metamethod to add a new record to database.
' RETURNS   the new index
DEF __newindex
IF ._OBJECTS(0, 0) < 100 THEN
.OBJECTS(0, 0) += 1 : RETURN .OBJECTS(0, 0)
END IF
END DEF

' Metamethod to find the index of a key on object (where it's stored).
' RETURNS   The index of the key or -1 if not found.
DEF __keyindex(index, key)
t = (STR SPLIT __table(index), ",") : i = -1
FOR k = 0 TO ((SIZE OF t) - 1)
IF (STR LEFT t(k), 1) = " " THEN t(k) = STR RIGHT t(k), (STR LEN t(k)) - 1
r = (STR RPL t(k), " = ", "=") : d = (STR SPLIT r, "=")
IF d(0) = key THEN
i = (k + 1) : BREAK
END IF
NEXT
RETURN i
END DEF

' Metamethod to assign starting values to keys.
DEF __init(index)
v = STR SPLIT __table(index), ","
FOR i = 0 TO ((SIZE OF v) - 1)
IF (STR LEFT v(i), 1) = " " THEN v(i) = STR RIGHT v(i), (STR LEN v(i)) - 1
r = (STR RPL v(i), " = ", "=") : d = (STR SPLIT r, "=") : g = 0
IF (STR LEFT d(1), 1) = "'" AND (STR RIGHT d(1), 1) = "'" THEN
g = STR MID d(1), 2, (STR LEN d(1)) - 2
ELSE
g = STR NUM d(1)
END IF
rawset(index, d(0), g)
NEXT
END DEF

' Metamethod to rawget an objects table
DEF __table(index) = ._OBJECTS(index, 0)

' Method to create a new object.
' table    table of keys assigned to the object, it can be the index of
'					 another object to use it's table instead.
' RETURNS  the new object's index
DEF \$(table)
index = __newindex
IF ._OBJECTS(index 0) = 0 THEN
IF (TYPE OF table) = 2 THEN ._OBJECTS(index 0) = table ELSE ._OBJECTS(index 0) = __table(table)
__init(index) : RETURN index
END IF
END DEF

' Method to assign values to an object's key.
' index     position of the object in the database
' key       key to assign
' value     value to assign to key
DEF rawset(index, key, value)
i = __keyindex(index, key)
IF i > -1 THEN ._OBJECTS(index, i) = value
END DEF

' Method to rawget the value of a key in an object.
' index     position of the object in the database
' table     table to rawget key index
' key       key to assign
' RETURNS   If the key exists returns its value, else returns 0
DEF rawget(index, key)
i = __keyindex(index, key)
IF i = -1 THEN RETURN 0 ELSE RETURN ._OBJECTS(index, i)
END DEF

object1 = \$("var1 = 'love', var2 = 'foo', var3 = 10")
object2 = \$(object1)

rawset(object1, "var1", "ken")
PRINT rawget(object2, "var1")
PRINT rawget(object1, "var1")
``````

kibernetik
Posts: 147
Joined: Tue Aug 06, 2019 3:03 pm

Re: First attempt at OOP

Very nice code.

For your information, in BestBASIC arrays can be re-defined to change their size dynamically:

Code: Select all

``````dim m(1) = "one","two"

s = sizeof m,1
for i = 0 to s-1
print m(i)
next
print

dim m(3)
m(2) = "three"
m(3) = "four"

s = sizeof m,1
for i = 0 to s-1
print m(i)
next
``````
Outputs:

Code: Select all

``````one
two

one
two
three
four``````

jotapapel
Posts: 4
Joined: Sun Jul 19, 2020 3:50 am

Re: First attempt at OOP

Second version, now the master array (the one that holds all object data) is dynamically dimensioned.

Code: Select all

``````' Dimension an array to hold all objects and their keys and values.
DIM OBJDATA(0, 0)

' Metamethod to re-dimension the master array.
' RETURNS   the master array re-dimensioned
DEF __redim(array, m, n)
s = SIZEOF(array, 2) : IF (n > s) THEN s = n
DIM array(m, s)
RETURN array
END DEF

' Metamethod to find the table of an object.
' RETURNS   the table
DEF __table(index) = OBJDATA(index, 0)

' Metamethod to find the number of variables an object has.
' RETURNS   the number of variables
DEF __len(index) = SIZEOF(STRSPLIT(__table(index), ","), 1)

' Metamethod to assign default values to the keys of a new object.
DEF __init(index)
vars = STRSPLIT(__table(index), ",")
FOR i = 0 TO (SIZEOF(vars, 1) - 1)
pair = vars(i) : pair = STRRPL(pair, " = ", "="): IF STRLEFT(pair, 1) = " " THEN pair = STRMID(pair, 2, STRLEN(pair) - 1)
p = STRSPLIT(pair, "=") : key = p(0) : val = p(1) : v = 0
IF (STRLEFT(val, 1) = "'" AND STRRIGHT(val, 1) = "'") THEN v = STRMID(val, 2, STRLEN(val) - 2) ELSE v = STRNUM(val)
SET(index, key, v)
NEXT
END DEF

' Metamethod to find the index assigned to a specific key, or the name of the key assign to an specific index in an object.
' RETURNS   the found pair
DEF __match(index, data)
vars = STRSPLIT(__table(index), ",") : e = 0
FOR i = 0 TO (SIZEOF(vars, 1) - 1)
pair = vars(i) : pair = STRRPL(pair, " = ", "="): IF STRLEFT(pair, 1) = " " THEN pair = STRMID(pair, 2, STRLEN(pair) - 1)
p = STRSPLIT(pair, "=") : k = p(0)
IF (TYPEOF(data) = 2) THEN
IF (k = data) THEN
e = (i + 1) : BREAK
END IF
ELSE IF ((i + 1) = data) THEN
e = k : BREAK
END IF
NEXT
RETURN e
END DEF

' Method to find the number of objects currently stored.
DEF OBJLEN = (SIZEOF(OBJDATA, 1) - 1)

' Method to create a new object. Strings must be inside apostrophes.
' data      table of keys to assign, it can be the index of another object to use it's table instead.
' RETURNS   the index of the new object
DEF OBJNEW(data)
.OBJDATA(0, 0) += 1
IF TYPEOF(data) = 2 THEN t = data ELSE t = __table(data)
m = OBJLEN + 1 : n = SIZEOF(STRSPLIT(t, ","), 1)
.OBJDATA = __redim(.OBJDATA, m, n)
.OBJDATA(m, 0) = t
__init(m)
RETURN m
END DEF

DEF \$(data) = OBJNEW(data)

' Method to assign values to an object's key.
' index     position of the object in the master array
' key       key to assign
' value     value to assign to key
DEF SET(index, key, value)
i = __match(index, key)
IF (i > -1) THEN .OBJDATA(index, i) = value
END DEF

' Method to get the value of a key in an object.
' index     position of the object in the master array
' table     table to rawget key index
' key       key to assign
DEF GET(index, key)
i = __match(index, key)
IF (i = -1) THEN RETURN 0 ELSE RETURN .OBJDATA(index, i)
END DEF

' Method to quickly add a number to a key's value.
' index     position of the object in the master array
' key       key to change
val = GET(index, key)
SET(index, key, val + number)
END DEF

' ---

obj1 = \$("x = 0, y = 0")
obj2 = \$(obj1)
obj3 = \$("name = 'joe', age = 25")

PRINT GET(obj1, "x"), GET(obj2, "x")
`````` 0               0