From 9fe8bcb5157fd499457527b10bcc96cd7a348444 Mon Sep 17 00:00:00 2001 From: William Bell Date: Wed, 21 Jun 2023 20:36:06 +0100 Subject: [PATCH] convert function call to builtInCall in setvariable, and add OOP example --- src/array.go | 8 ++++++++ src/built-ins.go | 17 ----------------- src/getIndex.go | 4 +--- src/map.go | 15 +++++++++++++++ src/operations.go | 18 ++++++++++-------- src/variable.go | 8 +------- testingoop.py | 21 --------------------- tests/oop.ar | 24 ++++++++++++++++++++++++ 8 files changed, 59 insertions(+), 56 deletions(-) delete mode 100644 testingoop.py create mode 100644 tests/oop.ar diff --git a/src/array.go b/src/array.go index be1caae..5e1bf92 100644 --- a/src/array.go +++ b/src/array.go @@ -115,6 +115,7 @@ func ArArray(arr []any) ArObject { step = int(a[2].(number).Num().Int64()) } } + var ogStart = start if start < 0 { start = len(arr) + start } @@ -124,6 +125,13 @@ func ArArray(arr []any) ArObject { if end != nil && end.(int) > 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 { return arr[start], ArErr{} } else if step == 1 { diff --git a/src/built-ins.go b/src/built-ins.go index 59dd854..e96f30c 100644 --- a/src/built-ins.go +++ b/src/built-ins.go @@ -195,23 +195,6 @@ func makeGlobal() ArObject { return ArArray([]any{}), ArErr{} }} 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["exit"] = builtinFunc{"exit", func(a ...any) (any, ArErr) { if len(a) == 0 { diff --git a/src/getIndex.go b/src/getIndex.go index 75e5e5d..651ec55 100644 --- a/src/getIndex.go +++ b/src/getIndex.go @@ -42,9 +42,7 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) { path: r.path, code: r.code, }, stack, stacklevel+1) - if !err.EXISTS { - return resp, ArErr{} - } + return resp, err } } diff --git a/src/map.go b/src/map.go index 470ea74..b458d81 100644 --- a/src/map.go +++ b/src/map.go @@ -330,5 +330,20 @@ func Map(m anymap) ArObject { 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 } diff --git a/src/operations.go b/src/operations.go index af5ac1c..b4e1e06 100644 --- a/src/operations.go +++ b/src/operations.go @@ -407,6 +407,14 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) { if err.EXISTS { 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" { output = output.(number).Quo(output.(number), resp.(number)) return output, ArErr{} @@ -423,6 +431,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) { if !err.EXISTS { return val, ArErr{} } + outputErr = err } } @@ -442,14 +451,7 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) { return val, ArErr{} } } - return nil, ArErr{ - "Runtime Error", - "Cannot divide type '" + typeof(resp) + "'", - o.line, - o.path, - o.code, - true, - } + return nil, outputErr } func calcAdd(o operationType, stack stack, stacklevel int) (any, ArErr) { diff --git a/src/variable.go b/src/variable.go index 125d12a..74b5362 100644 --- a/src/variable.go +++ b/src/variable.go @@ -275,13 +275,7 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) { case ArObject: if _, ok := y.obj["__setindex__"]; ok { callable := y.obj["__setindex__"] - _, err := runCall(call{ - callable: callable, - args: []any{key, resp}, - line: v.line, - path: v.path, - code: v.code, - }, stack, stacklevel+1) + builtinCall(callable, []any{key, resp}) if err.EXISTS { return nil, err } diff --git a/testingoop.py b/testingoop.py deleted file mode 100644 index 20617f0..0000000 --- a/testingoop.py +++ /dev/null @@ -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) \ No newline at end of file diff --git a/tests/oop.ar b/tests/oop.ar new file mode 100644 index 0000000..57a080a --- /dev/null +++ b/tests/oop.ar @@ -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() \ No newline at end of file