Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix returning values through variables as actual parameters #715

Merged
merged 5 commits into from
Jun 13, 2024

Conversation

vsbogd
Copy link
Collaborator

@vsbogd vsbogd commented Jun 13, 2024

When call is made using variable as an actual parameter the variables equality is kept in stack frame bindings to track the value of the variable. At the same time as formal argument variables are local they are not added into the Stack::vars set. Thus it is possible that variable equality is wiped when returning from the next nested call. And if after this call value is assigned to the formal argument variable this value will not be assigned to the actual argument variable.

In the following example:

(= (bar) (function (return ())))

(= (foo $b) (function
  ; fake internal call which wipes variables equalities
  (chain (eval (bar)) $_
  (unify $b value
    (return ())
    (return (Error () \"Unexpected error\")) ))))");

!(chain (eval (foo $a)) $_ $a)

calling (foo $a) adds variable equality { $a = $b } into bindings and $a is kept inside Stack::vars of the first frame because its value should be passed from the first chain's argument to the last one. After executing (chain (function (return ())) $_ bindings are being cleaned up and variable equality is removed from bindings. Thus when $b receives value it is not propagated to the $a

This fix replaces formal argument variables in a body of a called function by the actual argument value or variable. In the particular case above variable $b in (unify $b value (return ()) (return (Error () \"Unexpected error\")) ) is replaced by variable $a and value is assigned properly.

vsbogd added 4 commits June 12, 2024 12:17
Replace Bindings::retain() by Bindings::apply_and_retain() which is more
effective.
Replace formal argument variables in a body of a called function by the
actual argument value or variable. Otherwise variable equality can be
wiped during return from the nested call and assigning value to the
formal argument doesn't affect actual argument variable.
@vsbogd vsbogd requested a review from luketpeterson June 13, 2024 06:05
@vsbogd vsbogd merged commit cabe90a into trueagi-io:main Jun 13, 2024
2 checks passed
@vsbogd vsbogd deleted the fix-call-vars branch June 13, 2024 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants