Browse Source

fix: Using the proper declaration scope and an example

Matthias Ladkau 3 years ago
parent
commit
178b01bac9

+ 3 - 0
examples/fib/fib.ecal

@@ -0,0 +1,3 @@
+import "lib.ecal" as lib
+
+log("fib(1) = ", lib.fib(12))

+ 11 - 0
examples/fib/lib.ecal

@@ -0,0 +1,11 @@
+# Library for fib
+
+/* 
+fib calculates the fibonacci series using recursion.
+*/
+func fib(n) { 
+    if (n <= 1) {
+        return n
+    } 
+    return fib(n-1) + fib(n-2)
+} 

+ 2 - 0
examples/fib/run.sh

@@ -0,0 +1,2 @@
+#!/bin/sh
+../../ecal run fib.ecal

+ 1 - 1
interpreter/func_provider.go

@@ -252,7 +252,7 @@ func (rf *newFunc) addSuperClasses(vs parser.Scope, is map[string]interface{},
 		// Save previous init function
 
 		if funcVal, ok := v.(*function); ok {
-			newFunction := &function{funcVal.name, nil, obj, funcVal.declaration}
+			newFunction := &function{funcVal.name, nil, obj, funcVal.declaration, funcVal.declarationVS}
 			if k == "init" {
 				newFunction.super = initSuperList
 				initFunc = newFunction

+ 7 - 6
interpreter/rt_func.go

@@ -98,7 +98,7 @@ func (rt *funcRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interfa
 			name = rt.node.Children[0].Token.Val
 		}
 
-		fc = &function{name, nil, nil, rt.node}
+		fc = &function{name, nil, nil, rt.node, vs}
 
 		if name != "" {
 			vs.SetValue(name, fc)
@@ -112,10 +112,11 @@ func (rt *funcRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interfa
 function models a function in ECAL. It can have a context object attached - this.
 */
 type function struct {
-	name        string
-	super       []interface{}   // Super function pointer
-	this        interface{}     // Function context
-	declaration *parser.ASTNode // Function declaration node
+	name          string
+	super         []interface{}   // Super function pointer
+	this          interface{}     // Function context
+	declaration   *parser.ASTNode // Function declaration node
+	declarationVS parser.Scope    // Function declaration scope
 }
 
 /*
@@ -175,7 +176,7 @@ func (f *function) Run(instanceID string, vs parser.Scope, is map[string]interfa
 
 	if err == nil {
 
-		scope.SetParentOfScope(fvs, vs)
+		scope.SetParentOfScope(fvs, f.declarationVS)
 
 		res, err = body.Runtime.Eval(fvs, make(map[string]interface{}))
 

+ 21 - 0
interpreter/rt_func_test.go

@@ -197,6 +197,27 @@ result1 := foo(3, 2)
     c (float64) : 1
     foo (*interpreter.function) : ecal.function:  (Line 3, Pos 8)
     result1 (float64) : 6
+}` {
+		t.Error("Unexpected result: ", vsRes, res, err)
+		return
+	}
+
+	vs = scope.NewScope(scope.GlobalScope)
+
+	res, err = UnitTestEval(`
+func fib(n) {
+  if (n <= 1) {
+      return n
+  }
+  return fib(n-1) + fib(n-2)
+}
+
+result1 := fib(12)
+`, vs)
+
+	if vsRes := vs.String(); err != nil || res != nil || vsRes != `GlobalScope {
+    fib (*interpreter.function) : ecal.function: fib (Line 2, Pos 1)
+    result1 (float64) : 144
 }` {
 		t.Error("Unexpected result: ", vsRes, res, err)
 		return