diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/anglais.iml b/.idea/anglais.iml
new file mode 100644
index 0000000..11646b4
--- /dev/null
+++ b/.idea/anglais.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..6c7658f
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..36d0426
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/compiler.go b/core/compiler.go
index 83098d5..36f0f7a 100644
--- a/core/compiler.go
+++ b/core/compiler.go
@@ -977,41 +977,6 @@ func (c *Compiler) compileAssignFromStack(to Node, sig TypeSignature, declare bo
}
return sig, nil
- case IndexNodeType:
- if declare {
- return nil, c.error(fmt.Sprintf("cannot declare an indexed item"), to)
- }
-
- n := to.(*IndexNode)
-
- ssig, err := c.compile(n.source)
- if err != nil {
- return nil, err
- }
-
- isig, err := c.compile(n.index)
- if err != nil {
- return nil, err
- }
-
- if isig.Type() != TypeInteger {
- return nil, c.error(fmt.Sprintf("cannot index into list with non-integer (%s)", isig), n.index)
- }
-
- switch ssig.Type() {
- case TypeList:
- lsig := ssig.(*ListSignature)
- if !c.typeMatches(sig, lsig.Contents) {
- return nil, c.error(fmt.Sprintf("cannot assign value of type %s to list with items of type %s", sig, lsig.Contents), to)
- }
-
- c.add(InstructionSetIndexList)
- default:
- return nil, c.error(fmt.Sprintf("cannot set index of %s", ssig.Type()), n.source)
- }
-
- return sig, nil
-
default:
return nil, c.error(fmt.Sprintf("cannot assign to %s", to.Type()), to)
}
diff --git a/core/types.go b/core/types.go
index 81dafd8..6fe7c99 100644
--- a/core/types.go
+++ b/core/types.go
@@ -487,27 +487,6 @@ func quickComposite(a ...TypeSignature) TypeSignature {
return s
}
-func simplifyComposite(a TypeSignature) TypeSignature {
- var atoms []TypeSignature
-
- s := NewStack[TypeSignature](16)
- s.Push(a)
-
- for s.Current > 0 {
- i := s.Pop()
-
- c, ok := i.(*CompositeSignature)
- if !ok {
-
- atoms = append(atoms, i)
- } else {
- s.Push(c.A, c.B)
- }
- }
-
- return quickComposite(atoms...)
-}
-
type InnerSignature struct{}
func (*InnerSignature) Type() Type {
diff --git a/core/values.go b/core/values.go
index efb5f41..8f95a1c 100644
--- a/core/values.go
+++ b/core/values.go
@@ -117,12 +117,8 @@ type Value interface {
// Get a member from the value. An error is returned if the member does not exist
Get(string) (Value, error)
- // Copy create a copy of the value. A copy is a direct copy for small data (numbers) and a copy of pointer
- // for bigger data (lists, tuples, dicts)
- Copy() Value
-
- // Clone create a clone of the value. A clone is new data for all data.
- //Clone() Value
+ // Clone create a clone of the value. The returned value is a pointer to a new value of the same type as the value.
+ Clone() Value
}
type NilValue struct{}
@@ -147,7 +143,7 @@ func (v *NilValue) Get(_ string) (Value, error) {
return nil, errors.New("nil has no properties")
}
-func (v *NilValue) Copy() Value {
+func (v *NilValue) Clone() Value {
return &NilValue{}
}
@@ -179,7 +175,7 @@ func (v *BoolValue) Get(_ string) (Value, error) {
return nil, errors.New("booleans have no properties")
}
-func (v *BoolValue) Copy() Value {
+func (v *BoolValue) Clone() Value {
return &BoolValue{
v.Boolean,
}
@@ -262,11 +258,11 @@ func (v *ObjectValue) Get(key string) (Value, error) {
}
}
-func (v *ObjectValue) Copy() Value {
+func (v *ObjectValue) Clone() Value {
m := make(map[string]Value, len(v.Members))
for name, mem := range v.Members {
- m[name] = mem.Copy()
+ m[name] = mem.Clone()
}
return &ObjectValue{
@@ -307,7 +303,7 @@ func (v *FloatValue) Get(_ string) (Value, error) {
return nil, errors.New("numbers have no properties")
}
-func (v *FloatValue) Copy() Value {
+func (v *FloatValue) Clone() Value {
return &FloatValue{
v.Number,
}
@@ -338,7 +334,7 @@ func (v *IntegerValue) Get(_ string) (Value, error) {
return nil, errors.New("numbers have no properties")
}
-func (v *IntegerValue) Copy() Value {
+func (v *IntegerValue) Clone() Value {
return &IntegerValue{
new(big.Int).Set(v.Number),
}
@@ -431,7 +427,7 @@ func (v *StringValue) Get(key string) (Value, error) {
return nil, errors.New(fmt.Sprintf("string has no property \"%s\"", key))
}
-func (v *StringValue) Copy() Value {
+func (v *StringValue) Clone() Value {
return &StringValue{
v.Text,
}
@@ -598,9 +594,15 @@ func (v *ListValue) Get(key string) (Value, error) {
return nil, errors.New(fmt.Sprintf("list has no property \"%s\"", key))
}
-func (v *ListValue) Copy() Value {
+func (v *ListValue) Clone() Value {
+ n := make([]Value, len(v.Items))
+
+ for i, item := range v.Items {
+ n[i] = item.Clone()
+ }
+
return &ListValue{
- v.Items,
+ n,
}
}
@@ -633,9 +635,13 @@ func (v *TupleValue) DebugString() string {
return v.String()
}
-func (v *TupleValue) Copy() Value {
+func (v *TupleValue) Clone() Value {
+ n := make([]Value, len(v.Items))
+ for i, item := range v.Items {
+ n[i] = item.Clone()
+ }
return &TupleValue{
- v.Items,
+ n,
}
}
@@ -712,7 +718,7 @@ func (v *FunctionValue) Get(_ string) (Value, error) {
return nil, errors.New("functions have no properties")
}
-func (v *FunctionValue) Copy() Value {
+func (v *FunctionValue) Clone() Value {
return &FunctionValue{
v.Name,
v.Params,
@@ -752,7 +758,7 @@ func (v *BuiltinFunctionValue) Get(_ string) (Value, error) {
return nil, errors.New("functions have no properties")
}
-func (v *BuiltinFunctionValue) Copy() Value {
+func (v *BuiltinFunctionValue) Clone() Value {
return &BuiltinFunctionValue{
v.Name,
v.Signature,
@@ -801,7 +807,7 @@ func (v *RecordValue) DebugString() string {
return v.String()
}
-func (v *RecordValue) Copy() Value {
+func (v *RecordValue) Clone() Value {
return &RecordValue{
v.Entries,
}
diff --git a/core/vm.go b/core/vm.go
index f07890f..22a568e 100644
--- a/core/vm.go
+++ b/core/vm.go
@@ -152,14 +152,10 @@ const (
// is the index. [..., container, index] -> [..., item]
InstructionIndexTuple
// InstructionIndexString index into a string. The lower item is the container, and the top item
- // is the index. [..., container, index] -> [..., item]. Produces a new string with only the character
- // at the indexed position
+ // is the index. [..., container, index] -> [..., item]. Produces a new string with the character
+ // at the position
InstructionIndexString
- // InstructionSetIndexList set the item at a given index in a list.
- // [..., item, container, index] -> [..., item]
- InstructionSetIndexList
-
// InstructionBreakpoint for debugging purposes
InstructionBreakpoint
)
@@ -642,7 +638,7 @@ var DefaultGlobals = map[string]Value{
n, _ := v.Number.Float64()
return &FloatValue{n}, nil
case *FloatValue:
- return v.Copy(), nil
+ return v.Clone(), nil
case *StringValue:
num, err := strconv.ParseFloat(v.Text, FloatSize)
if err != nil {
@@ -982,7 +978,7 @@ func (vm *VM) Next() bool {
vm.Stack.Push(v)
case InstructionSetLocal:
- value := vm.Stack.Peek().Copy()
+ value := vm.Stack.Peek().Clone()
name := vm.GetConstant(vm.NextByte()).(*StringValue).Text
vm.setVar(name, value)
@@ -990,7 +986,7 @@ func (vm *VM) Next() bool {
case InstructionDeclareLocal:
vm.addVar(
vm.GetConstant(vm.NextByte()).(*StringValue).Text,
- vm.Stack.Peek().Copy(),
+ vm.Stack.Peek().Clone(),
)
case InstructionGetGlobal:
@@ -1074,7 +1070,7 @@ func (vm *VM) Next() bool {
vm.Stack.Push(r, l)
case InstructionDuplicate:
- vm.Stack.Push(vm.Stack.Peek().Copy())
+ vm.Stack.Push(vm.Stack.Peek().Clone())
case InstructionAccessProperty:
source := vm.Stack.Pop()
@@ -1116,7 +1112,7 @@ func (vm *VM) Next() bool {
vm.error(fmt.Sprintf("index %d out of bounds", n))
}
- vm.Stack.Push(l.Items[n].Copy())
+ vm.Stack.Push(l.Items[n].Clone())
case InstructionIndexTuple:
i := vm.Stack.Pop().(*IntegerValue)
@@ -1128,7 +1124,7 @@ func (vm *VM) Next() bool {
vm.error(fmt.Sprintf("index %d out of bounds", n))
}
- vm.Stack.Push(t.Items[n].Copy())
+ vm.Stack.Push(t.Items[n].Clone())
case InstructionIndexString:
i := vm.Stack.Pop().(*IntegerValue)
@@ -1142,18 +1138,6 @@ func (vm *VM) Next() bool {
vm.Stack.Push(&StringValue{string(s.Text[n])})
- case InstructionSetIndexList:
- n := vm.Stack.Pop().(*IntegerValue)
- l := vm.Stack.Pop().(*ListValue)
-
- i := n.Number.Int64()
-
- if i < 0 || int64(len(l.Items)) <= i {
- vm.error(fmt.Sprintf("index %d out of bounds", i))
- }
-
- l.Items[i] = vm.Stack.Peek().Copy()
-
case InstructionBreakpoint:
/*
// I'm keeping this
@@ -1300,7 +1284,7 @@ func (vm *VM) HasNext() bool {
}
func (vm *VM) GetConstant(id Bytecode) Value {
- return vm.chunk.Constants[id].Copy()
+ return vm.chunk.Constants[id].Clone()
}
func (vm *VM) ReadConstant() Value {
diff --git a/examples/fib.ang b/examples/fib.ang
index 4860a1e..63a432a 100644
--- a/examples/fib.ang
+++ b/examples/fib.ang
@@ -3,9 +3,14 @@
fn range(from: int, to: int) -> (fn() -> (int, bool)) {
i := from - 1
+ end := to - 1
fn() -> (int, bool) {
- (i = i+1, i+1 < to)
+ if i < end {
+ (i = i+1, true)
+ } else {
+ (-1, false)
+ }
}
}
diff --git a/examples/list.ang b/examples/list.ang
index d34887e..9866d3e 100644
--- a/examples/list.ang
+++ b/examples/list.ang
@@ -1,6 +1,6 @@
# Empty list
-println([]any)
+println([])
# List with items
println([3, 1, 4, 1, 5, 9, 2, 6, 5])
@@ -8,25 +8,25 @@ println([3, 1, 4, 1, 5, 9, 2, 6, 5])
# List with items of different types
println(["", "私はかっこいいです。", true, nil, nil, 1, 2])
-a := []int
+a := []
-a.push(1)
-a.push(2)
+a = a + [1]
+a = a + [2]
println(a)
-list := []int
+list := []
x := 0
for n in 0..100 {
x = x + 2*n + 1
- list.push(x)
+ list = list + [x]
}
println(list)
-println(list.map(fn(a: int) -> int {
+println(list.map(func(a) {
return a - 1
}))
println(list.length())
diff --git a/examples/recursive.ang b/examples/recursive.ang
index f30109f..caa0e37 100644
--- a/examples/recursive.ang
+++ b/examples/recursive.ang
@@ -1,15 +1,14 @@
# This program computes the fibonacci numbers using recursion (O(2^n))
# It is very slow
-fn fib(x: number) number {
+func fib(x: number) number {
if x <= 1 {
- x
- } else {
- fib(x - 1) + fib(x - 2)
+ return x
}
+ return fib(x - 1) + fib(x - 2)
}
n := 0
while n < 100 {
- println(fib(n))
+ write(str(fib(n)))
n = n + 1
}
diff --git a/foo.ang b/foo.ang
deleted file mode 100644
index e69de29..0000000
diff --git a/go.work.sum b/go.work.sum
deleted file mode 100644
index 2d35219..0000000
--- a/go.work.sum
+++ /dev/null
@@ -1 +0,0 @@
-github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
diff --git a/lib/list.ang b/lib/list.ang
index 792751f..254912d 100644
--- a/lib/list.ang
+++ b/lib/list.ang
@@ -1,5 +1,5 @@
-fn map(list: [T], f: fn(T) -> R) -> [R] {
+fn ([T]) map(f: fn(T) -> R) -> [R] {
out := []
for v in list.iter() {
diff --git a/lib/math.ang b/lib/math.ang
index 9dac01a..120e60e 100644
--- a/lib/math.ang
+++ b/lib/math.ang
@@ -249,5 +249,3 @@ fn tan(x: float) -> float {
# todo
0.0
}
-
-(E:, PI:, sqrt:, log:, ln:, exp:, pow:)
diff --git a/lib/testing.ang b/lib/testing.ang
index 82e7b77..59aed2c 100644
--- a/lib/testing.ang
+++ b/lib/testing.ang
@@ -1,25 +1,25 @@
NAMESPACE := ""
-fn namespace(name: str, test: fn()) {
+func namespace(name: string, test: func()) {
NAMESPACE = name
test()
}
-fn eq(a: T, b: T) {
+func assertEqual(a: any, b: any) {
if a != b {
- println(format("assertion error: % should (but doesn't) equal %", [a, b]))
+ write(format("assertion error: % should (but doesn't) equal %", [a, b]))
exit(1)
} else if env("DEBUG") != "" {
- println(format("assertion success: % equals %", [a, b]))
+ write(format("assertion success: % equals %", [a, b]))
}
}
-fn neq(a: T, b: T) {
+func assertNotEqual(a: any, b: any) {
if a == b {
- println(format("assertion error: % shouldn't (but does) equal %", [a, b]))
+ write(format("assertion error: % shouldn't (but does) equal %", [a, b]))
exit(1)
} else if env("DEBUG") != "" {
- println(format("assertion success: % doesn't equal %", [a, b]))
+ write(format("assertion success: % doesn't equal %", [a, b]))
}
}
diff --git a/tests/list.ang b/tests/list.ang
index e98fcf8..8554f14 100644
--- a/tests/list.ang
+++ b/tests/list.ang
@@ -34,10 +34,3 @@ assertEq("the, first, time".split(", "), ["the", "first", "time"])
# list indexing
assertEq([1, 2, 3].at(1), 2)
assertEq(["a", "b", "c"].at(2), "c")
-
-# mutating list
-a := [1, 2, 3]
-assertEq(a, [1, 2, 3])
-
-a[1] = 4
-assertEq(a, [1, 4, 3])
diff --git a/tests/tuple.ang b/tests/tuple.ang
index 65e99e9..81aa508 100644
--- a/tests/tuple.ang
+++ b/tests/tuple.ang
@@ -9,10 +9,3 @@ fn neighbours(n: int) -> (int, int) {
}
assertEq(neighbours(2), (1, 3))
-
-a := (1, 2)
-assertEq(a, (1, 2))
-
-(x, y) := a
-assertEq(x, 1)
-assertEq(y, 2)