convert function call to builtInCall in setvariable, and add OOP example

This commit is contained in:
2023-06-21 20:36:06 +01:00
parent ae08f059fb
commit 9fe8bcb515
8 changed files with 59 additions and 56 deletions

View File

@@ -115,6 +115,7 @@ func ArArray(arr []any) ArObject {
step = int(a[2].(number).Num().Int64()) step = int(a[2].(number).Num().Int64())
} }
} }
var ogStart = start
if start < 0 { if start < 0 {
start = len(arr) + start start = len(arr) + start
} }
@@ -124,6 +125,13 @@ func ArArray(arr []any) ArObject {
if end != nil && end.(int) > len(arr) { if end != nil && end.(int) > len(arr) {
end = len(arr) end = len(arr)
} }
if start >= len(arr) || start < 0 {
return "", ArErr{
TYPE: "IndexError",
message: "index out of range, trying to access index " + fmt.Sprint(ogStart) + " in array of length " + fmt.Sprint(len(arr)),
EXISTS: true,
}
}
if end == nil { if end == nil {
return arr[start], ArErr{} return arr[start], ArErr{}
} else if step == 1 { } else if step == 1 {

View File

@@ -195,23 +195,6 @@ func makeGlobal() ArObject {
return ArArray([]any{}), ArErr{} return ArArray([]any{}), ArErr{}
}} }}
vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess} vars["subprocess"] = builtinFunc{"subprocess", ArSubprocess}
vars["object"] = builtinFunc{"object", func(a ...any) (any, ArErr) {
if len(a) == 0 {
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
}
switch x := a[0].(type) {
case ArObject:
if typeof(x) == "object" {
return x, ArErr{}
}
newclass := ArObject{obj: anymap{}}
for key, val := range x.obj {
newclass.obj[key] = val
}
return newclass, ArErr{}
}
return nil, ArErr{TYPE: "TypeError", message: "Cannot create class from '" + typeof(a[0]) + "'", EXISTS: true}
}}
vars["sequence"] = builtinFunc{"sequence", ArSequence} vars["sequence"] = builtinFunc{"sequence", ArSequence}
vars["exit"] = builtinFunc{"exit", func(a ...any) (any, ArErr) { vars["exit"] = builtinFunc{"exit", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {

View File

@@ -42,9 +42,7 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
path: r.path, path: r.path,
code: r.code, code: r.code,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS { return resp, err
return resp, ArErr{}
}
} }
} }

View File

@@ -330,5 +330,20 @@ func Map(m anymap) ArObject {
return true, ArErr{} return true, ArErr{}
}, },
} }
obj.obj["object"] = builtinFunc{
"object",
func(args ...any) (any, ArErr) {
if len(args) != 0 {
return nil, ArErr{
TYPE: "TypeError",
message: "expected 0 arguments, got " + fmt.Sprint(len(args)),
EXISTS: true,
}
}
return ArObject{
obj: m,
}, ArErr{}
},
}
return obj return obj
} }

View File

@@ -407,6 +407,14 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
var outputErr ArErr = ArErr{
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
if typeof(resp) == "number" && typeof(output) == "number" { if typeof(resp) == "number" && typeof(output) == "number" {
output = output.(number).Quo(output.(number), resp.(number)) output = output.(number).Quo(output.(number), resp.(number))
return output, ArErr{} return output, ArErr{}
@@ -423,6 +431,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
if !err.EXISTS { if !err.EXISTS {
return val, ArErr{} return val, ArErr{}
} }
outputErr = err
} }
} }
@@ -442,14 +451,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
return val, ArErr{} return val, ArErr{}
} }
} }
return nil, ArErr{ return nil, outputErr
"Runtime Error",
"Cannot divide type '" + typeof(resp) + "'",
o.line,
o.path,
o.code,
true,
}
} }
func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) { func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) {

View File

@@ -275,13 +275,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
case ArObject: case ArObject:
if _, ok := y.obj["__setindex__"]; ok { if _, ok := y.obj["__setindex__"]; ok {
callable := y.obj["__setindex__"] callable := y.obj["__setindex__"]
_, err := runCall(call{ builtinCall(callable, []any{key, resp})
callable: callable,
args: []any{key, resp},
line: v.line,
path: v.path,
code: v.code,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }

View File

@@ -1,21 +0,0 @@
class obj1:
def __init__(self) -> None:
pass
def __add__(self, other):
print("obj1")
return 10
class obj2:
def __init__(self) -> None:
pass
def __add__(self, other):
print("obj2")
return 20
obj1 = obj1()
obj2 = obj2()
print(obj1 + obj2)
print(obj2 + obj1)

24
tests/oop.ar Normal file
View File

@@ -0,0 +1,24 @@
let toyTank(colour , name) = do
let class = {}
class.getColour() = do
term.log("My colour is", colour)
class.getName() = do
term.log("My name is", name)
class.setColour(newColour) = do
colour = newColour
class.setName(newName) = do
name = newName
return class.object()
let tanks = []
for (i from 0 to 10) tanks.append(toyTank("red", "tank" + (i+1)))
term.log(dir(tanks[0]))
for (i from 0 to tanks.length) do
tanks[i].getName()
tanks[i].getColour()
tanks[i].setColour("blue")
tanks[i].setName("tank" + (i + 11))
tanks[i].getName()
tanks[i].getColour()
term.log()