Skip to content

Commit ec5fc39

Browse files
Ex10si0nzhiyuuuu
authored andcommitted
[feat] Add support to arr.filter() (including foreach, map)
1 parent 4cb0d4d commit ec5fc39

File tree

7 files changed

+594
-59
lines changed

7 files changed

+594
-59
lines changed

Strata/DL/Heap/HEval.lean

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,20 @@ partial def evalApp (state : HState) (originalExpr e1 e2 : HExpr) : HState × HE
156156
-- Second application to StringFieldAccess - return partially applied
157157
-- This handles str.fieldName where fieldName is a string literal
158158
evalStringFieldAccess state2 objExpr e2'
159+
| .deferredOp "LengthAccess" _ =>
160+
-- First application to LengthAccess - return partially applied
161+
(state2, .app (.deferredOp "LengthAccess" none) e2')
162+
| .app (.deferredOp "LengthAccess" _) objExpr =>
163+
-- Second application to LengthAccess - evaluate
164+
evalLengthAccess state2 objExpr e2'
165+
| .deferredOp "FieldDelete" _ =>
166+
-- First application to FieldDelete - return partially applied
167+
(state2, .app (.deferredOp "FieldDelete" none) e2')
168+
| .app (.deferredOp "FieldDelete" _) objExpr =>
169+
-- Second application to FieldDelete - now we can evaluate
170+
-- This handles delete obj[field] where field is dynamic
171+
evalFieldDelete state2 objExpr e2'
172+
159173
| .deferredOp op _ =>
160174
-- First application to a deferred operation - return partially applied
161175
(state2, .app (.deferredOp op none) e2')
@@ -219,6 +233,57 @@ partial def evalStringFieldAccess (state : HState) (objExpr fieldExpr : HExpr) :
219233
-- Field is not a string literal
220234
(state, .lambda (LExpr.const "error_non_literal_string_field" none))
221235

236+
-- Handle field deletion: delete obj[field]
237+
partial def evalFieldDelete (state : HState) (objExpr fieldExpr : HExpr) : HState × HExpr :=
238+
-- First try to extract a numeric field index from the field expression
239+
match extractFieldIndex fieldExpr with
240+
| some fieldIndex =>
241+
-- We have a numeric field index, delete the field
242+
match objExpr with
243+
| .address addr =>
244+
-- Delete field from the object at this address
245+
match state.deleteField addr fieldIndex with
246+
| some newState => (newState, objExpr) -- Return the object address
247+
| none => (state, .lambda (LExpr.const s!"error_cannot_delete_field_{fieldIndex}" none))
248+
| _ =>
249+
-- First evaluate the object expression to get an address
250+
let (state1, objVal) := evalHExpr state objExpr
251+
match objVal with
252+
| .address addr =>
253+
match state1.deleteField addr fieldIndex with
254+
| some newState => (newState, objVal)
255+
| none => (state1, .lambda (LExpr.const s!"error_cannot_delete_field_{fieldIndex}" none))
256+
| _ =>
257+
(state1, .lambda (LExpr.const "error_invalid_address_for_delete" none))
258+
| none =>
259+
-- Can't extract a numeric field index, return error
260+
(state, .lambda (LExpr.const "error_field_delete_failed" none))
261+
262+
-- Handle length access for both strings and arrays
263+
partial def evalLengthAccess (state : HState) (objExpr fieldExpr : HExpr) : HState × HExpr :=
264+
match fieldExpr with
265+
| .lambda (LExpr.const key _) =>
266+
if key == "length" then
267+
match objExpr with
268+
| .lambda (LExpr.const s _) =>
269+
-- String length
270+
let len := s.length
271+
(state, .lambda (LExpr.const (toString len) (some Lambda.LMonoTy.int)))
272+
| .address addr =>
273+
-- Array length
274+
match state.heap.get? addr with
275+
| some obj =>
276+
let len := obj.size
277+
(state, .lambda (LExpr.const (toString len) (some Lambda.LMonoTy.int)))
278+
| none =>
279+
(state, .lambda (LExpr.const "error_invalid_address" none))
280+
| _ =>
281+
(state, .lambda (LExpr.const "error_not_string_or_array" none))
282+
else
283+
(state, .lambda (LExpr.const "error_unknown_length_property" none))
284+
| _ =>
285+
(state, .lambda (LExpr.const "error_non_literal_field" none))
286+
222287
-- Extract a numeric field index from an expression
223288
partial def extractFieldIndex (expr : HExpr) : Option Nat :=
224289
match expr with

Strata/DL/Heap/HState.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ def setField (state : HState) (addr : Address) (field : Nat) (value : HExpr) : O
161161
some { state with heap := newHeap }
162162
| none => none
163163

164+
def deleteField (state : HState) (addr : Address) (field : Nat) : Option HState :=
165+
-- Remove the field from the object's fields
166+
-- As an example:
167+
-- before array deletion {'0': 1, '1': 5} (delete arr[1])
168+
-- after array deletion {'0': 1} instead of {'0': 1, '1': None}
169+
match state.getObject addr with
170+
| some obj =>
171+
let newObj := obj.erase field
172+
let newHeap := state.heap.insert addr newObj
173+
some { state with heap := newHeap }
174+
| none => none
175+
164176
-- Check if an address is valid (exists in heap)
165177
def isValidAddr (state : HState) (addr : Address) : Bool :=
166178
state.heap.contains addr

0 commit comments

Comments
 (0)