muScript: support globals
This commit is contained in:
parent
a5fa86a6c7
commit
044f468024
|
@ -2,24 +2,37 @@ package io.gitlab.jfronny.muscript.data;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.ImmCollection;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Scope implements DObject {
|
||||
private final DObject source;
|
||||
private final @Nullable Scope source;
|
||||
private final Map<String, Dynamic<?>> override = new HashMap<>();
|
||||
|
||||
public Scope() {
|
||||
this(DFinal.of(Map.of()));
|
||||
this(null);
|
||||
}
|
||||
|
||||
public Scope(DObject source) {
|
||||
public Scope(@Nullable DObject source) {
|
||||
if (source == null) {
|
||||
this.source = null;
|
||||
} else if (source instanceof Scope src) {
|
||||
this.source = src;
|
||||
} else {
|
||||
this.source = new Scope();
|
||||
source.getValue().forEach(this::set);
|
||||
}
|
||||
}
|
||||
|
||||
public Scope(@Nullable Scope source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Dynamic<?>> getValue() {
|
||||
if (source == null) return ImmCollection.of(override);
|
||||
var map = new HashMap<>(source.getValue());
|
||||
map.putAll(override);
|
||||
return ImmCollection.of(map);
|
||||
|
@ -30,10 +43,25 @@ public class Scope implements DObject {
|
|||
*/
|
||||
@Deprecated(forRemoval = false)
|
||||
public Scope set(String key, Dynamic<?> value) {
|
||||
override.put(key, value);
|
||||
if (key.startsWith("$")) {
|
||||
if (!setGlobal(key, value)) override.put(key, value);
|
||||
} else {
|
||||
override.put(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean setGlobal(String key, Dynamic<?> value) {
|
||||
if (override.containsKey(key)) {
|
||||
override.put(key, value);
|
||||
return true;
|
||||
} else if (source != null) {
|
||||
return source.setGlobal(key, value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Scope set(String key, boolean value) {
|
||||
return set(key, DFinal.of(value));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package io.gitlab.jfronny.muscript.test;
|
||||
|
||||
import io.gitlab.jfronny.muscript.compiler.Parser;
|
||||
import io.gitlab.jfronny.muscript.error.LocationalException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static io.gitlab.jfronny.muscript.test.util.MuTestUtil.makeArgs;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class GlobalTest {
|
||||
@Test
|
||||
void notAll() {
|
||||
assertEquals(12, Parser.parseScript("""
|
||||
v = 12
|
||||
{->v = 5}()
|
||||
v
|
||||
""").run(makeArgs()).asNumber().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void global() {
|
||||
assertEquals(5, Parser.parseScript("""
|
||||
$v = 12
|
||||
{->$v = 5}()
|
||||
$v
|
||||
""").run(makeArgs()).asNumber().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void innermost() {
|
||||
assertThrows(LocationalException.class,
|
||||
() -> Parser.parseScript("""
|
||||
{->$v = 12}()
|
||||
$v
|
||||
""").run(makeArgs()).asNumber().getValue(),
|
||||
"This object doesn't contain '$v'");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue