Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"Bash(git fetch --all --prune)",
"Bash(git merge --no-ff:*)",
"Bash(git add -A)",
"Bash(git commit -m \"wfl-ai: *\")"
"Bash(git commit -m \"wfl-ai: *\")",
"Bash(../target/release/wfl.exe containers_comprehensive.wfl)"
Comment on lines +36 to +37

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Allow-list entries: confirm scope and add TestPrograms path variant for stability

  • The commit pattern looks fine, but double-check how * is interpreted in your permission engine when inside quotes to avoid over-broad matching of arguments.
  • For the new test runner entry, consider also allowing the explicit TestPrograms path to avoid cwd-dependency.

Apply this small enhancement:

       "Bash(git add -A)",
-      "Bash(git commit -m \"wfl-ai: *\")",
-      "Bash(../target/release/wfl.exe containers_comprehensive.wfl)"
+      "Bash(git commit -m \"wfl-ai: *\")",
+      "Bash(../target/release/wfl.exe containers_comprehensive.wfl)",
+      "Bash(../target/release/wfl.exe TestPrograms/containers_comprehensive.wfl)"

Verification script to check cwd-dependency of existing allow-list:


🏁 Script executed:

#!/bin/bash
# Show any allow-list entries that reference WFL execution and their arguments.
rg -n $'Bash\\(.*wfl.*\\)' .claude/settings.local.json -A 0

Length of output: 721


Add explicit TestPrograms path for containers_comprehensive and verify commit‐message wildcard

We don’t see a TestPrograms-scoped entry for containers_comprehensive.wfl, so add it to avoid cwd-dependency. Also, please confirm how your permission engine interprets * inside the quoted commit message to ensure it isn’t too permissive.

• .claude/settings.local.json
– After line 37, insert the TestPrograms variant

       "Bash(git commit -m \"wfl-ai: *\")",
       "Bash(../target/release/wfl.exe containers_comprehensive.wfl)",
+      "Bash(../target/release/wfl.exe TestPrograms/containers_comprehensive.wfl)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Bash(git commit -m \"wfl-ai: *\")",
"Bash(../target/release/wfl.exe containers_comprehensive.wfl)"
"Bash(git commit -m \"wfl-ai: *\")",
"Bash(../target/release/wfl.exe containers_comprehensive.wfl)",
"Bash(../target/release/wfl.exe TestPrograms/containers_comprehensive.wfl)"
🤖 Prompt for AI Agents
In .claude/settings.local.json around lines 36 to 37, add an explicit
TestPrograms-scoped entry for containers_comprehensive.wfl after line 37 to
avoid dependency on the current working directory. Also, review how the
permission engine interprets the asterisk (*) wildcard in the quoted commit
message to ensure it does not allow overly permissive matching. Make sure the
new entry clearly specifies the path for TestPrograms related to
containers_comprehensive.wfl.

],
"deny": []
}
Expand Down
2 changes: 1 addition & 1 deletion TestPrograms/basic_syntax_comprehensive.wfl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ display ""
display "4. Variable Redefinition Test"
store test var as "original"
display "Before: " with test var
store test var as "modified"
change test var to "modified"
display "After: " with test var
display ""

Expand Down
141 changes: 141 additions & 0 deletions TestPrograms/container_inheritance_simple.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Simple Container Inheritance Test - WFL
// Tests basic inheritance functionality without deep chains

display "=== Simple Container Inheritance Test ==="
display ""

// === Two-Level Inheritance ===
display "1. Two-Level Inheritance Test"
create container Vehicle:
property brand: Text
property model: Text

action start_engine:
display "Starting " with brand with " " with model
end

action get_info: Text
return brand with " " with model
end
end

create container Car extends Vehicle:
property doors: Number

action honk:
display brand with " " with model with " honks!"
end

action get_car_info: Text
return brand with " " with model with " (" with doors with " doors)"
end
end

create new Car as my_car:
brand is "Toyota"
model is "Camry"
doors is 4
end

display "Testing two-level inheritance:"
my_car.start_engine() // From Vehicle
my_car.honk() // From Car
display "Info: " with my_car.get_info() // From Vehicle
display "Car Info: " with my_car.get_car_info() // From Car
display ""

// === Method Override Test ===
display "2. Method Override Test"
create container Animal:
property species: Text

action make_sound:
display "The " with species with " makes a generic sound"
end
end

create container Dog extends Animal:
property breed: Text

action make_sound:
display "The " with breed with " dog barks!"
end

action fetch:
display "The " with breed with " fetches a ball"
end
end

create new Dog as my_dog:
species is "Canine"
breed is "Labrador"
end

