[muscript] Basic StarScript ingester

This commit is contained in:
Johannes Frohnmeyer 2022-06-04 17:01:23 +02:00
parent fe5138bb2b
commit 16e3a3224d
Signed by: Johannes
GPG Key ID: E76429612C2929F4
2 changed files with 105 additions and 0 deletions

View File

@ -0,0 +1,90 @@
package io.gitlab.jfronny.muscript;
import io.gitlab.jfronny.commons.log.*;
import java.util.*;
import java.util.stream.*;
public class StarScriptIngester {
private static final Logger LOGGER = Logger.forName("MuScript");
/** Naive conversion of starscript syntax to muscript */
public static String starScriptToMu(String source) {
StringBuilder result = new StringBuilder();
StringBuilder currbuf = new StringBuilder();
State state = State.Surrounding;
for (char c : source.toCharArray()) {
switch (state) {
case Surrounding -> {
if (c == '{') {
if (!currbuf.isEmpty()) {
if (!result.isEmpty()) result.append(" || ");
result.append(enquote(currbuf.toString()));
}
currbuf = new StringBuilder();
state = State.UnquotedInner;
} else currbuf.append(c);
}
case UnquotedInner -> {
switch (c) {
case '}' -> {
if (!currbuf.isEmpty()) {
if (!result.isEmpty()) result.append(" || ");
result.append("(").append(currbuf).append(")");
}
currbuf = new StringBuilder();
state = State.Surrounding;
}
case '\'' -> {
currbuf.append(c);
state = State.SingleQuoteInner;
}
case '"' -> {
currbuf.append(c);
state = State.DoubleQuoteInner;
}
default -> currbuf.append(c);
}
}
case SingleQuoteInner -> {
currbuf.append(c);
if (c == '\'') state = State.UnquotedInner;
}
case DoubleQuoteInner -> {
currbuf.append(c);
if (c == '"') state = State.UnquotedInner;
}
}
}
if (!currbuf.isEmpty() && !result.isEmpty()) result.append(" || ");
switch (state) {
case Surrounding -> {
if (!currbuf.isEmpty()) result.append(enquote(currbuf.toString()));
}
case UnquotedInner -> {
LOGGER.warn("Starscript code segment improperly closed, closing automatically");
if (!currbuf.isEmpty()) result.append("(").append(currbuf).append(")");
}
case SingleQuoteInner -> {
LOGGER.warn("Quote in starscript swallows ending, completing with closing quote");
if (!currbuf.isEmpty()) result.append("(").append(currbuf).append("')");
}
case DoubleQuoteInner -> {
LOGGER.warn("Quote in starscript swallows ending, completing with closing quote");
if (!currbuf.isEmpty()) result.append("(").append(currbuf).append("\")");
}
}
return result.toString();
}
/** Creates quotes around a string, supports strings containing quotes */
private static String enquote(String literalText) {
if (!literalText.contains("'")) return "'" + literalText + "'";
if (!literalText.contains("\"")) return "\"" + literalText + "\"";
return Arrays.stream(literalText.split("'")).map(s -> "'" + s + "'")
.collect(Collectors.joining(" || \"'\" || "));
}
enum State {
Surrounding, UnquotedInner, SingleQuoteInner, DoubleQuoteInner
}
}

View File

@ -0,0 +1,15 @@
package io.gitlab.jfronny.muscript.test;
import io.gitlab.jfronny.muscript.*;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StarScriptIngesterTest {
@Test
void ingestionTest() {
assertEquals("'Hello ' || (name) || '!'", StarScriptIngester.starScriptToMu("Hello {name}!"));
assertEquals("('Only \"Content')", StarScriptIngester.starScriptToMu("{'Only \"Content'}"));
assertEquals("(a + c / 75) || ' equals ' || (b)", StarScriptIngester.starScriptToMu("{a + c / 75} equals {b}"));
}
}