Skip to content

Commit

Permalink
Port cell.bal from nBallerina
Browse files Browse the repository at this point in the history
  • Loading branch information
lochana-chathura committed Mar 6, 2024
1 parent c3e746c commit f519976
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 28 deletions.
65 changes: 65 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/CellAtomicType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.ballerina.types;

/**
* CellAtomicType node.
*
* @since 2201.10.0
*/
public final class CellAtomicType implements AtomicType {
public final SemType ty;
public final CellMutability mut;

public static final CellAtomicType CELL_ATOMIC_VAL = from(PredefinedType.TOP, CellMutability.CELL_MUT_LIMITED);
public static final CellAtomicType CELL_ATOMIC_NEVER = from(PredefinedType.NEVER, CellMutability.CELL_MUT_LIMITED);

private CellAtomicType(SemType ty, CellMutability mut) {
this.ty = ty;
this.mut = mut;
}

public static CellAtomicType from(SemType ty, CellMutability mut) {
return new CellAtomicType(ty, mut);
}

public enum CellMutability {
CELL_MUT_NONE(0),
CELL_MUT_LIMITED(1),
CELL_MUT_UNLIMITED(2);

private final int value;

CellMutability(int value) {
this.value = value;
}

public int getValue() {
return value;
}

public static CellMutability fromValue(int value) {
for (CellMutability mutability : values()) {
if (mutability.value == value) {
return mutability;
}
}
throw new IllegalArgumentException("No enum constant with value " + value);
}
}
}
31 changes: 31 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/CellSemType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.ballerina.types;

/**
* This is to represent a SemType belonging to cell basic type.
*
* @since 2201.10.0
*/
public class CellSemType extends ComplexSemType {

public CellSemType(ProperSubtypeData[] subtypeDataList) {
super(UniformTypeBitSet.from(0), PredefinedType.CELL, subtypeDataList);
assert subtypeDataList.length == 1;
}
}
22 changes: 21 additions & 1 deletion semtypes/src/main/java/io/ballerina/types/Common.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
import static io.ballerina.types.Conjunction.and;
import static io.ballerina.types.UniformTypeCode.UT_LIST_RO;
import static io.ballerina.types.UniformTypeCode.UT_LIST_RW;
import static io.ballerina.types.typeops.BddCommonOps.bddDiff;
import static io.ballerina.types.typeops.BddCommonOps.bddIntersect;
import static io.ballerina.types.typeops.BddCommonOps.bddNodeComplement;
import static io.ballerina.types.typeops.BddCommonOps.bddUnion;

/**
* Code common to implementation of multiple basic types.
Expand Down Expand Up @@ -125,7 +129,7 @@ && bddEveryPositive(cx, bn.middle, pos, neg, predicate)
Instead, we transform the BDD to avoid cases that would give the wrong answer.
Atom index 0 is LIST_SUBTYPE_RO and MAPPING_SUBTYPE_RO */
public static Bdd bddFixReadOnly(Bdd b) {
return bddPosMaybeEmpty(b) ? BddCommonOps.bddIntersect(b, BddCommonOps.bddAtom(RecAtom.createRecAtom(0))) : b;
return bddPosMaybeEmpty(b) ? bddIntersect(b, BddCommonOps.bddAtom(RecAtom.createRecAtom(0))) : b;
}