display "Testing method override:"
my_dog.make_sound() // Should use Dog's version, not Animal's
my_dog.fetch() // Dog-specific method
display ""

// === Multiple Instances Test ===
display "3. Multiple Inheritance Instances"
create new Car as car1:
brand is "Honda"
model is "Civic"
doors is 4
end

create new Car as car2:
brand is "BMW"
model is "X5"
doors is 5
end

display "Testing multiple instances with inheritance:"
car1.start_engine()
display "Car1: " with car1.get_car_info()
car2.start_engine()
display "Car2: " with car2.get_car_info()
display ""

// === Property Access Through Inheritance ===
display "4. Property Access Through Inheritance"
create container Base:
property base_value: Number

action get_base: Number
return base_value
end

action set_base with value: Number:
store base_value as value
display "Base value set to " with base_value
end
end

create container Extended extends Base:
property extra_value: Text

action get_both: Text
return "Base: " with base_value with ", Extra: " with extra_value
end

action set_extra with value: Text:
store extra_value as value
display "Extra value set to " with extra_value
end
end

create new Extended as extended_obj:
base_value is 100
extra_value is "test"
end

display "Testing property access through inheritance:"
display "Base value: " with extended_obj.get_base()
display "Both values: " with extended_obj.get_both()
extended_obj.set_base(200)
extended_obj.set_extra("updated")
display "Updated values: " with extended_obj.get_both()
display ""

display "=== Simple Container Inheritance Tests Completed ==="
19 changes: 19 additions & 0 deletions TestPrograms/containers_comprehensive_debug.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
=== WFL Debug Report ===
Script: TestPrograms/containers_comprehensive.wfl
Time: 2025-08-10 14:22:59

=== Error Summary ===
Runtime error at line 210, column 1: Method 'shed_fur' not found in container 'Dog'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Method inheritance lookup bug: shed_fur not found on Dog

This confirms the reported inheritance issue. Likely causes:

  • Method resolution not walking parent chain for calls.
  • Parent link missing on the Dog container type during analysis.
  • Method table built only for concrete container, not merged with ancestors.

Please add an integration test that reproduces this (containers_comprehensive.wfl) and fix interpreter/analyzer lookup.

Run this to locate definitions and check hierarchy wiring:

I can help patch recursive parent lookup in interpreter/analyzer once we pinpoint the entry point.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Where is Dog defined and what's its parent?
rg -n "create container\s+Dog" -A5 TestPrograms src

# All occurrences of shed_fur (definitions and calls)
rg -n "shed_fur" -A2 -B2

# Inspect interpreter/analyzer method resolution
rg -n "lookup.*(method|action)|resolve.*(method|action)|get_.*(method|action)|find_.*(method|action)" src/interpreter src/analyzer

# Check if parent lookup is recursive
rg -n "extends|parent" -A3 -B3 src/interpreter src/analyzer

# Verify container inheritance tests exist
fd -a "container_inheritance*.wfl" TestPrograms || true

Length of output: 40260


Implement inherited-method merging in the analyzer and unify interpreter lookup

We’ve confirmed that:

  • In the static analyzer (src/analyzer/mod.rs around line 990), we only copy parent properties into the child’s ContainerInfo, but never import the parent’s methods, so calls like Dog.shed_fur() slip through static checking and then fail at runtime.
  • In the interpreter (src/interpreter/mod.rs around lines 2695–2750) there’s a “parent-only” lookup path that never checks the immediate container’s methods when instance.parent.is_some(), even though a fully recursive lookup is implemented later at lines 2935–2960.

To fix:

