-
Notifications
You must be signed in to change notification settings - Fork 0
Refines Containers and Core Language Features #137
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
Changes from all commits
82e779b
1f1e50f
e3e2118
1faeb2b
4d6846a
d6c6e25
0a3beb7
9174d35
400d7ae
1d84e63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 ===" |
| 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' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainMethod inheritance lookup bug: shed_fur not found on Dog This confirms the reported inheritance issue. Likely causes:
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 || trueLength of output: 40260 Implement inherited-method merging in the analyzer and unify interpreter lookup We’ve confirmed that:
To fix: • In src/analyzer/mod.rs (around --- 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 • 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.
🤖 Prompt for AI Agents |
||
|
|
||
| === 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) | ||
| 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" |
There was a problem hiding this comment.
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
*is interpreted in your permission engine when inside quotes to avoid over-broad matching of arguments.Apply this small enhancement:
Verification script to check cwd-dependency of existing allow-list:
🏁 Script executed:
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
🤖 Prompt for AI Agents