feat(muscript): Language versions

This commit is contained in:
Johannes Frohnmeyer 2023-09-15 19:21:14 +02:00
parent e84f8adc88
commit 6ffd67f23f
Signed by: Johannes
GPG Key ID: E76429612C2929F4
5 changed files with 139 additions and 64 deletions

View File

@ -4,6 +4,7 @@ import io.gitlab.jfronny.muscript.ast.Expr;
import io.gitlab.jfronny.muscript.ast.dynamic.Call;
import io.gitlab.jfronny.muscript.ast.dynamic.Variable;
import io.gitlab.jfronny.muscript.compiler.CodeLocation;
import io.gitlab.jfronny.muscript.compiler.MuScriptVersion;
import io.gitlab.jfronny.muscript.data.Scope;
import io.gitlab.jfronny.muscript.data.dynamic.*;
import io.gitlab.jfronny.muscript.data.dynamic.additional.*;
@ -21,12 +22,23 @@ import static io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal.of;
public class StandardLib {
private static final Random rnd = new Random();
@Deprecated
public static Scope createScope() {
return addTo(new Scope());
return createScope(MuScriptVersion.DEFAULT);
}
public static Scope createScope(MuScriptVersion version) {
return addTo(version, new Scope());
}
@Deprecated
public static Scope addTo(Scope scope) {
return scope
return addTo(MuScriptVersion.DEFAULT, scope);
}
public static Scope addTo(MuScriptVersion version, Scope scope) {
if (version.contains(MuScriptVersion.V1)) {
scope
.set("PI", Math.PI)
.set("E", Math.E)
.set("date", new DCallableObject(Map.of(
@ -61,8 +73,10 @@ public class StandardLib {
.set("toUpper", StandardLib::toUpper)
.set("toLower", StandardLib::toLower)
.set("contains", StandardLib::contains)
.set("replace", StandardLib::replace)
.set("replace", StandardLib::replace);
}
if (version.contains(MuScriptVersion.V2)) {
scope
.set("listOf", StandardLib::listOf)
.set("len", StandardLib::len)
.set("isEmpty", StandardLib::isEmpty)
@ -84,6 +98,8 @@ public class StandardLib {
.set("fail", StandardLib::fail)
.set("try", StandardLib::try_);
}
return scope;
}
// Numbers
public static DNumber round(DList args) {

View File

@ -5,7 +5,7 @@ import java.util.Set;
import java.util.regex.Pattern;
// Heavily inspired by starscript
public class Lexer {
public class Lexer extends VersionedComponent {
public final String file;
/**
@ -22,11 +22,22 @@ public class Lexer {
public final String source;
public int start, current;
@Deprecated
public Lexer(String source) {
this(source, null);
this(MuScriptVersion.DEFAULT, source);
}
@Deprecated
public Lexer(String source, String file) {
this(MuScriptVersion.DEFAULT, source, file);
}
public Lexer(MuScriptVersion version, String source) {
this(version, source, null);
}
public Lexer(MuScriptVersion version, String source, String file) {
super(version);
this.source = Objects.requireNonNull(source);
this.file = file;
}

View File

@ -0,0 +1,11 @@
package io.gitlab.jfronny.muscript.compiler;
public enum MuScriptVersion {
V1, V2;
public static final MuScriptVersion DEFAULT = V2;
public boolean contains(MuScriptVersion version) {
return compareTo(version) >= 0;
}
}

View File

@ -17,33 +17,58 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class Parser {
public class Parser extends VersionedComponent {
private final Lexer lexer;
private final TokenData previous = new TokenData();
private final TokenData current = new TokenData();
@Deprecated
public static Expr<?> parse(String source) {
return parse(source, null);
return parse(MuScriptVersion.DEFAULT, source);
}
@Deprecated
public static Expr<?> parse(String source, String file) {
return new Parser(new Lexer(source, file)).parse().optimize();
return parse(MuScriptVersion.DEFAULT, source, file);
}
@Deprecated
public static Script parseScript(String source) {
return parseScript(source, null);
return parseScript(MuScriptVersion.DEFAULT, source);
}
@Deprecated
public static Script parseScript(String source, String file) {
return new Parser(new Lexer(source, file)).parseScript().optimize();
return parseScript(MuScriptVersion.DEFAULT, source, file);
}
@Deprecated
public static Script parseMultiScript(String startFile, SourceFS filesystem) {
return new Script(parseMultiScript(startFile, filesystem, new HashSet<>()).stream().flatMap(Script::stream).toList());
return parseMultiScript(MuScriptVersion.DEFAULT, startFile, filesystem);
}
private static List<Script> parseMultiScript(String startFile, SourceFS filesystem, Set<String> alreadyIncluded) {
public static Expr<?> parse(MuScriptVersion version, String source) {
return parse(version, source, null);
}
public static Expr<?> parse(MuScriptVersion version, String source, String file) {
return new Parser(new Lexer(version, source, file)).parse().optimize();
}
public static Script parseScript(MuScriptVersion version, String source) {
return parseScript(version, source, null);
}
public static Script parseScript(MuScriptVersion version, String source, String file) {
return new Parser(new Lexer(version, source, file)).parseScript().optimize();
}
public static Script parseMultiScript(MuScriptVersion version, String startFile, SourceFS filesystem) {
return new Script(parseMultiScript(version, startFile, filesystem, new HashSet<>()).stream().flatMap(Script::stream).toList());
}
private static List<Script> parseMultiScript(MuScriptVersion version, String startFile, SourceFS filesystem, Set<String> alreadyIncluded) {
alreadyIncluded.add(startFile);
boolean isIncludes = true;
StringBuilder src = new StringBuilder();
@ -59,7 +84,7 @@ public class Parser {
String file = s.substring(includePrefix.length());
src.append("// include ").append(file).append("\n");
if (!alreadyIncluded.contains(file)) {
includes.addAll(parseMultiScript(file, filesystem, alreadyIncluded));
includes.addAll(parseMultiScript(version, file, filesystem, alreadyIncluded));
}
} else {
throw new ParseException(PrettyPrintError.builder()
@ -77,6 +102,7 @@ public class Parser {
}
public Parser(Lexer lexer) {
super(lexer.version);
this.lexer = lexer;
}
@ -89,7 +115,7 @@ public class Parser {
public Expr<?> parse() {
advance();
Expr<?> expr = expression();
if (!isAtEnd())
if (!isAtEnd() && version.contains(MuScriptVersion.V2))
throw new ParseException(PrettyPrintError.builder(lexer.location()).setMessage("Unexpected element after end of expression").build());
return expr;
}

View File

@ -0,0 +1,11 @@
package io.gitlab.jfronny.muscript.compiler;
import java.util.Objects;
public abstract class VersionedComponent {
protected final MuScriptVersion version;
public VersionedComponent(MuScriptVersion version) {
this.version = Objects.requireNonNull(version);
}
}