• In src/analyzer/mod.rs (around // Add inherited properties…), also merge inherited methods into container_info.methods and register them in the current scope. For example:

--- a/src/analyzer/mod.rs
+++ b/src/analyzer/mod.rs
@@ -989,6 +989,16 @@ impl Analyzer {
         if let Some(parent_name) = &container_info.extends
             && let Some(parent_container) = self.containers.get(parent_name)
         {
+            // inherit parent methods
+            for (m_name, m_info) in &parent_container.methods {
+                container_info.methods.insert(m_name.clone(), m_info.clone());
+                let sym = Symbol {
+                    name: m_name.clone(),
+                    kind: SymbolKind::Function { /* adjust if needed */ },
+                };
+                self.current_scope.define(sym);
+            }
             // existing property merge…
             for (prop_name, prop_info) in &parent_container.properties {
                 // …

• In src/interpreter/mod.rs (around the block that begins at line 2695), remove or refactor the “parent-only” branch so that all instance method calls—bare or via dot—use the single recursive lookup in lines 2935–2960. That ensures Dog methods run first, then its ancestors’.

• Add/extend integration tests (e.g. in TestPrograms/containers_comprehensive.wfl or container_inheritance_simple.wfl) for multi-level inheritance (Animal→Mammal→Dog), invoking parent and grandparent methods to catch regressions at both compile- and runtime.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In TestPrograms/containers_comprehensive_debug.txt at line 6, the issue is that
inherited methods are not merged into child containers during static analysis,
causing runtime errors when calling methods like Dog.shed_fur(). To fix this,
update src/analyzer/mod.rs around the section where inherited properties are
added to also merge inherited methods into container_info.methods and register
them in the current scope. Additionally, in src/interpreter/mod.rs around lines
2695 to 2750, refactor or remove the "parent-only" lookup branch so that all
instance method calls use the recursive lookup implemented later (lines
2935–2960), ensuring child container methods are checked before ancestors'.
Finally, add or extend integration tests for multi-level inheritance to verify
both compile-time and runtime correctness.


=== Stack Trace ===
In main script at line 210, column 1

=== Source Code ===
208:
209: buddy.make_sound()
>> 210: buddy.shed_fur()
211: buddy.fetch()
212: display ""

=== Local Variables ===
(No local variables in global scope)
183 changes: 183 additions & 0 deletions TestPrograms/event_system_simple.wfl
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// Simple Event System Test - WFL
// Tests basic event definitions and triggering

display "=== Simple Event System Test ==="
display ""

// === Basic Event Test ===
display "1. Basic Event Definition and Triggering"
create container SimpleButton:
property label: Text
property click_count: Number

event on_click
event on_reset

action click:
store click_count as click_count + 1
display "Button '" with label with "' clicked " with click_count with " times"
trigger on_click
end

action reset:
store click_count as 0
display "Button '" with label with "' reset"
trigger on_reset
end
end

create new SimpleButton as btn:
label is "Test Button"
click_count is 0
end

display "Testing basic event triggering:"
btn.click()
btn.click()
btn.click()
btn.reset()
btn.click()
display ""

// === Multiple Event Types ===
display "2. Multiple Event Types"
create container SimplePlayer:
property title: Text
property playing: Boolean

event on_play
event on_stop

action play:
check if not playing:
store playing as yes
display "▶️ Playing: " with title
trigger on_play
otherwise:
display "Already playing: " with title
end check
end

action stop:
store playing as no
display "⏹️ Stopped: " with title
trigger on_stop
end
end

create new SimplePlayer as player:
title is "Test Song"
playing is no
end

display "Testing multiple event types:"
player.play()
player.play() // Should show "Already playing"
player.stop()
player.play()
display ""

// === Event Inheritance ===
display "3. Event Inheritance"
create container BaseComponent:
property visible: Boolean

event on_show
event on_hide

action show:
store visible as yes
display "Component shown"
trigger on_show
end

action hide:
store visible as no
display "Component hidden"
trigger on_hide
end
end

create container TextComponent extends BaseComponent:
property text_data: Text

event on_text_data_change

action set_text_data with new_text_data: Text:
store text_data as new_text_data
display "Content changed to: '" with text_data with "'"
trigger on_text_data_change
end

// Override parent method and add event
action show:
store visible as yes
display "TextComponent shown with text_data: '" with text_data with "'"
trigger on_show
end
end

create new TextComponent as text_comp:
visible is no
text_data is "Hello World"
end

display "Testing event inheritance:"
text_comp.show() // Uses overridden method, triggers inherited event
text_comp.set_text_data("Updated text")
text_comp.hide() // Uses inherited method and event
display ""

// === Conditional Event Triggering ===
display "4. Conditional Event Triggering"
create container Counter:
property value: Number
property max_value: Number

event on_increment
event on_max_reached
event on_reset

action increment:
check if value is less than max_value:
store value as value + 1
display "Counter incremented to " with value
trigger on_increment

check if value is max_value:
display "Maximum value reached!"
trigger on_max_reached
end check
otherwise:
display "Counter already at maximum value (" with max_value with ")"
end check
end

action reset:
store value as 0
display "Counter reset to 0"
trigger on_reset
end
end

create new Counter as counter:
value is 0
max_value is 3
end

display "Testing conditional event triggering:"
counter.increment() // Should trigger on_increment
counter.increment() // Should trigger on_increment
counter.increment() // Should trigger on_increment AND on_max_reached
counter.increment() // Should show "already at maximum"
counter.reset() // Should trigger on_reset
counter.increment() // Should work again
display ""

display "=== Simple Event System Tests Completed ==="
display ""
display "Event System Features Tested:"
display "✓ Basic event definition and triggering"
display "✓ Multiple event types in single container"
display "✓ Event inheritance from parent containers"
display "✓ Conditional event triggering based on state"
Loading
Loading