Skip to content

Commit

Permalink
GH-556 Simplify modules and loading services, improve relations betwe…
Browse files Browse the repository at this point in the history
…en signatures and types, refactor type and module parsers
  • Loading branch information
dzikoysk committed Oct 6, 2020
1 parent c5eda0e commit a734f47
Show file tree
Hide file tree
Showing 166 changed files with 1,233 additions and 1,603 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@

import org.panda_lang.language.architecture.module.Module;
import org.panda_lang.language.architecture.statement.Statement;
import org.panda_lang.utilities.commons.function.CompletableOption;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

public abstract class AbstractScript implements Script {

private final String scriptName;
private final List<Statement> statements = new ArrayList<>();
protected Module associatedModule;
private final CompletableOption<Module> associatedModule = new CompletableOption<>();

public AbstractScript(String scriptName) {
this.scriptName = scriptName;
Expand Down Expand Up @@ -54,12 +56,8 @@ public void addStatement(Statement statement) {
this.statements.add(statement);
}

public void setModule(Module module) {
this.associatedModule = module;
}

@Override
public Module getModule() {
public CompletableOption<Module> getModule() {
return associatedModule;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.panda_lang.language.architecture.module.Module;
import org.panda_lang.language.architecture.statement.Statement;
import org.panda_lang.utilities.commons.function.CompletableOption;

import java.util.List;

Expand Down Expand Up @@ -45,7 +46,7 @@ public interface Script {
*
* @return the module
*/
Module getModule();
CompletableOption<Module> getModule();

/**
* Get script name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@

package org.panda_lang.language.architecture.expression;

import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.language.architecture.type.Signature;

public abstract class AbstractDynamicExpression implements DynamicExpression {

private final Type returnType;
private final Signature returnType;

public AbstractDynamicExpression(Type returnType) {
public AbstractDynamicExpression(Signature returnType) {
this.returnType = returnType;
}

@Override
public Type getReturnType() {
public Signature getReturnType() {
return returnType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.panda_lang.language.architecture.expression;

import org.panda_lang.language.architecture.type.Signature;
import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.language.runtime.ProcessStack;

import java.security.InvalidParameterException;
Expand Down Expand Up @@ -66,7 +65,7 @@ public ExpressionValueType getExpressionType() {

@Override
public String toString() {
String s = type.name() + ":" + (returnType != null ? returnType.getType().getSimpleName() : "any");
String s = type.name() + ":" + (returnType != null ? returnType.getType() : "any");
return ExpressionValueType.CONST == type ? s + ":" + value : s;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.language.interpreter.parser.Context;
import org.panda_lang.language.runtime.ProcessStack;
import org.panda_lang.language.architecture.type.TypeComponents;
import org.panda_lang.utilities.commons.ObjectUtils;

public final class ThisExpression implements DynamicExpression {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,101 @@

package org.panda_lang.language.architecture.module;

import org.panda_lang.language.PandaFrameworkException;
import org.panda_lang.language.architecture.type.Reference;
import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.utilities.commons.function.Option;
import org.panda_lang.utilities.commons.function.PandaStream;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Represents references imported in the specific space, e.g. file
*/
public interface Imports extends ModuleResource {
public final class Imports {

private final TypeLoader typeLoader;
private final Map<String, Module> importedModules = new HashMap<>();
private final Map<String, Reference> importedTypes = new HashMap<>();

public Imports(TypeLoader typeLoader) {
this.typeLoader = typeLoader;
}

/**
* Import module using the given name
*
* @param name the name of module
*/
void importModule(String name);

public void importModule(String name) {
typeLoader.forModule(name)
.peek(module -> importedModules.put(name, module))
.orThrow(() -> {
throw new PandaFrameworkException("Module " + name + " does not exist");
});
}

/**
* Import module
*
* @param module the module to import
* // @return if type with the given name is already imported, the method will interrupt importing and return the name of that type
*/
void importModule(Module module);
public void importModule(Module module) {
importedModules.putIfAbsent(module.getName(), module);
}

/**
* Import reference
*
* @param name the name of type to import as (may be different than type name)
* @param type the reference to type
* @param reference the reference to type
* @return if type with the given name is already imported, the method will return false, otherwise true
*/
boolean importType(String name, Type type);
public boolean importType(String name, Reference reference) {
reference.getType().then(typeLoader::load);

if (importedTypes.containsKey(name)) {
return false;
}

importedTypes.put(name, reference);
return true;
}

public Option<Type> forType(String name) {
return Option.of(importedTypes.get(name))
.orElse(() -> forModuleType(name))
.map(Reference::getType)
.map(futureType -> futureType.orThrow(() -> {
throw new PandaFrameworkException("Parse error, cannot get type " + name);
}))
.peek(typeLoader::load);
}

private Option<Reference> forModuleType(String name) {
List<? extends Reference> references = PandaStream.of(importedModules.entrySet())
.mapOpt(entry -> entry.getValue().get(name))
.collect(Collectors.toList());

if (references.size() > 1) {
throw new PandaFrameworkException("Duplicated reference names: " + references);
}

return references.isEmpty() ? Option.none() : Option.of(references.get(0));
}

/**
* Get associated type loader
*
* @return the associated type loader
*/
TypeLoader getTypeLoader();
public TypeLoader getTypeLoader() {
return typeLoader;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import org.jetbrains.annotations.Nullable;
import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.language.interpreter.parser.Components;
import org.panda_lang.language.interpreter.parser.Context;
import org.panda_lang.language.interpreter.token.Snippet;
import org.panda_lang.language.interpreter.token.Snippetable;
Expand All @@ -29,15 +28,15 @@
import java.util.function.Function;
import java.util.function.Supplier;

public final class PandaImportsUtils {
public final class ImportsUtils {

private PandaImportsUtils() { }
private ImportsUtils() { }

public static Type getTypeOrThrow(Context context, Snippetable nameSource, String message, String note) {
public static Type getTypeOrThrow(Context<?> context, Snippetable nameSource, String message, String note) {
String name = nameSource.toSnippet().asSource();

return context.getComponent(Components.IMPORTS)
.forName(name)
return context.getImports()
.forType(name)
.orThrow((Supplier<? extends PandaParserFailure>) () -> {
MessageFormatter formatter = new MessageFormatter();
formatter.register("{name}", name);
Expand All @@ -46,12 +45,12 @@ public static Type getTypeOrThrow(Context context, Snippetable nameSource, Strin
});
}

public static Type getTypeOrThrow(Context context, String className, @Nullable Snippet source) {
return getTypeOrThrow(context, imports -> imports.forName(className), "Unknown type " + className, source);
public static Type getTypeOrThrow(Context<?> context, String className, @Nullable Snippet source) {
return getTypeOrThrow(context, imports -> imports.forType(className), "Unknown type " + className, source);
}

private static Type getTypeOrThrow(Context context, Function<Imports, Option<Type>> mapper, String message, Snippet source) {
return mapper.apply(context.getComponent(Components.IMPORTS)).orThrow(() -> {
private static Type getTypeOrThrow(Context<?> context, Function<Imports, Option<Type>> mapper, String message, Snippet source) {
return mapper.apply(context.getImports()).orThrow(() -> {
throw new PandaParserFailure(context, source, message);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,73 +16,70 @@

package org.panda_lang.language.architecture.module;

import org.panda_lang.language.architecture.type.Type;
import org.panda_lang.language.architecture.type.Reference;
import org.panda_lang.utilities.commons.function.Option;

import java.util.Collection;

/**
* Identifiable container of resources
*/
public interface Module extends Modules, ModuleResource {
public interface Module extends Modules {

/**
* Add reference to type to the module
*
* @param type the reference to add
* @param reference the reference to add
* @return the added reference
*/
Type add(Type type);
Reference add(Reference reference);

/**
* Check if the given module is submodule of the current module
* Get reference if exists
*
* @param module the module to check
* @return true if module is submodule, otherwise false
* @param name the name of reference
* @return the option with reference, otherwise none
*/
boolean isSubmodule(Module module);
Option<? extends Reference> get(String name);

/**
* Check if the module contains type associated with the specified class
* Check if the given module is submodule of the current module
*
* @param clazz the class to check
* @return true if module contains type associated with the provided class
* @param module the module to check
* @return true if module is submodule, otherwise false
*/
default boolean hasType(Class<?> clazz) {
return forClass(clazz).isDefined();
}
boolean hasSubmodule(Module module);

/**
* Check if the module contains a reference to type with the given name
*
* @param name the name to search for
* @return true if module contains such a reference
*/
default boolean hasType(CharSequence name) {
return forName(name).isDefined();
default boolean hasType(String name) {
return get(name).isDefined();
}

/**
* Get all types (also from submodules)
* Iterable is used instead of collection because of the performance reasons.
*
* @return the iterable that contains all types
*/
Collection<Type> getAllTypes();

/**
* Get types that belongs to the module
*
* @return collection of types
*/
Collection<Type> getTypes();
Collection<? extends Reference> getReferences();

/**
* Get parent module
*
* @return the parent module
*/
Option<Module> getParent();
Option<? extends Module> getParent();

/**
* Get non prefixed name of module
*
* @return the simple name of module
*/
String getSimpleName();

/**
* Get name of module
Expand Down

This file was deleted.

Loading

0 comments on commit a734f47

Please sign in to comment.