public static boolean bddPosMaybeEmpty(Bdd b) {
Expand All @@ -144,6 +148,22 @@ public static Conjunction andIfPositive(Atom atom, Conjunction next) {
return and(atom, next);
}

public static SubtypeData bddSubtypeUnion(ProperSubtypeData t1, ProperSubtypeData t2) {
return bddUnion((BddNode) t1, (BddNode) t2);
}

public static SubtypeData bddSubtypeIntersect(ProperSubtypeData t1, ProperSubtypeData t2) {
return bddIntersect((BddNode) t1, (BddNode) t2);
}

public static SubtypeData bddSubtypeDiff(ProperSubtypeData t1, ProperSubtypeData t2) {
return bddDiff((BddNode) t1, (BddNode) t2);
}

public static SubtypeData bddSubtypeComplement(ProperSubtypeData t) {
return bddNodeComplement((BddNode) t);
}

public static SemType[] shallowCopyTypes(SemType[] v) {
return Arrays.copyOf(v, v.length);
}
Expand Down
4 changes: 4 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ public static boolean isSubtypeSimple(SemType t1, UniformTypeBitSet t2) {
return (bits & ~t2.bitset) == 0;
}

public static boolean isSameType(Context context, SemType t1, SemType t2) {
return isSubtype(context, t1, t2) && isSubtype(context, t2, t1);
}

public static UniformTypeBitSet widenToBasicTypes(SemType t) {
if (t instanceof UniformTypeBitSet uniformTypeBitSet) {
return uniformTypeBitSet;
Expand Down
8 changes: 8 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/Env.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ public TypeAtom mappingAtom(MappingAtomicType atomicType) {
return this.typeAtom(atomicType);
}

public TypeAtom cellAtom(CellAtomicType atomicType) {
return this.typeAtom(atomicType);
}

private TypeAtom typeAtom(AtomicType atomicType) {
synchronized (this.atomTable) {
TypeAtom ta = this.atomTable.get(atomicType);
Expand Down Expand Up @@ -147,6 +151,10 @@ public MappingAtomicType getRecMappingAtomType(RecAtom ra) {
}
}

public static CellAtomicType cellAtomType(Atom atom) {
return (CellAtomicType) ((TypeAtom) atom).atomicType;
}

public void addTypeDef(String typeName, SemType semType) {
this.types.put(typeName, semType);
}
Expand Down
2 changes: 2 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/PredefinedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public class PredefinedType {
public static final UniformTypeBitSet STREAM = uniformType(UniformTypeCode.UT_STREAM);
public static final UniformTypeBitSet FUTURE = uniformType(UniformTypeCode.UT_FUTURE);

public static final UniformTypeBitSet CELL = uniformType(UniformTypeCode.BT_CELL);

// this is SubtypeData|error
public static final UniformTypeBitSet TOP = uniformTypeUnion(UniformTypeCode.UT_MASK);
public static final UniformTypeBitSet ANY =
Expand Down
2 changes: 1 addition & 1 deletion semtypes/src/main/java/io/ballerina/types/SemTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static boolean isSubtypeSimple(SemType t1, UniformTypeBitSet t2) {
}

public static boolean isSameType(Context context, SemType t1, SemType t2) {
return isSubtype(context, t1, t2) && isSubtype(context, t2, t1);
return Core.isSameType(context, t1, t2);
}

public static SemType errorDetail(SemType detail) {
Expand Down
6 changes: 6 additions & 0 deletions semtypes/src/main/java/io/ballerina/types/TypeAtom.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/
package io.ballerina.types;

import static io.ballerina.types.CellAtomicType.CELL_ATOMIC_NEVER;
import static io.ballerina.types.CellAtomicType.CELL_ATOMIC_VAL;

/**
* Represent a TypeAtom.
*
Expand All @@ -26,6 +29,9 @@ public class TypeAtom implements Atom {
public final long index;
public final AtomicType atomicType;

public static final TypeAtom ATOM_CELL_VAL = createTypeAtom(0, CELL_ATOMIC_VAL);
public static final TypeAtom ATOM_CELL_NEVER = createTypeAtom(1, CELL_ATOMIC_NEVER);

private TypeAtom(long index, AtomicType atomicType) {
this.index = index;
this.atomicType = atomicType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public class UniformTypeCode {
public static final UniformTypeCode UT_XML_RW = from(0x15);
public static final UniformTypeCode UT_OBJECT_RW = from(0x16);

// Non-val
public static final UniformTypeCode BT_CELL = from(0x11);

// Helper bit fields (does not represent uniform type tag)
static final int UT_COUNT = UT_OBJECT_RW.code + 1;
static final int UT_MASK = (1 << UT_COUNT) - 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.ballerina.types.subtypedata;

import io.ballerina.types.CellAtomicType;
import io.ballerina.types.CellSemType;
import io.ballerina.types.ComplexSemType;
import io.ballerina.types.Env;
import io.ballerina.types.PredefinedType;
import io.ballerina.types.SemType;
import io.ballerina.types.TypeAtom;
import io.ballerina.types.UniformTypeCode;

import static io.ballerina.types.typeops.BddCommonOps.bddAtom;

/**
* CellSubType.
*
* @since 2201.10.0
*/
public class CellSubtype {

public static CellSemType cellContaining(Env env, SemType ty, CellAtomicType.CellMutability mut) {
CellAtomicType atomicCell = CellAtomicType.from(ty, mut);
TypeAtom atom = env.cellAtom(atomicCell);
BddNode bdd = bddAtom(atom);
ComplexSemType complexSemType = (ComplexSemType) PredefinedType.uniformSubtype(UniformTypeCode.BT_CELL, bdd);
return new CellSemType(complexSemType.subtypeDataList);
}
}
55 changes: 29 additions & 26 deletions semtypes/src/main/java/io/ballerina/types/typeops/BddCommonOps.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,32 +143,35 @@ public static Bdd bddComplement(Bdd b) {
if (b instanceof BddAllOrNothing) {
return ((BddAllOrNothing) b).complement();
} else {
BddNode bdd = (BddNode) b;
BddAllOrNothing bddNothing = BddAllOrNothing.bddNothing();
if (bdd.right.equals(bddNothing)) {
return bddCreate(bdd.atom,
bddNothing,
bddComplement(bddUnion(bdd.left, bdd.middle)),
bddComplement(bdd.middle));
} else if (bdd.left.equals(bddNothing)) {
return bddCreate(bdd.atom,
bddComplement(bdd.middle),
bddComplement(bddUnion(bdd.right, bdd.middle)),
bddNothing);
} else if (bdd.middle.equals(bddNothing)) {
return bddCreate(bdd.atom,
bddComplement(bdd.left),
bddComplement(bddUnion(bdd.left, bdd.right)),
bddComplement(bdd.right));
} else {
// There is a typo in the Frisch PhD thesis for this formula.
// (It has left and right swapped.)
// Castagna (the PhD supervisor) confirms that this is the correct formula.
return bddCreate(bdd.atom,
bddComplement(bddUnion(bdd.left, bdd.middle)),
bddNothing,
bddComplement(bddUnion(bdd.right, bdd.middle)));
}
return bddNodeComplement((BddNode) b);
}
}

public static Bdd bddNodeComplement(BddNode b) {
BddAllOrNothing bddNothing = BddAllOrNothing.bddNothing();
if (b.right.equals(bddNothing)) {
return bddCreate(b.atom,
bddNothing,
bddComplement(bddUnion(b.left, b.middle)),
bddComplement(b.middle));
} else if (b.left.equals(bddNothing)) {
return bddCreate(b.atom,
bddComplement(b.middle),
bddComplement(bddUnion(b.right, b.middle)),
bddNothing);
} else if (b.middle.equals(bddNothing)) {
return bddCreate(b.atom,
bddComplement(b.left),
bddComplement(bddUnion(b.left, b.right)),
bddComplement(b.right));
} else {
// There is a typo in the Frisch PhD thesis for this formula.
// (It has left and right swapped.)
// Castagna (the PhD supervisor) confirms that this is the correct formula.
return bddCreate(b.atom,
bddComplement(bddUnion(b.left, b.middle)),
bddNothing,
bddComplement(bddUnion(b.right, b.middle)));
}
}

Expand Down
Loading

0 comments on commit f519976

Please sign in to comment.