mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Поддержка инстанцирования java-класса с помощью ключевого слова new
This commit is contained in:
parent
483c7c1242
commit
826891ac52
@ -1,15 +1,14 @@
|
|||||||
package com.annimon.ownlang.lib;
|
package com.annimon.ownlang.lib;
|
||||||
|
|
||||||
import com.annimon.ownlang.exceptions.UnknownFunctionException;
|
|
||||||
import com.annimon.ownlang.parser.ast.ClassDeclarationStatement;
|
import com.annimon.ownlang.parser.ast.ClassDeclarationStatement;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public final class ClassDeclarations {
|
public final class ClassDeclarations {
|
||||||
|
|
||||||
private static final Map<String, ClassDeclarationStatement> declarations;
|
private static final Map<String, ClassDeclarationStatement> declarations;
|
||||||
static {
|
static {
|
||||||
declarations = new HashMap<>();
|
declarations = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassDeclarations() { }
|
private ClassDeclarations() { }
|
||||||
@ -22,12 +21,7 @@ public final class ClassDeclarations {
|
|||||||
return declarations;
|
return declarations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isExists(String key) {
|
|
||||||
return declarations.containsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassDeclarationStatement get(String key) {
|
public static ClassDeclarationStatement get(String key) {
|
||||||
if (!isExists(key)) throw new UnknownFunctionException(key);
|
|
||||||
return declarations.get(key);
|
return declarations.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
src/main/java/com/annimon/ownlang/lib/Instantiable.java
Normal file
9
src/main/java/com/annimon/ownlang/lib/Instantiable.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.annimon.ownlang.lib;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for values that supports creating instances with `new` keyword.
|
||||||
|
*/
|
||||||
|
public interface Instantiable {
|
||||||
|
|
||||||
|
Value newInstance(Value[] args);
|
||||||
|
}
|
@ -103,7 +103,7 @@ public final class java implements Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ClassValue extends MapValue {
|
private static class ClassValue extends MapValue implements Instantiable {
|
||||||
|
|
||||||
public static Value classOrNull(Class<?> clazz) {
|
public static Value classOrNull(Class<?> clazz) {
|
||||||
if (clazz == null) return NULL;
|
if (clazz == null) return NULL;
|
||||||
@ -162,7 +162,8 @@ public final class java implements Module {
|
|||||||
return NumberValue.fromBoolean(clazz.isAssignableFrom( ((ClassValue)args[0]).clazz ));
|
return NumberValue.fromBoolean(clazz.isAssignableFrom( ((ClassValue)args[0]).clazz ));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Value newInstance(Value[] args) {
|
@Override
|
||||||
|
public Value newInstance(Value[] args) {
|
||||||
return findConstructorAndInstantiate(args, clazz.getConstructors());
|
return findConstructorAndInstantiate(args, clazz.getConstructors());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.annimon.ownlang.parser.ast;
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.UnknownClassException;
|
||||||
import com.annimon.ownlang.lib.*;
|
import com.annimon.ownlang.lib.*;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,6 +18,16 @@ public final class ObjectCreationExpression implements Expression {
|
|||||||
@Override
|
@Override
|
||||||
public Value eval() {
|
public Value eval() {
|
||||||
final ClassDeclarationStatement cd = ClassDeclarations.get(className);
|
final ClassDeclarationStatement cd = ClassDeclarations.get(className);
|
||||||
|
if (cd == null) {
|
||||||
|
// Is Instantiable?
|
||||||
|
if (Variables.isExists(className)) {
|
||||||
|
final Value variable = Variables.get(className);
|
||||||
|
if (variable instanceof Instantiable) {
|
||||||
|
return ((Instantiable) variable).newInstance(ctorArgs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new UnknownClassException(className);
|
||||||
|
}
|
||||||
|
|
||||||
// Create an instance and put evaluated fields with method declarations
|
// Create an instance and put evaluated fields with method declarations
|
||||||
final ClassInstanceValue instance = new ClassInstanceValue(className);
|
final ClassInstanceValue instance = new ClassInstanceValue(className);
|
||||||
@ -30,14 +41,17 @@ public final class ObjectCreationExpression implements Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call a constructor
|
// Call a constructor
|
||||||
|
instance.callConstructor(ctorArgs());
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value[] ctorArgs() {
|
||||||
final int argsSize = constructorArguments.size();
|
final int argsSize = constructorArguments.size();
|
||||||
final Value[] ctorArgs = new Value[argsSize];
|
final Value[] ctorArgs = new Value[argsSize];
|
||||||
for (int i = 0; i < argsSize; i++) {
|
for (int i = 0; i < argsSize; i++) {
|
||||||
ctorArgs[i] = constructorArguments.get(i).eval();
|
ctorArgs[i] = constructorArguments.get(i).eval();
|
||||||
}
|
}
|
||||||
instance.callConstructor(ctorArgs);
|
return ctorArgs;
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user