keisan 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11f1a2644fbb02817db69dd289564d6fdb9bfd09d294cda62b07156723aebc0e
4
- data.tar.gz: 4b9787c0d558af15d466759e40fe4cfac35131d254d227416144588256e5ea9f
3
+ metadata.gz: e9daac57399adbc7f0028c078c8ec1a74e6a5b7222f2473a871d2ca7ae46c1e4
4
+ data.tar.gz: 2ffd26dec791b8a88e1edce5aeaf331622ccbb2403b5f17185d3aad36065c173
5
5
  SHA512:
6
- metadata.gz: 8149fee69d598164334b96f8be59b9763168af97e3803c9abea7285da5ed1d90bb9f87710a3de94498461baec65db335168f8e721fe73c4a837c684a30bc4114
7
- data.tar.gz: 8a4e301fb14461b164bf0331684fe7ebe3cd660d4abd38f3c44aba5f50fbed58b6b945082accdf13f9da55bcb76579890fd63db75e8b17e5c098c52d0e2d80ae
6
+ metadata.gz: 90b892b2b7602af3406bdbd84b18d211e790afcf185268f3d84800d8fe390d099870053e39f39d2c46e82da0ba7b185597c1d462af359a1fdb7a0f3aad07c80a
7
+ data.tar.gz: 29175b77265433e8e619a098e7e862472c7575bc2de91b38ed8e853355e3a133da5a33f6e43a321295cbff0a900e41502885c1fc4dbe649431fadc1baa767469
@@ -49,11 +49,13 @@ module Keisan
49
49
  end
50
50
 
51
51
  def unbound_variables(context = nil)
52
- variables = super(context)
52
+ context ||= Context.new
53
+
53
54
  if is_variable_definition?
54
- variables.delete(children.first.name)
55
+ variable_assignment_unbound_variables(context)
55
56
  else
56
- variables
57
+ # TODO: Should update to handle function / list assignment.
58
+ super(context)
57
59
  end
58
60
  end
59
61
 
@@ -70,6 +72,10 @@ module Keisan
70
72
  children.first.is_a?(Variable)
71
73
  end
72
74
 
75
+ def variable_name
76
+ children.first.name
77
+ end
78
+
73
79
  def is_function_definition?
74
80
  children.first.is_a?(Function)
75
81
  end
@@ -78,6 +84,10 @@ module Keisan
78
84
  children.first.is_a?(List)
79
85
  end
80
86
 
87
+ def rhs_unbound_variables(context = nil)
88
+ children.last.unbound_variables(context)
89
+ end
90
+
81
91
  private
82
92
 
83
93
  def evaluate_variable_assignment(context, lhs, rhs)
@@ -96,6 +106,16 @@ module Keisan
96
106
  def evaluate_cell_assignment(context, lhs, rhs)
97
107
  CellAssignment.new(self, context, lhs, rhs).evaluate
98
108
  end
109
+
110
+ def variable_assignment_unbound_variables(context)
111
+ rhs = rhs_unbound_variables(context)
112
+ # If the right-side is fully defined, then this is a valid assignment.
113
+ if rhs.empty?
114
+ Set.new
115
+ else
116
+ rhs | Set.new([variable_name])
117
+ end
118
+ end
99
119
  end
100
120
  end
101
121
  end
@@ -20,9 +20,49 @@ module Keisan
20
20
  evaluate(context)
21
21
  end
22
22
 
23
+ def unbound_variables(context = nil)
24
+ context ||= Context.new
25
+ defined_variables = Set.new
26
+
27
+ children.inject(Set.new) do |unbound_vars, child|
28
+ if child.is_a?(Assignment) && child.is_variable_definition?
29
+ line_unbound_vars = unbound_variables_for_line_variable_assignment(context, child, unbound_vars, defined_variables)
30
+ if line_unbound_vars.empty?
31
+ defined_variables.add(child.variable_name)
32
+ end
33
+ unbound_vars | line_unbound_vars
34
+ else
35
+ unbound_vars | (child.unbound_variables(context) - defined_variables)
36
+ end
37
+ end
38
+ end
39
+
23
40
  def to_s
24
41
  children.map(&:to_s).join(";")
25
42
  end
43
+
44
+ private
45
+
46
+ def unbound_variables_for_line_variable_assignment(context, line, unbound_vars, defined_variables)
47
+ child_unbound_variables = variable_assignment_unbound_variables(context, line, defined_variables)
48
+ if child_unbound_variables.empty?
49
+ defined_variables.add(line.variable_name)
50
+ unbound_vars
51
+ else
52
+ unbound_vars | child_unbound_variables
53
+ end
54
+ end
55
+
56
+ def variable_assignment_unbound_variables(context, assignment, defined_variables)
57
+ rhs_child_unbound_variables = assignment.rhs_unbound_variables(context) - defined_variables
58
+
59
+ # If there are no unbound variables, this is a properly bound assignment.
60
+ if rhs_child_unbound_variables.empty?
61
+ Set.new
62
+ else
63
+ Set.new([assignment.variable_name]) | rhs_child_unbound_variables
64
+ end
65
+ end
26
66
  end
27
67
  end
28
68
  end
@@ -1,3 +1,3 @@
1
1
  module Keisan
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keisan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Locke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-01 00:00:00.000000000 Z
11
+ date: 2024-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmath