Skip to content

Commit

Permalink
support java collections
Browse files Browse the repository at this point in the history
  • Loading branch information
tranleduy2000 committed Jun 17, 2017
1 parent 1c96108 commit 3727000
Show file tree
Hide file tree
Showing 24 changed files with 316 additions and 177 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
*/
public class CastObjectFunction implements IMethodDeclaration {

private ArgumentType[] argumentTypes =
{new RuntimeType(new JavaClassBasedType(Object.class), true),
new RuntimeType(new JavaClassBasedType(Object.class), false)};
private static final ArgumentType[] ARGUMENT_TYPES =
{new RuntimeType(new JavaClassBasedType(Object.class), true), //target
new RuntimeType(new JavaClassBasedType(Object.class), false)}; //other

@Override
public String getName() {
Expand All @@ -67,7 +67,7 @@ public FunctionCall generatePerfectFitCall(LineInfo line, RuntimeValue[] values,

@Override
public ArgumentType[] argumentTypes() {
return argumentTypes;
return ARGUMENT_TYPES;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,40 @@ public static BinaryOperatorEval generateOp(@NonNull ExpressionContext context,
|| operatorTypes == OperatorTypes.NOTEQUAL) {
return new JavaBiOperatorEval(v1, v2, operatorTypes, line);
}
} else if (t1 instanceof EnumGroupType
}
if (t1 instanceof EnumGroupType
&& t2 instanceof SetType) {
RuntimeValue converted = ((SetType) t2).getElementType().convert(v1, context);
if (converted != null) {
if (operatorTypes == OperatorTypes.IN) {
return new InBiOperatorEval(converted, v2, operatorTypes, line);
}
}
} else if (t1 instanceof EnumGroupType && t2 instanceof EnumGroupType) {
}
if (t1 instanceof EnumGroupType && t2 instanceof EnumGroupType) {
if (t1.equals(t2)) {
return new EnumBiOperatorEval(v1, v2, operatorTypes, line);
}
} else if (t1 instanceof EnumGroupType && t2.equals(BasicType.Integer)) {
}
if (t1 instanceof EnumGroupType && t2.equals(BasicType.Integer)) {
return new EnumBiOperatorEval(v1, v2, operatorTypes, line);
} else if (t1 instanceof SetType && t2 instanceof SetType) {
}
if (t1 instanceof SetType && t2 instanceof SetType) {

if (((SetType) t1).getElementType().equals(((SetType) t2).getElementType())) {
return new SetBiOperatorEval(v1, v2, operatorTypes, line);
}

} else if (t2 instanceof SetType) {
}
if (t2 instanceof SetType) {
if (operatorTypes == OperatorTypes.IN) {
if (t1.equals(((SetType) t2).getElementType())) {
return new InBiOperatorEval(v1, v2, operatorTypes, line);
}
}

} else if (t1.equals(BasicType.StringBuilder) || t2.equals(BasicType.StringBuilder)) {
}
if (t1.equals(BasicType.StringBuilder) || t2.equals(BasicType.StringBuilder)) {
if (operatorTypes == OperatorTypes.PLUS) {
v1 = new AnyToStringType(v1);
v2 = new AnyToStringType(v2);
Expand All @@ -122,32 +128,37 @@ public static BinaryOperatorEval generateOp(@NonNull ExpressionContext context,
operatorTypes);
}
}
} else if (t1.equals(BasicType.Double) || t2.equals(BasicType.Double)) {
}
if (t1.equals(BasicType.Double) || t2.equals(BasicType.Double)) {

v1 = TypeConverter.forceConvertRequired(BasicType.Double, v1, t1, context);
v2 = TypeConverter.forceConvertRequired(BasicType.Double, v2, t2, context);
return new DoubleBiOperatorEval(v1, v2, operatorTypes, line);

} else if (t1.equals(BasicType.Long) || t2.equals(BasicType.Long)) {
}
if (t1.equals(BasicType.Long) || t2.equals(BasicType.Long)) {

v1 = TypeConverter.forceConvertRequired(BasicType.Long, v1, t1, context);
v2 = TypeConverter.forceConvertRequired(BasicType.Long, v2, t2, context);
return new LongBiOperatorEval(v1, v2, operatorTypes, line);

} else if (t1.equals(BasicType.Character) || t2.equals(BasicType.Character)) {
}
if (t1.equals(BasicType.Character) || t2.equals(BasicType.Character)) {

v1 = TypeConverter.forceConvertRequired(BasicType.Character, v1, t1, context);
v2 = TypeConverter.forceConvertRequired(BasicType.Character, v2, t2, context);

return new CharBiOperatorEval(v1, v2, operatorTypes, line);

} else if (t1.equals(BasicType.Integer) || t2.equals(BasicType.Integer)) {
}
if (t1.equals(BasicType.Integer) || t2.equals(BasicType.Integer)) {

v1 = TypeConverter.forceConvertRequired(BasicType.Integer, v1, t1, context);
v2 = TypeConverter.forceConvertRequired(BasicType.Integer, v2, t2, context);
return new IntegerBiOperatorEval(v1, v2, operatorTypes, line);

} else if (t1.equals(BasicType.Boolean) || t2.equals(BasicType.Boolean)) {
}
if (t1.equals(BasicType.Boolean) || t2.equals(BasicType.Boolean)) {

v1 = TypeConverter.forceConvertRequired(BasicType.Boolean, v1, t1, context);
v2 = TypeConverter.forceConvertRequired(BasicType.Boolean, v2, t2, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import com.duy.pascal.backend.builtin_libraries.crt.WinCrt;
import com.duy.pascal.backend.builtin_libraries.graph.GraphLib;
import com.duy.pascal.backend.builtin_libraries.io.InOutListener;
import com.duy.pascal.backend.builtin_libraries.java.data.JavaCollectionsAPI;
import com.duy.pascal.backend.builtin_libraries.math.MathLib;
import com.duy.pascal.backend.linenumber.LineInfo;
import com.duy.pascal.backend.parse_exception.PermissionDeniedException;
Expand Down Expand Up @@ -125,6 +126,7 @@ public class PascalLibraryManager {
MAP_LIBRARIES.put(AndroidMediaPlayerLib.NAME, AndroidMediaPlayerLib.class);
MAP_LIBRARIES.put(HtmlLib.NAME, HtmlLib.class);
MAP_LIBRARIES.put(AndroidLocationLib.NAME, AndroidLocationLib.class);
MAP_LIBRARIES.put(JavaCollectionsAPI.NAME, JavaCollectionsAPI.class);

//socket library
MAP_LIBRARIES.put(SocketIOLib.NAME, SocketIOLib.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
Expand All @@ -49,7 +54,9 @@
* Created by Duy on 17-Jun-17.
*/

public class JavaUtilAPI extends PascalLibraryImpl {
public class JavaCollectionsAPI extends PascalLibraryImpl {
public static final String NAME = "JavaCollections".toLowerCase();

@Override
public void declareConstants(ExpressionContextMixin parentContext) {
super.declareConstants(parentContext);
Expand Down Expand Up @@ -82,10 +89,15 @@ public void declareTypes(ExpressionContextMixin parentContext) {
parentContext.declareTypedef("JDelayQueue", new JavaClassBasedType(DelayQueue.class));
parentContext.declareTypedef("JIdentityHashMap", new JavaClassBasedType(IdentityHashMap.class));
parentContext.declareTypedef("JEnumeration", new JavaClassBasedType(Enumeration.class));
parentContext.declareTypedef("JProperties", new JavaClassBasedType(Properties.class));
parentContext.declareTypedef("JDictionary", new JavaClassBasedType(Dictionary.class));
parentContext.declareTypedef("JSet", new JavaClassBasedType(Set.class));
parentContext.declareTypedef("JIterator", new JavaClassBasedType(Iterator.class));
parentContext.declareTypedef("JEntry", new JavaClassBasedType(Map.Entry.class));
}

@Override
public String getName() {
return null;
return "JavaCollections".toLowerCase();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1344,32 +1344,38 @@ private RuntimeValue getMethodFromJavaClass(ExpressionContext context, RuntimeVa
//access method of java class
if (type.declType instanceof JavaClassBasedType) {
JavaClassBasedType javaType = (JavaClassBasedType) type.declType;
Class<?> storageClass = javaType.getStorageClass();

//get arguments
List<RuntimeValue> argumentsForCall = new ArrayList<>();
if (hasNext()) {
if (peek() instanceof ParenthesizedToken) {
ParenthesizedToken token = (ParenthesizedToken) take();
argumentsForCall = token.getArgumentsForCall(context);
Class<?> clazz = javaType.getStorageClass();
String className = clazz.getSimpleName();
while (true) {

//get arguments
List<RuntimeValue> argumentsForCall = new ArrayList<>();
if (hasNext()) {
if (peek() instanceof ParenthesizedToken) {
ParenthesizedToken token = (ParenthesizedToken) take();
argumentsForCall = token.getArgumentsForCall(context);
}
}
}

//get method, ignore case
Method[] declaredMethods = storageClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.getName().equalsIgnoreCase(methodName)) {
MethodDeclaration methodDeclaration =
new MethodDeclaration(container, declaredMethod, javaType);
FunctionCall functionCall = methodDeclaration.generateCall(getLineNumber(),
argumentsForCall, context);
if (functionCall != null) {
return functionCall;
//get method, ignore case
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.getName().equalsIgnoreCase(methodName)) {
MethodDeclaration methodDeclaration =
new MethodDeclaration(container, declaredMethod, javaType);
FunctionCall functionCall = methodDeclaration.generateCall(getLineNumber(),
argumentsForCall, context);
if (functionCall != null) {
return functionCall;
}
}
}
Class<?>[] interfaces = clazz.getInterfaces();
clazz = clazz.getSuperclass();
if (clazz == null) break;
}
throw new MethodNotFoundException(container.getLineNumber(),
methodName, storageClass.getName());
throw new MethodNotFoundException(container.getLineNumber(), methodName, className);
} else {
throw new NotAStatementException(container);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.duy.pascal.java;/*
* Copyright (c) 2017 Tran Le Duy
*
* Licensed 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.
*/


import com.duy.pascal.interpreter.BaseTestCase;

import java.io.File;

/**
* Created by Duy on 17-Jun-17.
*/

public class JavaCollectionsTest extends BaseTestCase {
@Override
public String getDirTest() {
return "test_libraries" + File.separator + "javacollections";
}


public void testArrayList() {
run("ArrayList.pas");
}

public void testHashMap() {
run("HashMap.pas");
}

public void testHashSet() {
run("HashSet.pas");

}

public void testLinkedHashMap() {
run("LinkedHashMap.pas");

}

public void testLinkedHashSet() {
run("LinkedHashSet.pas");

}

public void testLinkedList() {
run("LinkedList.pas");

}

public void testStack() {
run("Stack.pas");

}

public void testTreeSet() {
run("TreeSet.pas");

}

public void testVector() {
run("Vector.pas");

}
}
5 changes: 5 additions & 0 deletions test_pascal/test_libraries/javacollections/ArrayList.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Initial size of list : 0
Size of list after additions : 7
Contents of list : [C, A2, A, E, B, D, F]
Size of list after deletions : 6
Contents of list : [C, A2, A, E, B, D]
27 changes: 27 additions & 0 deletions test_pascal/test_libraries/javacollections/ArrayList.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
uses JavaCollections;

var
list : JArrayList;
begin
writeln('Initial size of list : ' + list.size());

// add elements to the array list
list.add('C');
list.add('A');
list.add('E');
list.add('B');
list.add('D');
list.add('F');
list.add(1, 'A2');
writeln('Size of list after additions : ' + list.size());

// display the array list
writeln('Contents of list : ' + list);

// Remove elements from the array list
list.remove('F');
list.remove(2);
writeln('Size of list after deletions : ' + list.size());
writeln('Contents of list : ' + list);
end.
{https://www.tutorialspoint.com/java/java_arraylist_class.htm}
40 changes: 40 additions & 0 deletions test_pascal/test_libraries/javacollections/HashMap.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{https://www.tutorialspoint.com/java/java_hashmap_class.htm}
uses JavaCollections;

var
// Create a hash map
map : JHashMap;
entries : JSet;
i : JIterator;
entry : JEntry;
balance : Double;
begin
// Put elements to the map
map.put('Zara', (3434.34));
map.put('Mahnaz', (123.22));
map.put('Ayan', (1378.00));
map.put('Daisy', (99.22));
map.put('Qadir', (-19.08));

// Get a set of the entries
entries := map.entrySet();

// Get an iterator
i := entries.iterator();
writeln(i);

// Display elements
while(i.hasNext()) do
begin
cast(entry, i.next());
write(entry.getKey() + ' : ');
writeln(entry.getValue());
end;

// Deposit 1000 into Zara's account
writeln(map.get('Zara'));

cast(balance, map.get('Zara'));
map.put('Zara', (balance + 1000));
writeln('Zara''s new balance : ' + map.get('Zara'));
end.
1 change: 1 addition & 0 deletions test_pascal/test_libraries/javacollections/HashSet.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[A, B, C, D, E, F]
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
uses JavaCollections;

var
// create a hash set
hs : JHashSet;
Expand Down
Loading

0 comments on commit 3727000

Please sign in to comment.