1
+ Require Import LibInt.
1
2
Require Import JsNumber.
2
3
Require Import String.
3
4
Require Import Store.
@@ -123,6 +124,13 @@ Definition pretty runs store v :=
123
124
(Context .add_value_return store Undefined)
124
125
.
125
126
127
+ Definition strlen store v :=
128
+ match v with
129
+ | String s => add_value_return store (Number (JsNumber.of_int (String.length s)))
130
+ | _ => (store, Fail value_loc "strlen got non-string.")
131
+ end
132
+ .
133
+
126
134
Definition numstr_to_num store (v : Values.value) :=
127
135
match v with
128
136
| String "" => Context .add_value_return store (Number JsNumber.zero)
@@ -143,6 +151,7 @@ Definition unary (op : string) runs store v_loc : (Store.store * (@Context.resul
143
151
match op with
144
152
| "print" => print store v
145
153
| "pretty" => pretty runs store v
154
+ | "strlen" => strlen store v
146
155
| "typeof" => typeof store v
147
156
| "abs" => unary_arith store JsNumber.absolute v
148
157
| "void" => void store v
@@ -249,17 +258,33 @@ Definition string_plus store v1 v2 : (Store.store * Context.result Values.value_
249
258
end
250
259
.
251
260
261
+ Parameter _nat_of_float : number -> nat.
262
+
263
+ Definition char_at store v1 v2 :=
264
+ match (v1, v2) with
265
+ | (Values.String s, Number n) =>
266
+ match (String.get (_nat_of_float n) s) with
267
+ | Some char => add_value_return store (Values.String (String.String char String.EmptyString))
268
+ | None => (store, Fail Values.value_loc "char_at called with index larger than length.")
269
+ end
270
+ | _ => (store, Fail Values.value_loc "char_at called with wrong argument types.")
271
+ end
272
+ .
273
+
252
274
Definition arith store (op : number -> number -> number) (v1 v2 : Values.value) : (Store.store * Context .result Values.value_loc) :=
253
275
match (v1, v2) with
254
276
| (Number n1, Number n2) => Context .add_value_return store (Number (op n1 n2))
255
277
| _ => (store, Fail Values.value_loc "Arithmetic with non-numbers.")
256
278
end
257
279
.
258
280
259
- Definition cmp store (op : number -> number -> bool) (v1 v2 : Values.value) : (Store.store * Context .result Values.value_loc) :=
281
+ Definition cmp store undef_left undef_both undef_right (op : number -> number -> bool) (v1 v2 : Values.value) : (Store.store * Context .result Values.value_loc) :=
260
282
match (v1, v2) with
261
283
| (Number n1, Number n2) => Context .add_value_return store (if (op n1 n2) then True else False)
262
- | _ => (store, Fail Values.value_loc "Comparison of non-numbers.")
284
+ | (Undefined, Number _) => Context .add_value_return store undef_left
285
+ | (Undefined, Undefined) => Context .add_value_return store undef_both
286
+ | (Number _, Undefined) => Context .add_value_return store undef_right
287
+ | _ => (store, Fail Values.value_loc "Comparison/order of non-numbers.")
263
288
end
264
289
.
265
290
@@ -277,14 +302,15 @@ Definition binary (op : string) runs store v1_loc v2_loc : (Store.store * (Conte
277
302
| "*" => arith store JsNumber.mult v1 v2
278
303
| "/" => arith store JsNumber.div v1 v2
279
304
| "%" => arith store JsNumber.fmod v1 v2
280
- | "<" => cmp store JsNumber.lt_bool v1 v2
281
- | "<=" => cmp store le_bool v1 v2
282
- | ">" => cmp store gt_bool v1 v2
283
- | ">=" => cmp store ge_bool v1 v2
305
+ | "<" => cmp store True False False JsNumber.lt_bool v1 v2
306
+ | "<=" => cmp store True True False le_bool v1 v2
307
+ | ">" => cmp store False False True gt_bool v1 v2
308
+ | ">=" => cmp store False True True ge_bool v1 v2
284
309
| "stx=" => stx_eq store v1 v2
285
310
| "hasProperty" => has_property runs store v1_loc v2
286
311
| "hasOwnProperty" => has_own_property store v1 v2
287
312
| "string+" => string_plus store v1 v2
313
+ | "char-at" => char_at store v1 v2
288
314
| "__prop->obj" => prop_to_obj store v1 v2 (* For debugging purposes *)
289
315
| _ => (store, Context .Fail Values.value_loc ("Binary operator " ++ op ++ " not implemented."))
290
316
end
0 commit comments