1+ Require Import LibInt.
12Require Import JsNumber.
23Require Import String.
34Require Import Store.
@@ -123,6 +124,13 @@ Definition pretty runs store v :=
123124 (Context .add_value_return store Undefined)
124125.
125126
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+
126134Definition numstr_to_num store (v : Values.value) :=
127135 match v with
128136 | 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
143151 match op with
144152 | "print" => print store v
145153 | "pretty" => pretty runs store v
154+ | "strlen" => strlen store v
146155 | "typeof" => typeof store v
147156 | "abs" => unary_arith store JsNumber.absolute v
148157 | "void" => void store v
@@ -249,17 +258,33 @@ Definition string_plus store v1 v2 : (Store.store * Context.result Values.value_
249258 end
250259.
251260
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+
252274Definition arith store (op : number -> number -> number) (v1 v2 : Values.value) : (Store.store * Context .result Values.value_loc) :=
253275 match (v1, v2) with
254276 | (Number n1, Number n2) => Context .add_value_return store (Number (op n1 n2))
255277 | _ => (store, Fail Values.value_loc "Arithmetic with non-numbers.")
256278 end
257279.
258280
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) :=
260282 match (v1, v2) with
261283 | (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.")
263288 end
264289.
265290
@@ -277,14 +302,15 @@ Definition binary (op : string) runs store v1_loc v2_loc : (Store.store * (Conte
277302 | "*" => arith store JsNumber.mult v1 v2
278303 | "/" => arith store JsNumber.div v1 v2
279304 | "%" => 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
284309 | "stx=" => stx_eq store v1 v2
285310 | "hasProperty" => has_property runs store v1_loc v2
286311 | "hasOwnProperty" => has_own_property store v1 v2
287312 | "string+" => string_plus store v1 v2
313+ | "char-at" => char_at store v1 v2
288314 | "__prop->obj" => prop_to_obj store v1 v2 (* For debugging purposes *)
289315 | _ => (store, Context .Fail Values.value_loc ("Binary operator " ++ op ++ " not implemented."))
290316 end
0 commit comments