From ce423971e6ea3b4126806eea4b6874daee9f07b2 Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Mon, 19 Aug 2024 01:15:51 +0800 Subject: Added a checker module. NOTE: I think I should look at guava or commons for some sort of sealable Map instead of the current Scope :D --- .../java/lv/enes/orang/core/ImmutableScope.java | 47 ++++++++++++++++++++++ .../main/java/lv/enes/orang/core/MutableScope.java | 26 ++++++++++++ .../lv/enes/orang/core/OrangRuntimeException.java | 11 +++++ core/src/main/java/lv/enes/orang/core/Scope.java | 31 ++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 core/src/main/java/lv/enes/orang/core/ImmutableScope.java create mode 100644 core/src/main/java/lv/enes/orang/core/MutableScope.java create mode 100644 core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java create mode 100644 core/src/main/java/lv/enes/orang/core/Scope.java (limited to 'core/src') diff --git a/core/src/main/java/lv/enes/orang/core/ImmutableScope.java b/core/src/main/java/lv/enes/orang/core/ImmutableScope.java new file mode 100644 index 0000000..5120b08 --- /dev/null +++ b/core/src/main/java/lv/enes/orang/core/ImmutableScope.java @@ -0,0 +1,47 @@ +package lv.enes.orang.core; + +import java.util.HashMap; +import java.util.Map; + +public class ImmutableScope extends Scope { + public static ImmutableScope of(Map builtins) { + return new ImmutableScope<>(null, new HashMap<>(builtins)); + } + + public static ImmutableScope of(Scope parent) { + if (parent instanceof ImmutableScope imm) { + return imm; + } + return ImmutableScope.of(parent, Map.of()); + } + + public static ImmutableScope of(Scope parent, String key, E value) { + return ImmutableScope.of(parent, Map.of(key, value)); + } + + public static ImmutableScope of(Scope parent, Map definitions) { + return new ImmutableScope<>(parent, definitions).maybeFlattened(); + } + + protected ImmutableScope(Scope parent, Map definitions) { + super(parent, Map.copyOf(definitions)); + } + + public ImmutableScope maybeFlattened() { + if (depth > MAX_DEPTH) { + return flattened(); + } + return this; + } + + private ImmutableScope flattened() { + if (parent instanceof ImmutableScope immParent) { + var flatParent = immParent.flattened(); + var newDefs = new HashMap<>(flatParent.definitions); + newDefs.putAll(definitions); + return new ImmutableScope<>(flatParent.parent, newDefs); + } + + return this; + } +} diff --git a/core/src/main/java/lv/enes/orang/core/MutableScope.java b/core/src/main/java/lv/enes/orang/core/MutableScope.java new file mode 100644 index 0000000..8d8b455 --- /dev/null +++ b/core/src/main/java/lv/enes/orang/core/MutableScope.java @@ -0,0 +1,26 @@ +package lv.enes.orang.core; + +import java.util.HashMap; +import java.util.Map; + +public class MutableScope extends Scope { + public static MutableScope of(Map builtins) { + return new MutableScope<>(null, new HashMap<>(builtins)); + } + + public static MutableScope of(Scope parent) { + return new MutableScope<>(parent, Map.of()); + } + + public static MutableScope of(Scope parent, String name, E value) { + return new MutableScope<>(parent, Map.of(name, value)); + } + + protected MutableScope(Scope parent, Map definitions) { + super(parent, new HashMap<>(definitions)); + } + + public void setDefinition(String key, E value) { + definitions.put(key, value); + } +} diff --git a/core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java b/core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java new file mode 100644 index 0000000..6ce5f70 --- /dev/null +++ b/core/src/main/java/lv/enes/orang/core/OrangRuntimeException.java @@ -0,0 +1,11 @@ +package lv.enes.orang.core; + +public class OrangRuntimeException extends OrangException { + public OrangRuntimeException(String message) { + super(message); + } + + public OrangRuntimeException(Throwable cause) { + super(cause); + } +} diff --git a/core/src/main/java/lv/enes/orang/core/Scope.java b/core/src/main/java/lv/enes/orang/core/Scope.java new file mode 100644 index 0000000..0f4d23a --- /dev/null +++ b/core/src/main/java/lv/enes/orang/core/Scope.java @@ -0,0 +1,31 @@ +package lv.enes.orang.core; + +import java.util.Map; + +public abstract class Scope { + public static final int MAX_DEPTH = 4; + + protected final Scope parent; + protected final Map definitions; + protected final int depth; + + protected Scope(Scope parent, Map definitions) { + this.parent = parent; + this.definitions = definitions; + this.depth = parent == null ? 0 : parent.depth + 1; + } + + public E getDefinition(String name) throws OrangRuntimeException { + if (definitions.containsKey(name)) { + return definitions.get(name); + } else if (parent != null) { + return parent.getDefinition(name); + } else { + throw new OrangRuntimeException(STR."Value named \{name} is not defined!"); + } + } + + public boolean hasDefinition(String name) { + return definitions.containsKey(name) || parent != null && parent.hasDefinition(name); + } +} -- cgit v1.2.3