Skip to content

Commit

Permalink
Implement wasm/EJsonRuntime(Contains|Length|Substring|SubstringEnd|St…
Browse files Browse the repository at this point in the history
…ringJoin) operators
  • Loading branch information
pkel committed May 31, 2021
1 parent 880d5dc commit 4466a28
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 18 deletions.
62 changes: 44 additions & 18 deletions runtimes/assemblyscript/assembly/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ const c_0 = new EjNumber(0);
export class EjBigInt extends EjValue {
value: i64
constructor(a: i64) { super(); this.value = a; }

safe_to_i32() : i32 {
if (this.value > I32.MAX_VALUE || this.value < I32.MIN_VALUE) {
throw new Error("EjBigInt: cannot convert to i32");
} else {
return <i32>this.value;
}
}
}
export const IdEjBigInt = idof<EjBigInt>()
export function ejBigInt_of_f64(x: f64) : EjBigInt {
Expand All @@ -53,6 +61,7 @@ export class EjString extends EjValue {
constructor(a: string) { super(); this.value = a; }
}
export const IdEjString = idof<EjString>()
const c_empty_string = new EjString("")

export class EjArray extends EjValue {
values: Array<EjValue>
Expand Down Expand Up @@ -505,60 +514,64 @@ export function opMathTrunc(a: EjNumber): EjNumber {
// EJson Runtime Operators //
/////////////////////////////

export function runtimeEqual(a: EjValue, b: EjValue): EjBool {
function equal(a: EjValue, b: EjValue): boolean {
if (a instanceof EjNull && b instanceof EjNull) {
return c_true;
return true;
}
if (a instanceof EjBool && b instanceof EjBool) {
let aa : EjBool = changetype<EjBool>(a) ;
let bb : EjBool = changetype<EjBool>(b) ;
return aa.value == bb.value ? c_true : c_false;
return aa.value == bb.value ? true : false;
}
if (a instanceof EjNumber && b instanceof EjNumber) {
let aa : EjNumber = changetype<EjNumber>(a) ;
let bb : EjNumber = changetype<EjNumber>(b) ;
return aa.value == bb.value ? c_true : c_false;
return aa.value == bb.value ? true : false;
}
if (a instanceof EjBigInt && b instanceof EjBigInt) {
let aa : EjBigInt = changetype<EjBigInt>(a) ;
let bb : EjBigInt = changetype<EjBigInt>(b) ;
return aa.value == bb.value ? c_true : c_false;
return aa.value == bb.value ? true : false;
}
if (a instanceof EjString && b instanceof EjString) {
let aa : EjString = changetype<EjString>(a) ;
let bb : EjString = changetype<EjString>(b) ;
return aa.value == bb.value ? c_true : c_false;
return aa.value == bb.value ? true : false;
}
if (a instanceof EjArray && b instanceof EjArray) {
let aa : EjArray = changetype<EjArray>(a) ;
let bb : EjArray = changetype<EjArray>(b) ;
if (aa.values.length != bb.values.length) {
return c_false;
return false;
}
for (let i = 0; i < aa.values.length; i++) {
if (! runtimeEqual(aa.values[i], bb.values[i]).value) {
return c_false;
return false;
}
}
return c_true;
return true;
}
if (a instanceof EjObject && b instanceof EjObject) {
let aa : EjObject = changetype<EjObject>(a) ;
let bb : EjObject = changetype<EjObject>(b) ;
if (aa.values.size != bb.values.size) {
return c_false;
return false;
}
let keys = aa.values.keys();
for (let i = 0; i < keys.length; i++) {
let k = keys[i];
if (! bb.values.has(k) ||
! runtimeEqual(aa.values[k], bb.values[k]).value ) {
return c_false;
return false;
}
}
return c_true;
return true;
}
return c_false;
return false;
}

export function runtimeEqual(a: EjValue, b: EjValue): EjBool {
return equal(a, b) ? c_true : c_false;
}

// This is actually a compare negative.
Expand Down Expand Up @@ -998,7 +1011,10 @@ export function runtimeCount(a: EjArray) : EjBigInt {
}

export function runtimeContains(a: EjValue, b: EjArray) : EjBool {
throw new Error('runtimeContains: not implemented');
for (let i=0; i < b.values.length; i++) {
if (equal(a, b.values[i])) { return c_true; }
}
return c_false;
}

export function runtimeSort(a: EjArray, b: EjNull) : EjArray {
Expand All @@ -1010,19 +1026,29 @@ export function runtimeGroupBy(a: EjArray, b: EjNull, c:EjNull) : EjArray {
}

export function runtimeLength(a: EjString) : EjBigInt {
throw new Error('runtimeLength: not implemented');
return new EjBigInt(a.value.length);
}

export function runtimeSubstring(a: EjString, start: EjBigInt, len:EjBigInt) : EjString {
throw new Error('runtimeSubstring: not implemented');
let istart = start.safe_to_i32();
let iend = istart + len.safe_to_i32();
return new EjString(a.value.substring(istart, iend));
}

export function runtimeSubstringEnd(a: EjString, start: EjBigInt) : EjString {
throw new Error('runtimeSubstringEnd: not implemented');
return new EjString(a.value.substring(start.safe_to_i32()));
}

export function runtimeStringJoin(sep: EjString, a: EjArray): EjString {
throw new Error('runtimeStringJoin: not implemented');
let v = a.values;
if (v.length < 1) { return c_empty_string; }
let i = 0;
let r = cast<EjString>(v[i++]).value;
while (i < v.length) {
r += sep.value;
r += cast<EjString>(v[i++]).value;
}
return new EjString(r);
}

export function runtimeLike(reg: EjString, target:EjString): EjBool {
Expand Down
Binary file modified runtimes/assemblyscript/runtime.wasm
Binary file not shown.
49 changes: 49 additions & 0 deletions tests/operators/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,55 @@ let _ =
; [ arr [null] ]
; [ arr [] ]
];
test_rtop
EJsonRuntimeContains
[ [ null; arr [] ]
; [ null; arr [null] ]
; [ null; arr [bool true] ]
; [ bool true; arr [bool true; bool false] ]
; [ bool false; arr [bool true; null] ]
; [ int 0; arr [int 0; int 1; int 2] ]
; [ int 1; arr [int 0; int 1; int 2] ]
; [ int 2; arr [int 0; int 1; int 2] ]
; [ int 3; arr [int 0; int 1; int 2] ]
];
test_rtop
EJsonRuntimeLength
[ [ str "" ]
; [ str "a" ]
; [ str "abcc" ]
(* ; [ str "abccᵤ" ] *) (* Coq uses char list, JS/Wasm use UTF16. *)
];
test_rtop
EJsonRuntimeSubstring (* string, start, target length *)
[ [ str "" ; int 0; int 0 ]
; [ str "" ; int 1; int 1 ]
; [ str "" ; int 1; int (-1) ]
; [ str "0" ; int 0; int 1 ]
; [ str "0" ; int 0; int 0 ]
; [ str "0" ; int 0; int (-1) ]
; [ str "012345" ; int 0; int 3 ]
; [ str "012345" ; int 2; int 3 ]
; [ str "012345" ; int 0; int 6 ]
];
test_rtop
EJsonRuntimeSubstringEnd
[ [ str "" ; int 0]
; [ str "" ; int 1]
; [ str "0" ; int 0]
; [ str "012345" ; int 0]
; [ str "012345" ; int 2]
; [ str "012345" ; int 5]
; [ str "012345" ; int 6]
];
test_rtop
EJsonRuntimeStringJoin (* sep, string array *)
[ [ str ""; arr [] ]
; [ str "_"; arr [] ]
; [ str "_"; arr [str "-"] ]
; [ str "_"; arr [str "-"; str "-"] ]
; [ str "/"; arr [str "a"; str "b"; str "c"] ]
];
test_rtop
EJsonRuntimeNatPlus
[ [int 41; int 1]
Expand Down

0 comments on commit 4466a28

Please sign in to comment.