mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 10:59:01 +00:00
version 1.2020.2
This commit is contained in:
parent
3a156f1ff4
commit
7a5b515bf6
2
pom.xml
2
pom.xml
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<groupId>net.sourceforge.plantuml</groupId>
|
<groupId>net.sourceforge.plantuml</groupId>
|
||||||
<artifactId>plantuml</artifactId>
|
<artifactId>plantuml</artifactId>
|
||||||
<version>1.2020.2-SNAPSHOT</version>
|
<version>1.2020.3-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>PlantUML</name>
|
<name>PlantUML</name>
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
package net.sourceforge.plantuml;
|
package net.sourceforge.plantuml;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.command.regex.FoxSignature;
|
import net.sourceforge.plantuml.command.regex.FoxSignature;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
|
||||||
final public class StringLocated {
|
final public class StringLocated {
|
||||||
|
|
||||||
@ -43,6 +44,10 @@ final public class StringLocated {
|
|||||||
private final LineLocation location;
|
private final LineLocation location;
|
||||||
private final String preprocessorError;
|
private final String preprocessorError;
|
||||||
|
|
||||||
|
private StringLocated trimmed;
|
||||||
|
private long fox = -1;
|
||||||
|
private TLineType type;
|
||||||
|
|
||||||
public StringLocated(String s, LineLocation location) {
|
public StringLocated(String s, LineLocation location) {
|
||||||
this(s, location, null);
|
this(s, location, null);
|
||||||
}
|
}
|
||||||
@ -76,12 +81,14 @@ final public class StringLocated {
|
|||||||
return new StringLocated(s, location, preprocessorError);
|
return new StringLocated(s, location, preprocessorError);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringLocated sub(int start, int end) {
|
public StringLocated substring(int start, int end) {
|
||||||
return new StringLocated(this.getString().substring(start, end), this.getLocation(),
|
return new StringLocated(this.getString().substring(start, end), this.getLocation(),
|
||||||
this.getPreprocessorError());
|
this.getPreprocessorError());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringLocated trimmed;
|
public StringLocated substring(int start) {
|
||||||
|
return new StringLocated(this.getString().substring(start), this.getLocation(), this.getPreprocessorError());
|
||||||
|
}
|
||||||
|
|
||||||
public StringLocated getTrimmed() {
|
public StringLocated getTrimmed() {
|
||||||
if (trimmed == null) {
|
if (trimmed == null) {
|
||||||
@ -134,8 +141,6 @@ final public class StringLocated {
|
|||||||
return preprocessorError;
|
return preprocessorError;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long fox = -1;
|
|
||||||
|
|
||||||
public long getFoxSignature() {
|
public long getFoxSignature() {
|
||||||
if (fox == -1) {
|
if (fox == -1) {
|
||||||
fox = FoxSignature.getFoxSignature(getString());
|
fox = FoxSignature.getFoxSignature(getString());
|
||||||
@ -143,4 +148,11 @@ final public class StringLocated {
|
|||||||
return fox;
|
return fox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TLineType getType() {
|
||||||
|
if (type == null) {
|
||||||
|
type = TLineType.getFromLineInternal(s);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -334,6 +334,9 @@ public class StringUtils {
|
|||||||
if (uml.startsWith("@startuml\nauthor\n")) {
|
if (uml.startsWith("@startuml\nauthor\n")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (uml.startsWith("@startuml\ndonors\n")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (uml.startsWith("@startuml\ncheckversion")) {
|
if (uml.startsWith("@startuml\ncheckversion")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -343,6 +346,9 @@ public class StringUtils {
|
|||||||
if (uml.startsWith("@startuml\nsudoku\n")) {
|
if (uml.startsWith("@startuml\nsudoku\n")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (uml.startsWith("@startuml\nstdlib\n")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,9 @@ package net.sourceforge.plantuml;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.cucadiagram.dot.DotMaker2;
|
import net.sourceforge.plantuml.cucadiagram.dot.DotMaker2;
|
||||||
|
import net.sourceforge.plantuml.project.lang.Complement;
|
||||||
|
|
||||||
public class Url implements EnsureVisible {
|
public class Url implements EnsureVisible, Complement {
|
||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
private final String tooltip;
|
private final String tooltip;
|
||||||
|
@ -194,7 +194,7 @@ public class BlocLines implements Iterable<StringLocated> {
|
|||||||
for (int i = 0; i < copy.size(); i++) {
|
for (int i = 0; i < copy.size(); i++) {
|
||||||
final StringLocated s = copy.get(i);
|
final StringLocated s = copy.get(i);
|
||||||
if (s.getString().length() > 0) {
|
if (s.getString().length() > 0) {
|
||||||
copy.set(i, s.sub(1, s.getString().length()));
|
copy.set(i, s.substring(1, s.getString().length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (firstColumnRemovable(copy));
|
} while (firstColumnRemovable(copy));
|
||||||
@ -229,7 +229,7 @@ public class BlocLines implements Iterable<StringLocated> {
|
|||||||
copy.set(0, new StringLocated(data, null));
|
copy.set(0, new StringLocated(data, null));
|
||||||
final int n = copy.size() - 1;
|
final int n = copy.size() - 1;
|
||||||
final StringLocated s = copy.get(n);
|
final StringLocated s = copy.get(n);
|
||||||
copy.set(n, s.sub(0, s.getString().length() - 1));
|
copy.set(n, s.substring(0, s.getString().length() - 1));
|
||||||
return new BlocLines(copy);
|
return new BlocLines(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ public class BlocLines implements Iterable<StringLocated> {
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
return arg.sub(i, arg.getString().length());
|
return arg.substring(i, arg.getString().length());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlocLines subExtract(int margeStart, int margeEnd) {
|
public BlocLines subExtract(int margeStart, int margeEnd) {
|
||||||
|
@ -71,6 +71,7 @@ import net.sourceforge.plantuml.graphic.TextBlockUtils;
|
|||||||
import net.sourceforge.plantuml.graphic.VerticalAlignment;
|
import net.sourceforge.plantuml.graphic.VerticalAlignment;
|
||||||
import net.sourceforge.plantuml.sequencediagram.MessageNumber;
|
import net.sourceforge.plantuml.sequencediagram.MessageNumber;
|
||||||
import net.sourceforge.plantuml.skin.VisibilityModifier;
|
import net.sourceforge.plantuml.skin.VisibilityModifier;
|
||||||
|
import net.sourceforge.plantuml.style.PName;
|
||||||
import net.sourceforge.plantuml.style.Style;
|
import net.sourceforge.plantuml.style.Style;
|
||||||
import net.sourceforge.plantuml.ugraphic.UFont;
|
import net.sourceforge.plantuml.ugraphic.UFont;
|
||||||
import net.sourceforge.plantuml.ugraphic.UStroke;
|
import net.sourceforge.plantuml.ugraphic.UStroke;
|
||||||
@ -84,7 +85,11 @@ public class Display implements Iterable<CharSequence> {
|
|||||||
|
|
||||||
public final static Display NULL = new Display(null, null, true, CreoleMode.FULL);
|
public final static Display NULL = new Display(null, null, true, CreoleMode.FULL);
|
||||||
|
|
||||||
public Display withoutStereotype(Style usedStyle) {
|
public Display withoutStereotypeIfNeeded(Style usedStyle) {
|
||||||
|
final boolean showStereotype = usedStyle.value(PName.ShowStereotype).asBoolean();
|
||||||
|
if (showStereotype) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
final List<CharSequence> copy = new ArrayList<CharSequence>(displayData);
|
final List<CharSequence> copy = new ArrayList<CharSequence>(displayData);
|
||||||
final Display result = new Display(naturalHorizontalAlignment, isNull, defaultCreoleMode);
|
final Display result = new Display(naturalHorizontalAlignment, isNull, defaultCreoleMode);
|
||||||
for (Iterator<CharSequence> it = copy.iterator(); it.hasNext();) {
|
for (Iterator<CharSequence> it = copy.iterator(); it.hasNext();) {
|
||||||
@ -441,8 +446,8 @@ public class Display implements Iterable<CharSequence> {
|
|||||||
|
|
||||||
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
||||||
ISkinSimple spriteContainer, CreoleMode creoleMode) {
|
ISkinSimple spriteContainer, CreoleMode creoleMode) {
|
||||||
return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode,
|
return create(fontConfiguration, horizontalAlignment, spriteContainer, LineBreakStrategy.NONE, creoleMode, null,
|
||||||
null, null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
||||||
@ -513,15 +518,15 @@ public class Display implements Iterable<CharSequence> {
|
|||||||
FontConfiguration stereotypeConfiguration) {
|
FontConfiguration stereotypeConfiguration) {
|
||||||
final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode,
|
final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode,
|
||||||
stereotypeConfiguration).createSheet(this);
|
stereotypeConfiguration).createSheet(this);
|
||||||
final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, spriteContainer == null ? 0
|
final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize,
|
||||||
: spriteContainer.getPadding());
|
spriteContainer == null ? 0 : spriteContainer.getPadding());
|
||||||
return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5));
|
return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextBlock createMessageNumber(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
private TextBlock createMessageNumber(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
|
||||||
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, FontConfiguration stereotypeConfiguration) {
|
ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, FontConfiguration stereotypeConfiguration) {
|
||||||
TextBlock tb1 = subList(0, 1).getCreole(fontConfiguration, horizontalAlignment, spriteContainer,
|
TextBlock tb1 = subList(0, 1).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize,
|
||||||
maxMessageSize, CreoleMode.FULL, stereotypeConfiguration);
|
CreoleMode.FULL, stereotypeConfiguration);
|
||||||
tb1 = TextBlockUtils.withMargin(tb1, 0, 4, 0, 0);
|
tb1 = TextBlockUtils.withMargin(tb1, 0, 4, 0, 0);
|
||||||
final TextBlock tb2 = subList(1, size()).getCreole(fontConfiguration, horizontalAlignment, spriteContainer,
|
final TextBlock tb2 = subList(1, size()).getCreole(fontConfiguration, horizontalAlignment, spriteContainer,
|
||||||
maxMessageSize, CreoleMode.FULL, stereotypeConfiguration);
|
maxMessageSize, CreoleMode.FULL, stereotypeConfiguration);
|
||||||
|
@ -71,24 +71,24 @@ public class PSystemDonors extends AbstractPSystem {
|
|||||||
private static final int COLS = 6;
|
private static final int COLS = 6;
|
||||||
private static final int FREE_LINES = 6;
|
private static final int FREE_LINES = 6;
|
||||||
|
|
||||||
public static final String DONORS = "6qOA02mFU3XMJbc44wzsfuUeUc2VR6qyRpkVqESmi8ZJNK3y1jWxFUutqbz4LxhtJJEYBLjJd6SKnOAW"
|
public static final String DONORS = "6taA0AmEU9ELAujmujswMQFg3ojH8OBbUK9n65Z4qzs0-0FSEptkDz9VH5UwzqqpeYr_pV7pZA4O27ey"
|
||||||
+ "nzlacc6RUtiWLXFpLN9dtkWNveKX2Mr8WEjmHyIdof0IVEycQbqbNzfRkOJbCk0By7OGIqNtNoPkJxUE"
|
+ "VrqDs_nl3nxxgV8W-Ev2KDA92uXiAx7-a7f_TK3C5DrlcT3URXqNwk24ckSZ-BYouVtDS9vl6X-zz0nO"
|
||||||
+ "2t6mGuLG3YdksVytfxRkNbM58LrMhTFH5Ih0gi0ZOdS_QdDfrCPtKvlUX09qAd45DrMLy7hZfYBDuAxZ"
|
+ "GjLFqNtj_qrTPLrULOLPkblL-UWAbR5LkrbpkljHu8ues7Seq23Kc4vTN8T3LOUvTgAlJemGOEAT4tpR"
|
||||||
+ "N3gqw1GZpI8bNZUE43SwC_JKfF1ByaH6vZ_g1RJfNAufaJEXF4Q9HDTjVqVs7PG_BNb1H48ks2ImW4gE"
|
+ "jPWLenuY9LKtjY0b1YDqjqdhb-GN6RN_g1VGfhrSKo9dGddC4ecksqg7znrqFolvvOW7Nx19O06L7E4J"
|
||||||
+ "m0cANXinFY8oQEZgIMDihcRC4oyCAUZ4lloZKTIufsHw6bfyH5s1ahYlSG3Iatgqu6nXDA2i9rkCQ9Ag"
|
+ "5Brjn934UT3GEPlHsCAHBKy2C6IWZNtuHr4SAPwIcMreaIIaG4dAjt40CYfrQn6pvSs0yfxHObYJXCxt"
|
||||||
+ "C_CbtByEorDwpJJS3nPHbhG9hYd8cz0JFk6hBfcSuwMeuIy_JVB8rmGQBbi6t9iEVOjhaqIvdMsQkVDf"
|
+ "Xt3VE4och3feU0Wi4Yof3Qefo9lG4pxLLrqoEET3KSLVVflairaCD2XR0kJDZBw5HvD4-Py-aFdyRbBR"
|
||||||
+ "KssUqjdgQkD_DeVSDMNLyfjHH2D7SEzl2obON5e0FmAzD2SgoPzb7rd8Xd1jfHVITQvUkHeHBjcGgM9T"
|
+ "FAMnrNNC_puSYg8fiuRVz3PgEO9xVrb8mU920SeHwAK-KKb-Vyg-iH23S6sb5z8njrr9emYNR4YhM9UV"
|
||||||
+ "_eWjh-d_wE9ocn7Bus2HpvwlCqt9G4jTYLo6lj3AvhRE5qfAK-FpoAEbupFXcgpPlUFqFihcDF-_RYip"
|
+ "Oearwz-wnCQcnRBSMBIF_nTyKpBG4YkHPEXjMlbaxNoXf6bglB_arT3vRc9Dtapl6Ar7wPpc_tV3Iise"
|
||||||
+ "un80dPbY5dJze1YifjNmP0CHc1QwFUGcG5v0TPZSoiFg4R_E1mHlAYCHXGrAB-Hzi-MGYnGciBmxIdG0"
|
+ "X85ETp7AT4EWs8o6QgXPc0XC2zqS2XCW3w3sDBdbJwilyMkV8FEc4ed8RRZqWB_-JAvouS9KhEds9cO0"
|
||||||
+ "9ayfxU4Zve48HUs2daQLUgGiGh_TfATjsPYuJ_fWVzPW3FAOpjOu2Nyi18umpAf5ixvR-m8z1LUvNEPL"
|
+ "auUKUf8aBOXGrY7eIQ1K8sKH-XacBTEMZedxf0qUfysCWH_LCSL9-6aXS7N3l9etMxkspp5RS8FlPJvr"
|
||||||
+ "Ty_Fgm3M5juBBbBz90DwfGKZ8hL6DFQzx99mQA0mYxFahI6-PrXZvQ7x1vpMeatCQ3CVCWsI6ybgfRSO"
|
+ "7zAuYkTqS-zv5wdv6mpeBIte4QanejZtial2LGCbihXB7XhYkuSTN3nqtu8pMRI16MsEGsP2vLeoQkaj"
|
||||||
+ "tZKP_kOXgzcnMkGvi4V4PaWpenMyFveyKejBV4Hqi9mWMm0Ivk8LU_72dIjLkPoSRAvJcEgnMWiLyhla"
|
+ "HXcQTBubapNjrLPK6X1U7EFWZenEy7WZUQGMbqZYPZ2325i0qlhY4xiauSw4gbjkTZRN5gODNxq8BS7l"
|
||||||
+ "4rYgmCBJWxNo7i0piaUnSpZlbJKVZTUGuda1bNAOe2wTA7Ea56NQMY33rghrRBGEjf_gM31lurivAmw5"
|
+ "Kfd0KeKNdYxiwEv-SKPZ5DadvhqoUsayfXGV2wYIKmLLQQFqcLBaQMiP6JBMe6Uz3R3BgMuB-3O_rR1E"
|
||||||
+ "jqrqrhX1mHGsdHAuqOYHA2SQ5NhPay80V_twbNfoKmSPl_QooJYriY6MGgMSByiNfw3nTWoj-rlqVzks"
|
+ "ABojejCM6tIRGeQhX6yqYYTg5UqQkDYaC82lUNaAdZRMGSPtUbb7722RIq885Lfp-0UdfR7w22rblKN_"
|
||||||
+ "lQsSF_zUDvkSUkFjAmNGSv0S_nxAhAEBajNzDFWRR9WCSC1AAjeuuSf3Isy5aXRinpk3gFFjZEQTd2ot"
|
+ "jstRoyhvy-zrP0MdddZcLGNG8qZpVpzble15h-jx6_fMvLCUs06pnP0UR2rM7b1w9v3KO1-biugwDCs8"
|
||||||
+ "f1QzSlvGsT_zoIm7LtF3YejwYdBu4gTiUsi45M_x_ZS6MpaC_4LKcPFXwgzUBICAnFOsuZoDVOzIt5cL"
|
+ "htX7kKLjqSgF3vN_wNIFM4m7tx3yefeYdxx4QRQzD9nAqdtV5ukJ73R-AQhCokIgrAg94Tt4Te_YF8sT"
|
||||||
+ "11BCZii4pdxrqscQXupPHoYp7Yu2-Vc8T3c4XnRKqhGuJWHMnHdUUwTroOJ_9JU9kEgdh2tLGq_ZL6vg"
|
+ "Podkkde54lIEImNkdhhUJjDyIf_p1QM7uOeXFn-H8PlghWMra9RZjC0sSTRtPhOXcUf_IGy-2RLrdDN3"
|
||||||
+ "5sZuTYMA6qQ1uI9cny3uTfEJ5RZvfeTwgBOVwVGN4oSkAeRTtdDs0W00";
|
+ "qC7sRt8NQFRjJMxS40K6HVo1WNtsc9CJ5CSR0kt6r1rfkPYoSz4ztIuMhB7Vz8_8ieG_B6kLYJ3NowrO" + "B0lnh6sq0m00";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special thanks to our sponsors and donors:
|
* Special thanks to our sponsors and donors:
|
||||||
|
@ -221,11 +221,11 @@ public abstract class PSystemError extends AbstractPSystem {
|
|||||||
}
|
}
|
||||||
final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
|
final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
|
||||||
// udrawable = addMessageAdopt(udrawable);
|
// udrawable = addMessageAdopt(udrawable);
|
||||||
if (min == 1 || min == 8) {
|
if (min == 1 || min == 8 || min == 13 || min == 55) {
|
||||||
udrawable = addMessagePatreon(udrawable);
|
udrawable = addMessagePatreon(udrawable);
|
||||||
} else if (min == 15) {
|
} else if (min == 15) {
|
||||||
udrawable = addMessageLiberapay(udrawable);
|
udrawable = addMessageLiberapay(udrawable);
|
||||||
} else if (min == 30) {
|
} else if (min == 30 || min == 39 || min == 48) {
|
||||||
udrawable = addMessageDedication(udrawable);
|
udrawable = addMessageDedication(udrawable);
|
||||||
} else if (getSource().containsIgnoreCase("arecibo")) {
|
} else if (getSource().containsIgnoreCase("arecibo")) {
|
||||||
udrawable = addMessageArecibo(udrawable);
|
udrawable = addMessageArecibo(udrawable);
|
||||||
|
@ -244,7 +244,10 @@ public class QuoteUtils {
|
|||||||
"Obhagl Uhagvat vf n pbzcyvpngrq cebsrffvba.",
|
"Obhagl Uhagvat vf n pbzcyvpngrq cebsrffvba.",
|
||||||
"Znahsnpghere'f cebgbpby qvpgngrf V pna abg or pncgherq. V zhfg frys-qrfgehpg.", "Snvyher vf abg na bcgvba",
|
"Znahsnpghere'f cebgbpby qvpgngrf V pna abg or pncgherq. V zhfg frys-qrfgehpg.", "Snvyher vf abg na bcgvba",
|
||||||
"Rirelguvat snvyf nyy gur gvzr", "Gur orfg jnl gb nibvq snvyher vf gb snvy pbafgnagyl",
|
"Rirelguvat snvyf nyy gur gvzr", "Gur orfg jnl gb nibvq snvyher vf gb snvy pbafgnagyl",
|
||||||
"Cerzngher bcgvzvmngvba vf gur ebbg bs nyy rivy", "Chgnva, w'ra nv zneer q'nibve gbhwbhef envfba");
|
"Cerzngher bcgvzvmngvba vf gur ebbg bs nyy rivy", "Chgnva, w'ra nv zneer q'nibve gbhwbhef envfba",
|
||||||
|
"Guvf vf gur jnl", "Cngvrapr lbh zhfg unir zl lbhat cnqnjna", "V gubhtug lbh jrer ba zl fvqr",
|
||||||
|
"Qba'g cnavp. Abar bs lbh cnavp. Nofbyhgryl ab ernfba gb cnavp.",
|
||||||
|
"Gung jnf hacyrnfnag. V'z fbeel lbh unq gb frr gung.", "Gur neg bs fvzcyvpvgl vf n chmmyr bs pbzcyrkvgl.");
|
||||||
|
|
||||||
private QuoteUtils() {
|
private QuoteUtils() {
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
import net.sourceforge.plantuml.AParentFolder;
|
import net.sourceforge.plantuml.AParentFolder;
|
||||||
import net.sourceforge.plantuml.BackSlash;
|
import net.sourceforge.plantuml.BackSlash;
|
||||||
import net.sourceforge.plantuml.tim.TVariable;
|
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class Define {
|
public class Define {
|
||||||
@ -124,7 +123,7 @@ public class Define {
|
|||||||
return signature.getFonctionName();
|
return signature.getFonctionName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TVariable asTVariable() {
|
public TValue asTVariable() {
|
||||||
return new TVariable(TValue.fromString(definition));
|
return TValue.fromString(definition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,13 @@ import net.sourceforge.plantuml.tim.EaterStartsub;
|
|||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TLineType;
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
import net.sourceforge.plantuml.tim.TMemory;
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorImpl;
|
||||||
|
|
||||||
public class Sub {
|
public class Sub {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final List<StringLocated> lines = new ArrayList<StringLocated>();
|
private final List<StringLocated> lines = new ArrayList<StringLocated>();
|
||||||
|
// private boolean indentationDone = false;
|
||||||
|
|
||||||
public Sub(String name) {
|
public Sub(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -62,37 +64,47 @@ public class Sub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void add(StringLocated s) {
|
public void add(StringLocated s) {
|
||||||
|
// if (indentationDone) {
|
||||||
|
// throw new IllegalStateException();
|
||||||
|
// }
|
||||||
this.lines.add(s);
|
this.lines.add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<StringLocated> lines() {
|
public final List<StringLocated> lines() {
|
||||||
|
// if (indentationDone == false) {
|
||||||
|
// CodeIteratorImpl.indentNow(lines);
|
||||||
|
// indentationDone = true;
|
||||||
|
// }
|
||||||
return Collections.unmodifiableList(lines);
|
return Collections.unmodifiableList(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Sub fromFile(ReadLine reader, String blocname, TContext context, TMemory memory) throws IOException,
|
public static Sub fromFile(ReadLine reader, String blocname, TContext context, TMemory memory)
|
||||||
EaterException {
|
throws IOException, EaterException {
|
||||||
Sub result = null;
|
Sub result = null;
|
||||||
StringLocated s = null;
|
StringLocated s = null;
|
||||||
|
boolean skip = false;
|
||||||
while ((s = reader.readLine()) != null) {
|
while ((s = reader.readLine()) != null) {
|
||||||
final TLineType type = TLineType.getFromLine(s.getTrimmed().getString());
|
final TLineType type = s.getTrimmed().getType();
|
||||||
if (type == TLineType.STARTSUB) {
|
if (type == TLineType.STARTSUB) {
|
||||||
final EaterStartsub eater = new EaterStartsub(s.getTrimmed().getString());
|
final EaterStartsub eater = new EaterStartsub(s.getTrimmed());
|
||||||
eater.execute(context, memory);
|
eater.analyze(context, memory);
|
||||||
if (eater.getSubname().equals(blocname)) {
|
if (eater.getSubname().equals(blocname)) {
|
||||||
result = new Sub(blocname);
|
skip = false;
|
||||||
|
if (result == null) {
|
||||||
|
result = new Sub(blocname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type == TLineType.ENDSUB && result != null) {
|
if (type == TLineType.ENDSUB && result != null) {
|
||||||
reader.close();
|
skip = true;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
if (result != null) {
|
if (result != null && skip == false) {
|
||||||
result.add(s);
|
result.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
return null;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -76,7 +76,7 @@ public class UncommentReadLine implements ReadLine {
|
|||||||
return new StringLocated("", result.getLocation());
|
return new StringLocated("", result.getLocation());
|
||||||
}
|
}
|
||||||
if (headerToRemove != null && result.getString().startsWith(headerToRemove)) {
|
if (headerToRemove != null && result.getString().startsWith(headerToRemove)) {
|
||||||
return result.sub(headerToRemove.length(), result.getString().length());
|
return result.substring(headerToRemove.length(), result.getString().length());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public class PreprocessorUtils {
|
|||||||
return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation());
|
return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new EaterException("Cannot open URL");
|
throw EaterException.located("Cannot open URL", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.project.core;
|
package net.sourceforge.plantuml.project.core;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.project.Load;
|
import net.sourceforge.plantuml.project.Load;
|
||||||
import net.sourceforge.plantuml.project.draw.TaskDraw;
|
import net.sourceforge.plantuml.project.draw.TaskDraw;
|
||||||
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
||||||
@ -70,5 +71,7 @@ public interface Task extends Subject, Moment {
|
|||||||
|
|
||||||
public void setCompletion(int completion);
|
public void setCompletion(int completion);
|
||||||
|
|
||||||
|
public void setUrl(Url url);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.project.Load;
|
import net.sourceforge.plantuml.project.Load;
|
||||||
import net.sourceforge.plantuml.project.LoadPlanable;
|
import net.sourceforge.plantuml.project.LoadPlanable;
|
||||||
import net.sourceforge.plantuml.project.PlanUtils;
|
import net.sourceforge.plantuml.project.PlanUtils;
|
||||||
@ -54,6 +55,14 @@ public class TaskImpl implements Task, LoadPlanable {
|
|||||||
private final LoadPlanable defaultPlan;
|
private final LoadPlanable defaultPlan;
|
||||||
private boolean diamond;
|
private boolean diamond;
|
||||||
|
|
||||||
|
private Url url;
|
||||||
|
private TaskDraw taskDraw;
|
||||||
|
private ComplementColors colors;
|
||||||
|
|
||||||
|
public void setUrl(Url url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
public TaskImpl(TaskCode code, LoadPlanable defaultPlan) {
|
public TaskImpl(TaskCode code, LoadPlanable defaultPlan) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.defaultPlan = defaultPlan;
|
this.defaultPlan = defaultPlan;
|
||||||
@ -72,7 +81,8 @@ public class TaskImpl implements Task, LoadPlanable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int loadForResource(Resource res, Wink instant) {
|
public int loadForResource(Resource res, Wink instant) {
|
||||||
if (resources2.keySet().contains(res) && instant.compareTo(getStart()) >= 0 && instant.compareTo(getEnd()) <= 0) {
|
if (resources2.keySet().contains(res) && instant.compareTo(getStart()) >= 0
|
||||||
|
&& instant.compareTo(getEnd()) <= 0) {
|
||||||
if (res.isClosedAt(instant)) {
|
if (res.isClosedAt(instant)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -172,11 +182,9 @@ public class TaskImpl implements Task, LoadPlanable {
|
|||||||
solver.setData(TaskAttribute.END, end);
|
solver.setData(TaskAttribute.END, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskDraw taskDraw;
|
|
||||||
private ComplementColors colors;
|
|
||||||
|
|
||||||
public void setTaskDraw(TaskDraw taskDraw) {
|
public void setTaskDraw(TaskDraw taskDraw) {
|
||||||
taskDraw.setColorsAndCompletion(colors, completion);
|
taskDraw.setColorsAndCompletion(colors, completion, url);
|
||||||
this.taskDraw = taskDraw;
|
this.taskDraw = taskDraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.project.core;
|
package net.sourceforge.plantuml.project.core;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.project.Load;
|
import net.sourceforge.plantuml.project.Load;
|
||||||
import net.sourceforge.plantuml.project.draw.TaskDraw;
|
import net.sourceforge.plantuml.project.draw.TaskDraw;
|
||||||
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
||||||
@ -112,4 +113,8 @@ public class TaskSeparator implements Task {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUrl(Url url) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,14 @@
|
|||||||
package net.sourceforge.plantuml.project.draw;
|
package net.sourceforge.plantuml.project.draw;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.Direction;
|
import net.sourceforge.plantuml.Direction;
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.graphic.UDrawable;
|
import net.sourceforge.plantuml.graphic.UDrawable;
|
||||||
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
import net.sourceforge.plantuml.project.lang.ComplementColors;
|
||||||
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
import net.sourceforge.plantuml.ugraphic.UGraphic;
|
||||||
|
|
||||||
public interface TaskDraw extends UDrawable {
|
public interface TaskDraw extends UDrawable {
|
||||||
|
|
||||||
public void setColorsAndCompletion(ComplementColors colors, int completion);
|
public void setColorsAndCompletion(ComplementColors colors, int completion, Url url);
|
||||||
|
|
||||||
public double getY();
|
public double getY();
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ package net.sourceforge.plantuml.project.draw;
|
|||||||
|
|
||||||
import net.sourceforge.plantuml.Direction;
|
import net.sourceforge.plantuml.Direction;
|
||||||
import net.sourceforge.plantuml.SpriteContainerEmpty;
|
import net.sourceforge.plantuml.SpriteContainerEmpty;
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||||
@ -66,6 +67,7 @@ public class TaskDrawRegular implements TaskDraw {
|
|||||||
private final double y;
|
private final double y;
|
||||||
private ComplementColors colors;
|
private ComplementColors colors;
|
||||||
private int completion = 100;
|
private int completion = 100;
|
||||||
|
private Url url;
|
||||||
|
|
||||||
private final double margin = 2;
|
private final double margin = 2;
|
||||||
|
|
||||||
@ -125,22 +127,29 @@ public class TaskDrawRegular implements TaskDraw {
|
|||||||
if (fullLength < 10) {
|
if (fullLength < 10) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (url != null) {
|
||||||
|
ug.startUrl(url);
|
||||||
|
}
|
||||||
final URectangle full = new URectangle(fullLength, getShapeHeight(), 8, 8);
|
final URectangle full = new URectangle(fullLength, getShapeHeight(), 8, 8);
|
||||||
if (completion == 100) {
|
if (completion == 100) {
|
||||||
ug.draw(full);
|
ug.draw(full);
|
||||||
return;
|
} else {
|
||||||
|
final double partialLength = fullLength * completion / 100.;
|
||||||
|
ug.apply(new UChangeColor(HtmlColorUtils.WHITE)).apply(new UChangeBackColor(HtmlColorUtils.WHITE))
|
||||||
|
.draw(full);
|
||||||
|
if (partialLength > 2) {
|
||||||
|
final URectangle partial = new URectangle(partialLength, getShapeHeight(), 8, 8);
|
||||||
|
ug.apply(new UChangeColor(null)).draw(partial);
|
||||||
|
}
|
||||||
|
if (partialLength > 10 && partialLength < fullLength - 10) {
|
||||||
|
final URectangle patch = new URectangle(8, getShapeHeight());
|
||||||
|
ug.apply(new UChangeColor(null)).apply(new UTranslate(partialLength - 8, 0)).draw(patch);
|
||||||
|
}
|
||||||
|
ug.apply(new UChangeBackColor(null)).draw(full);
|
||||||
}
|
}
|
||||||
final double partialLength = fullLength * completion / 100.;
|
if (url != null) {
|
||||||
ug.apply(new UChangeColor(HtmlColorUtils.WHITE)).apply(new UChangeBackColor(HtmlColorUtils.WHITE)).draw(full);
|
ug.closeAction();
|
||||||
if (partialLength > 2) {
|
|
||||||
final URectangle partial = new URectangle(partialLength, getShapeHeight(), 8, 8);
|
|
||||||
ug.apply(new UChangeColor(null)).draw(partial);
|
|
||||||
}
|
}
|
||||||
if (partialLength > 10 && partialLength < fullLength - 10) {
|
|
||||||
final URectangle patch = new URectangle(8, getShapeHeight());
|
|
||||||
ug.apply(new UChangeColor(null)).apply(new UTranslate(partialLength - 8, 0)).draw(patch);
|
|
||||||
}
|
|
||||||
ug.apply(new UChangeBackColor(null)).draw(full);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,8 +194,9 @@ public class TaskDrawRegular implements TaskDraw {
|
|||||||
return y + getHeight() / 2;
|
return y + getHeight() / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColorsAndCompletion(ComplementColors colors, int completion) {
|
public void setColorsAndCompletion(ComplementColors colors, int completion, Url url) {
|
||||||
this.colors = colors;
|
this.colors = colors;
|
||||||
this.completion = completion;
|
this.completion = completion;
|
||||||
|
this.url = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ package net.sourceforge.plantuml.project.draw;
|
|||||||
|
|
||||||
import net.sourceforge.plantuml.Direction;
|
import net.sourceforge.plantuml.Direction;
|
||||||
import net.sourceforge.plantuml.SpriteContainerEmpty;
|
import net.sourceforge.plantuml.SpriteContainerEmpty;
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
import net.sourceforge.plantuml.cucadiagram.Display;
|
import net.sourceforge.plantuml.cucadiagram.Display;
|
||||||
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
import net.sourceforge.plantuml.graphic.FontConfiguration;
|
||||||
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
|
||||||
@ -126,7 +127,7 @@ public class TaskDrawSeparator implements TaskDraw {
|
|||||||
return y + getHeight() / 2;
|
return y + getHeight() / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColorsAndCompletion(ComplementColors colors, int completion) {
|
public void setColorsAndCompletion(ComplementColors colors, int completion, Url url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements ComplementPatt
|
|||||||
|
|
||||||
public IRegex toRegex(String suffix) {
|
public IRegex toRegex(String suffix) {
|
||||||
return new RegexLeaf("COMPLEMENT" + suffix,
|
return new RegexLeaf("COMPLEMENT" + suffix,
|
||||||
"(?:at|(\\d+)[%s]+days?[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)");
|
"(?:at|with|after|(\\d+)[%s]+days?[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
|
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
|
||||||
|
62
src/net/sourceforge/plantuml/project/lang/ComplementUrl.java
Normal file
62
src/net/sourceforge/plantuml/project/lang/ComplementUrl.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.project.lang;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
|
import net.sourceforge.plantuml.UrlBuilder;
|
||||||
|
import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
|
||||||
|
import net.sourceforge.plantuml.command.regex.IRegex;
|
||||||
|
import net.sourceforge.plantuml.command.regex.RegexConcat;
|
||||||
|
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||||
|
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||||
|
import net.sourceforge.plantuml.project.Failable;
|
||||||
|
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||||
|
|
||||||
|
public class ComplementUrl implements ComplementPattern {
|
||||||
|
|
||||||
|
public IRegex toRegex(String suffix) {
|
||||||
|
return new RegexConcat( //
|
||||||
|
new RegexLeaf("COMPLEMENT" + suffix, "(" + UrlBuilder.getRegexp() + ")")); //
|
||||||
|
}
|
||||||
|
|
||||||
|
public Failable<Complement> getComplement(GanttDiagram diagram, RegexResult arg, String suffix) {
|
||||||
|
final String urlString = arg.get("COMPLEMENT" + suffix, 0);
|
||||||
|
final UrlBuilder urlBuilder = new UrlBuilder("", ModeUrl.STRICT);
|
||||||
|
final Url url = urlBuilder.getUrl(urlString);
|
||||||
|
return Failable.<Complement>ok(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -50,10 +50,9 @@ import net.sourceforge.plantuml.project.core.Task;
|
|||||||
public class SubjectTask implements SubjectPattern {
|
public class SubjectTask implements SubjectPattern {
|
||||||
|
|
||||||
public Collection<VerbPattern> getVerbs() {
|
public Collection<VerbPattern> getVerbs() {
|
||||||
return Arrays
|
return Arrays.<VerbPattern>asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
|
||||||
.<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
|
new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored(), new VerbIsDeleted(),
|
||||||
new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored(),
|
new VerbIsForTask(), new VerbLinksTo());
|
||||||
new VerbIsDeleted(), new VerbIsForTask());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRegex toRegex() {
|
public IRegex toRegex() {
|
||||||
|
70
src/net/sourceforge/plantuml/project/lang/VerbLinksTo.java
Normal file
70
src/net/sourceforge/plantuml/project/lang/VerbLinksTo.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.project.lang;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.Url;
|
||||||
|
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||||
|
import net.sourceforge.plantuml.command.regex.IRegex;
|
||||||
|
import net.sourceforge.plantuml.command.regex.RegexLeaf;
|
||||||
|
import net.sourceforge.plantuml.command.regex.RegexResult;
|
||||||
|
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||||
|
import net.sourceforge.plantuml.project.core.Task;
|
||||||
|
|
||||||
|
public class VerbLinksTo implements VerbPattern {
|
||||||
|
|
||||||
|
public Collection<ComplementPattern> getComplements() {
|
||||||
|
return Arrays.<ComplementPattern>asList(new ComplementUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRegex toRegex() {
|
||||||
|
return new RegexLeaf("links to");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Verb getVerb(GanttDiagram project, RegexResult arg) {
|
||||||
|
return new Verb() {
|
||||||
|
public CommandExecutionResult execute(Subject subject, Complement complement) {
|
||||||
|
final Task task = (Task) subject;
|
||||||
|
final Url url = (Url) complement;
|
||||||
|
task.setUrl(url);
|
||||||
|
return CommandExecutionResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -67,8 +67,8 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
|
|||||||
final protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) {
|
final protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) {
|
||||||
final String body = arg.getLazzy("ARROW_BODYA", 0) + arg.getLazzy("ARROW_BODYB", 0);
|
final String body = arg.getLazzy("ARROW_BODYA", 0) + arg.getLazzy("ARROW_BODYB", 0);
|
||||||
final String dressing = arg.getLazzy("ARROW_DRESSING", 0);
|
final String dressing = arg.getLazzy("ARROW_DRESSING", 0);
|
||||||
final Participant p = diagram.getOrCreateParticipant(StringUtils
|
final Participant p = diagram.getOrCreateParticipant(
|
||||||
.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("PARTICIPANT", 0)));
|
StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("PARTICIPANT", 0)));
|
||||||
|
|
||||||
final boolean sync = dressing.length() == 2;
|
final boolean sync = dressing.length() == 2;
|
||||||
final boolean dotted = body.contains("--");
|
final boolean dotted = body.contains("--");
|
||||||
@ -82,15 +82,17 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
|
|||||||
|
|
||||||
final boolean bothDirection = arg.get("ARROW_BOTHDRESSING", 0) != null;
|
final boolean bothDirection = arg.get("ARROW_BOTHDRESSING", 0) != null;
|
||||||
|
|
||||||
ArrowConfiguration config = bothDirection ? ArrowConfiguration.withDirectionBoth() : ArrowConfiguration
|
ArrowConfiguration config = bothDirection ? ArrowConfiguration.withDirectionBoth()
|
||||||
.withDirectionNormal();
|
: ArrowConfiguration.withDirectionNormal();
|
||||||
if (dotted) {
|
if (dotted) {
|
||||||
config = config.withBody(ArrowBody.DOTTED);
|
config = config.withBody(ArrowBody.DOTTED);
|
||||||
}
|
}
|
||||||
if (sync) {
|
if (sync) {
|
||||||
config = config.withHead(ArrowHead.ASYNC);
|
config = config.withHead(ArrowHead.ASYNC);
|
||||||
}
|
}
|
||||||
config = config.withPart(getArrowPart(dressing));
|
final MessageExoType messageExoType = getMessageExoType(arg);
|
||||||
|
|
||||||
|
config = config.withPart(getArrowPart(dressing, messageExoType));
|
||||||
config = CommandArrow.applyStyle(arg.getLazzy("ARROW_STYLE", 0), config);
|
config = CommandArrow.applyStyle(arg.getLazzy("ARROW_STYLE", 0), config);
|
||||||
|
|
||||||
final String activationSpec = arg.get("ACTIVATION", 0);
|
final String activationSpec = arg.get("ACTIVATION", 0);
|
||||||
@ -99,8 +101,6 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
|
|||||||
diagram.activate(p, LifeEventType.CREATE, null);
|
diagram.activate(p, LifeEventType.CREATE, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final MessageExoType messageExoType = getMessageExoType(arg);
|
|
||||||
|
|
||||||
if (messageExoType == MessageExoType.TO_RIGHT || messageExoType == MessageExoType.TO_LEFT) {
|
if (messageExoType == MessageExoType.TO_RIGHT || messageExoType == MessageExoType.TO_LEFT) {
|
||||||
if (containsSymbolExterior(arg, "o")) {
|
if (containsSymbolExterior(arg, "o")) {
|
||||||
config = config.withDecoration2(ArrowDecoration.CIRCLE);
|
config = config.withDecoration2(ArrowDecoration.CIRCLE);
|
||||||
@ -178,12 +178,18 @@ abstract class CommandExoArrowAny extends SingleLineCommand2<SequenceDiagram> {
|
|||||||
return CommandExecutionResult.ok();
|
return CommandExecutionResult.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrowPart getArrowPart(String dressing) {
|
private ArrowPart getArrowPart(String dressing, MessageExoType messageExoType) {
|
||||||
if (dressing.contains("/")) {
|
if (dressing.contains("/")) {
|
||||||
return ArrowPart.BOTTOM_PART;
|
if (messageExoType.getDirection() == 1) {
|
||||||
|
return ArrowPart.BOTTOM_PART;
|
||||||
|
}
|
||||||
|
return ArrowPart.TOP_PART;
|
||||||
}
|
}
|
||||||
if (dressing.contains("\\")) {
|
if (dressing.contains("\\")) {
|
||||||
return ArrowPart.TOP_PART;
|
if (messageExoType.getDirection() == 1) {
|
||||||
|
return ArrowPart.TOP_PART;
|
||||||
|
}
|
||||||
|
return ArrowPart.BOTTOM_PART;
|
||||||
}
|
}
|
||||||
return ArrowPart.FULL;
|
return ArrowPart.FULL;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,9 @@ public class PlayingSpace implements Bordered {
|
|||||||
for (LinkAnchor linkAnchor : linkAnchors) {
|
for (LinkAnchor linkAnchor : linkAnchors) {
|
||||||
final YPositionedTile tile1 = getFromAnchor(positionedTiles, linkAnchor.getAnchor1());
|
final YPositionedTile tile1 = getFromAnchor(positionedTiles, linkAnchor.getAnchor1());
|
||||||
final YPositionedTile tile2 = getFromAnchor(positionedTiles, linkAnchor.getAnchor2());
|
final YPositionedTile tile2 = getFromAnchor(positionedTiles, linkAnchor.getAnchor2());
|
||||||
linkAnchor.drawAnchor(ug, tile1, tile2, skinParam);
|
if (tile1 != null && tile2 != null) {
|
||||||
|
linkAnchor.drawAnchor(ug, tile1, tile2, skinParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// System.err.println("MainTile::drawUInternal finalY=" + y);
|
// System.err.println("MainTile::drawUInternal finalY=" + y);
|
||||||
return y;
|
return y;
|
||||||
|
@ -97,7 +97,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
|
|||||||
horizontalAlignment = style.getHorizontalAlignment();
|
horizontalAlignment = style.getHorizontalAlignment();
|
||||||
fontForStereotype = stereo.getUFont();
|
fontForStereotype = stereo.getUFont();
|
||||||
htmlColorForStereotype = stereo.value(PName.FontColor).asColor(getIHtmlColorSet());
|
htmlColorForStereotype = stereo.value(PName.FontColor).asColor(getIHtmlColorSet());
|
||||||
this.display = display.withoutStereotype(style);
|
this.display = display.withoutStereotypeIfNeeded(style);
|
||||||
} else {
|
} else {
|
||||||
this.font = fc.getFont();
|
this.font = fc.getFont();
|
||||||
this.fontColor = fc.getColor();
|
this.fontColor = fc.getColor();
|
||||||
|
@ -55,6 +55,7 @@ public enum PName {
|
|||||||
ExportedName, //
|
ExportedName, //
|
||||||
Image, //
|
Image, //
|
||||||
HorizontalAlignment, //
|
HorizontalAlignment, //
|
||||||
|
ShowStereotype, //
|
||||||
ImagePosition;
|
ImagePosition;
|
||||||
|
|
||||||
public static PName getFromName(String name) {
|
public static PName getFromName(String name) {
|
||||||
|
@ -49,6 +49,8 @@ public interface Value {
|
|||||||
|
|
||||||
public double asDouble();
|
public double asDouble();
|
||||||
|
|
||||||
|
public boolean asBoolean();
|
||||||
|
|
||||||
public int asFontStyle();
|
public int asFontStyle();
|
||||||
|
|
||||||
public HorizontalAlignment asHorizontalAlignment();
|
public HorizontalAlignment asHorizontalAlignment();
|
||||||
|
@ -57,6 +57,10 @@ public abstract class ValueAbstract implements Value {
|
|||||||
throw new UnsupportedOperationException("Class=" + getClass());
|
throw new UnsupportedOperationException("Class=" + getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean asBoolean() {
|
||||||
|
throw new UnsupportedOperationException("Class=" + getClass());
|
||||||
|
}
|
||||||
|
|
||||||
public int asFontStyle() {
|
public int asFontStyle() {
|
||||||
throw new UnsupportedOperationException("Class=" + getClass());
|
throw new UnsupportedOperationException("Class=" + getClass());
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,10 @@ public class ValueImpl implements Value {
|
|||||||
return set.getColorIfValid(value);
|
return set.getColorIfValid(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean asBoolean() {
|
||||||
|
return "true".equalsIgnoreCase(value);
|
||||||
|
}
|
||||||
|
|
||||||
public int asInt() {
|
public int asInt() {
|
||||||
return Integer.parseInt(value);
|
return Integer.parseInt(value);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,11 @@ public class ValueNull extends ValueAbstract implements Value {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean asBoolean() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asString() {
|
public String asString() {
|
||||||
return "";
|
return "";
|
||||||
|
@ -50,12 +50,28 @@ public abstract class Eater {
|
|||||||
|
|
||||||
private int i = 0;
|
private int i = 0;
|
||||||
private final String s;
|
private final String s;
|
||||||
|
private final StringLocated sl;
|
||||||
|
|
||||||
public Eater(String s) {
|
public Eater(StringLocated sl) {
|
||||||
this.s = s;
|
this.s = sl.getString();
|
||||||
|
this.sl = sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void execute(TContext context, TMemory memory) throws EaterException;
|
public final StringLocated getStringLocated() {
|
||||||
|
if (sl == null) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final LineLocation getLineLocation() {
|
||||||
|
if (sl == null) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
return sl.getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
public int getCurrentPosition() {
|
public int getCurrentPosition() {
|
||||||
return i;
|
return i;
|
||||||
@ -67,26 +83,31 @@ public abstract class Eater {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected TValue eatExpression(TContext context, TMemory memory) throws EaterException {
|
final protected TValue eatExpression(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
if (peekChar() == '{') {
|
if (peekChar() == '{') {
|
||||||
String data = eatAllToEnd();
|
String data = eatAllToEnd();
|
||||||
System.err.println("data=" + data);
|
// System.err.println("data=" + data);
|
||||||
JsonValue json = Json.parse(data);
|
final JsonValue json = Json.parse(data);
|
||||||
System.err.println("json=" + json);
|
// System.err.println("json=" + json);
|
||||||
return TValue.fromJson(json);
|
return TValue.fromJson(json);
|
||||||
}
|
}
|
||||||
|
final TokenStack tokenStack = eatTokenStack();
|
||||||
|
return tokenStack.getResult(getLineLocation(), context, memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected TokenStack eatTokenStack() throws EaterException {
|
||||||
final TokenStack tokenStack = new TokenStack();
|
final TokenStack tokenStack = new TokenStack();
|
||||||
addIntoTokenStack(tokenStack, false);
|
addIntoTokenStack(tokenStack, false);
|
||||||
if (tokenStack.size() == 0) {
|
if (tokenStack.size() == 0) {
|
||||||
throw new EaterException("Missing expression");
|
throw EaterException.located("Missing expression", getStringLocated());
|
||||||
}
|
}
|
||||||
return tokenStack.getResult(context, memory);
|
return tokenStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected TValue eatExpressionStopAtColon(TContext context, TMemory memory) throws EaterException {
|
final protected TValue eatExpressionStopAtColon(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
final TokenStack tokenStack = new TokenStack();
|
final TokenStack tokenStack = new TokenStack();
|
||||||
addIntoTokenStack(tokenStack, true);
|
addIntoTokenStack(tokenStack, true);
|
||||||
return tokenStack.getResult(context, memory);
|
return tokenStack.getResult(getLineLocation(), context, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected void addIntoTokenStack(TokenStack tokenStack, boolean stopAtColon) throws EaterException {
|
final protected void addIntoTokenStack(TokenStack tokenStack, boolean stopAtColon) throws EaterException {
|
||||||
@ -103,7 +124,7 @@ public abstract class Eater {
|
|||||||
final public String eatAndGetQuotedString() throws EaterException {
|
final public String eatAndGetQuotedString() throws EaterException {
|
||||||
final char separator = peekChar();
|
final char separator = peekChar();
|
||||||
if (TLineType.isQuote(separator) == false) {
|
if (TLineType.isQuote(separator) == false) {
|
||||||
throw new EaterException("quote10");
|
throw EaterException.located("quote10", getStringLocated());
|
||||||
}
|
}
|
||||||
checkAndEatChar(separator);
|
checkAndEatChar(separator);
|
||||||
final StringBuilder value = new StringBuilder();
|
final StringBuilder value = new StringBuilder();
|
||||||
@ -124,7 +145,7 @@ public abstract class Eater {
|
|||||||
while (true) {
|
while (true) {
|
||||||
char ch = peekChar();
|
char ch = peekChar();
|
||||||
if (ch == 0) {
|
if (ch == 0) {
|
||||||
throw new EaterException("until001");
|
throw EaterException.located("until001", getStringLocated());
|
||||||
}
|
}
|
||||||
if (level == 0 && (ch == ',' || ch == ')')) {
|
if (level == 0 && (ch == ',' || ch == ')')) {
|
||||||
return value.toString().trim();
|
return value.toString().trim();
|
||||||
@ -167,7 +188,7 @@ public abstract class Eater {
|
|||||||
final protected String eatAndGetVarname() throws EaterException {
|
final protected String eatAndGetVarname() throws EaterException {
|
||||||
final StringBuilder varname = new StringBuilder("" + eatOneChar());
|
final StringBuilder varname = new StringBuilder("" + eatOneChar());
|
||||||
if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) {
|
if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) {
|
||||||
throw new EaterException("a002");
|
throw EaterException.located("a002", getStringLocated());
|
||||||
}
|
}
|
||||||
addUpToLastLetterOrUnderscoreOrDigit(varname);
|
addUpToLastLetterOrUnderscoreOrDigit(varname);
|
||||||
return varname.toString();
|
return varname.toString();
|
||||||
@ -176,7 +197,7 @@ public abstract class Eater {
|
|||||||
final protected String eatAndGetFunctionName() throws EaterException {
|
final protected String eatAndGetFunctionName() throws EaterException {
|
||||||
final StringBuilder varname = new StringBuilder("" + eatOneChar());
|
final StringBuilder varname = new StringBuilder("" + eatOneChar());
|
||||||
if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) {
|
if (TLineType.isLetterOrUnderscoreOrDollar(varname.charAt(0)) == false) {
|
||||||
throw new EaterException("a003");
|
throw EaterException.located("a003", getStringLocated());
|
||||||
}
|
}
|
||||||
addUpToLastLetterOrUnderscoreOrDigit(varname);
|
addUpToLastLetterOrUnderscoreOrDigit(varname);
|
||||||
return varname.toString();
|
return varname.toString();
|
||||||
@ -220,7 +241,7 @@ public abstract class Eater {
|
|||||||
|
|
||||||
final protected void checkAndEatChar(char ch) throws EaterException {
|
final protected void checkAndEatChar(char ch) throws EaterException {
|
||||||
if (i >= s.length() || s.charAt(i) != ch) {
|
if (i >= s.length() || s.charAt(i) != ch) {
|
||||||
throw new EaterException("a001");
|
throw EaterException.located("a001", getStringLocated());
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -269,7 +290,8 @@ public abstract class Eater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// final protected void addUpToUnused(char separator1, char separator2, StringBuilder sb) {
|
// final protected void addUpToUnused(char separator1, char separator2,
|
||||||
|
// StringBuilder sb) {
|
||||||
// while (i < s.length()) {
|
// while (i < s.length()) {
|
||||||
// final char ch = peekChar();
|
// final char ch = peekChar();
|
||||||
// if (ch == separator1 || ch == separator2) {
|
// if (ch == separator1 || ch == separator2) {
|
||||||
@ -281,7 +303,7 @@ public abstract class Eater {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
final protected TFunctionImpl eatDeclareFunction(TContext context, TMemory memory, boolean unquoted,
|
final protected TFunctionImpl eatDeclareFunction(TContext context, TMemory memory, boolean unquoted,
|
||||||
LineLocation location, boolean allowNoParenthesis) throws EaterException {
|
LineLocation location, boolean allowNoParenthesis) throws EaterException, EaterExceptionLocated {
|
||||||
final List<TFunctionArgument> args = new ArrayList<TFunctionArgument>();
|
final List<TFunctionArgument> args = new ArrayList<TFunctionArgument>();
|
||||||
final String functionName = eatAndGetFunctionName();
|
final String functionName = eatAndGetFunctionName();
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -289,7 +311,7 @@ public abstract class Eater {
|
|||||||
if (allowNoParenthesis) {
|
if (allowNoParenthesis) {
|
||||||
return new TFunctionImpl(functionName, args, unquoted);
|
return new TFunctionImpl(functionName, args, unquoted);
|
||||||
}
|
}
|
||||||
throw new EaterException("Missing opening parenthesis");
|
throw EaterException.located("Missing opening parenthesis", getStringLocated());
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -302,7 +324,7 @@ public abstract class Eater {
|
|||||||
eatOneChar();
|
eatOneChar();
|
||||||
final TokenStack def = TokenStack.eatUntilCloseParenthesisOrComma(this);
|
final TokenStack def = TokenStack.eatUntilCloseParenthesisOrComma(this);
|
||||||
def.guessFunctions();
|
def.guessFunctions();
|
||||||
defValue = def.getResult(context, memory);
|
defValue = def.getResult(getLineLocation(), context, memory);
|
||||||
// System.err.println("result=" + defValue);
|
// System.err.println("result=" + defValue);
|
||||||
} else {
|
} else {
|
||||||
defValue = null;
|
defValue = null;
|
||||||
@ -314,7 +336,7 @@ public abstract class Eater {
|
|||||||
checkAndEatChar(")");
|
checkAndEatChar(")");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
throw new EaterException("Error in function definition");
|
throw EaterException.located("Error in function definition", getStringLocated());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -322,7 +344,7 @@ public abstract class Eater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final protected TFunctionImpl eatDeclareFunctionWithOptionalReturn(TContext context, TMemory memory,
|
final protected TFunctionImpl eatDeclareFunctionWithOptionalReturn(TContext context, TMemory memory,
|
||||||
boolean unquoted, LineLocation location) throws EaterException {
|
boolean unquoted, LineLocation location) throws EaterException, EaterExceptionLocated {
|
||||||
final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false);
|
final TFunctionImpl result = eatDeclareFunction(context, memory, unquoted, location, false);
|
||||||
if (peekChar() == 'r') {
|
if (peekChar() == 'r') {
|
||||||
checkAndEatChar("return");
|
checkAndEatChar("return");
|
||||||
|
@ -34,16 +34,17 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterAffectation extends Eater {
|
public class EaterAffectation extends Eater {
|
||||||
|
|
||||||
public EaterAffectation(String s) {
|
public EaterAffectation(StringLocated sl) {
|
||||||
super(s);
|
super(sl.getTrimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!");
|
checkAndEatChar("!");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -58,7 +59,7 @@ public class EaterAffectation extends Eater {
|
|||||||
checkAndEatChar('=');
|
checkAndEatChar('=');
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
final TValue value = eatExpression(context, memory);
|
final TValue value = eatExpression(context, memory);
|
||||||
memory.putVariable(varname, new TVariable(value), scope);
|
memory.putVariable(varname, value, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,28 +34,29 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterAffectationDefine extends Eater {
|
public class EaterAffectationDefine extends Eater {
|
||||||
|
|
||||||
public EaterAffectationDefine(String s) {
|
public EaterAffectationDefine(StringLocated s) {
|
||||||
super(s);
|
super(s.getTrimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!define");
|
checkAndEatChar("!define");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
final String varname = eatAndGetVarname();
|
final String varname = eatAndGetVarname();
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
final String tmp = eatAllToEnd();
|
final String tmp = eatAllToEnd();
|
||||||
final String tmp2 = context.applyFunctionsAndVariables(memory, tmp);
|
final String tmp2 = context.applyFunctionsAndVariables(memory, getLineLocation(), tmp);
|
||||||
final TValue value = TValue.fromString(tmp2);
|
final TValue value = TValue.fromString(tmp2);
|
||||||
// if (memory instanceof TMemoryLocal) {
|
// if (memory instanceof TMemoryLocal) {
|
||||||
// memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly();
|
// memory = ((TMemoryLocal) memory).getGlobalForInternalUseOnly();
|
||||||
// }
|
// }
|
||||||
memory.putVariable(varname, new TVariable(value), TVariableScope.GLOBAL);
|
memory.putVariable(varname, value, TVariableScope.GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,16 +34,17 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterAssert extends Eater {
|
public class EaterAssert extends Eater {
|
||||||
|
|
||||||
public EaterAssert(String s) {
|
public EaterAssert(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!assert");
|
checkAndEatChar("!assert");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -54,9 +55,9 @@ public class EaterAssert extends Eater {
|
|||||||
if (ch == ':') {
|
if (ch == ':') {
|
||||||
checkAndEatChar(':');
|
checkAndEatChar(':');
|
||||||
final TValue message = eatExpression(context, memory);
|
final TValue message = eatExpression(context, memory);
|
||||||
throw new EaterException("Assertion error : " + message.toString());
|
throw EaterException.located("Assertion error : " + message.toString(), getStringLocated());
|
||||||
}
|
}
|
||||||
throw new EaterException("Assertion error");
|
throw EaterException.located("Assertion error", getStringLocated());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,12 +44,12 @@ public class EaterDeclareFunction extends Eater {
|
|||||||
private boolean finalFlag;
|
private boolean finalFlag;
|
||||||
|
|
||||||
public EaterDeclareFunction(StringLocated s) {
|
public EaterDeclareFunction(StringLocated s) {
|
||||||
super(s.getTrimmed().getString());
|
super(s.getTrimmed());
|
||||||
this.location = s.getLocation();
|
this.location = s.getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!");
|
checkAndEatChar("!");
|
||||||
boolean unquoted = false;
|
boolean unquoted = false;
|
||||||
|
@ -34,14 +34,16 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterDumpMemory extends Eater {
|
public class EaterDumpMemory extends Eater {
|
||||||
|
|
||||||
public EaterDumpMemory(String s) {
|
public EaterDumpMemory(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!dump_memory");
|
checkAndEatChar("!dump_memory");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
|
@ -34,18 +34,19 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterElseIf extends Eater {
|
public class EaterElseIf extends Eater {
|
||||||
|
|
||||||
private boolean booleanValue;
|
private boolean booleanValue;
|
||||||
|
|
||||||
public EaterElseIf(String s) {
|
public EaterElseIf(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!elseif");
|
checkAndEatChar("!elseif");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
|
@ -39,23 +39,25 @@ import net.sourceforge.plantuml.StringLocated;
|
|||||||
public class EaterException extends Exception {
|
public class EaterException extends Exception {
|
||||||
|
|
||||||
private final String message;
|
private final String message;
|
||||||
private final StringLocated location;
|
|
||||||
|
|
||||||
public EaterException(String message, StringLocated location) {
|
private EaterException(String message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.location = location;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EaterException(String message) {
|
public static EaterException unlocated(String message) {
|
||||||
this(message, null);
|
return new EaterException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EaterException located(String message, StringLocated unused) {
|
||||||
|
return new EaterException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getMessage() {
|
public final String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final StringLocated getLocation() {
|
public EaterExceptionLocated withLocation(StringLocated sl) {
|
||||||
return location;
|
return EaterExceptionLocated.located(message, sl);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,32 +34,31 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
import java.util.Deque;
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
public abstract class ConditionalContexts {
|
public class EaterExceptionLocated extends Exception {
|
||||||
|
|
||||||
private final Deque<ConditionalContext> allIfs = new LinkedList<ConditionalContext>();
|
private final String message;
|
||||||
|
private final StringLocated location;
|
||||||
|
|
||||||
public ConditionalContext peekConditionalContext() {
|
private EaterExceptionLocated(String message, StringLocated location) {
|
||||||
return allIfs.peekLast();
|
this.message = message;
|
||||||
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConditionalContext(ConditionalContext fromValue) {
|
public static EaterExceptionLocated located(String message, StringLocated location) {
|
||||||
allIfs.addLast(fromValue);
|
if (location == null) {
|
||||||
}
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
public ConditionalContext pollConditionalContext() {
|
|
||||||
return allIfs.pollLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean areAllIfOk() {
|
|
||||||
for (ConditionalContext conditionalContext : allIfs) {
|
|
||||||
if (conditionalContext.conditionIsOkHere() == false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return new EaterExceptionLocated(message, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final StringLocated getLocation() {
|
||||||
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
78
src/net/sourceforge/plantuml/tim/EaterForeach.java
Normal file
78
src/net/sourceforge/plantuml/tim/EaterForeach.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.json.JsonArray;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
|
public class EaterForeach extends Eater {
|
||||||
|
|
||||||
|
private String varname;
|
||||||
|
private JsonArray jsonArray;
|
||||||
|
|
||||||
|
public EaterForeach(StringLocated s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
|
skipSpaces();
|
||||||
|
checkAndEatChar("!foreach");
|
||||||
|
skipSpaces();
|
||||||
|
this.varname = eatAndGetVarname();
|
||||||
|
skipSpaces();
|
||||||
|
checkAndEatChar("in");
|
||||||
|
skipSpaces();
|
||||||
|
final TValue value = eatExpression(context, memory);
|
||||||
|
this.jsonArray = (JsonArray) value.toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSkip() {
|
||||||
|
if (this.jsonArray == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return this.jsonArray.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getVarname() {
|
||||||
|
return varname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final JsonArray getJsonArray() {
|
||||||
|
return jsonArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,6 +38,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
import net.sourceforge.plantuml.tim.expression.TokenStack;
|
import net.sourceforge.plantuml.tim.expression.TokenStack;
|
||||||
|
|
||||||
@ -47,14 +48,14 @@ public class EaterFunctionCall extends Eater {
|
|||||||
private final boolean isLegacyDefine;
|
private final boolean isLegacyDefine;
|
||||||
private final boolean unquoted;
|
private final boolean unquoted;
|
||||||
|
|
||||||
public EaterFunctionCall(String s, boolean isLegacyDefine, boolean unquoted) {
|
public EaterFunctionCall(StringLocated s, boolean isLegacyDefine, boolean unquoted) {
|
||||||
super(s);
|
super(s);
|
||||||
this.isLegacyDefine = isLegacyDefine;
|
this.isLegacyDefine = isLegacyDefine;
|
||||||
this.unquoted = unquoted;
|
this.unquoted = unquoted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipUntilChar('(');
|
skipUntilChar('(');
|
||||||
checkAndEatChar('(');
|
checkAndEatChar('(');
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -66,7 +67,7 @@ public class EaterFunctionCall extends Eater {
|
|||||||
skipSpaces();
|
skipSpaces();
|
||||||
if (isLegacyDefine || unquoted) {
|
if (isLegacyDefine || unquoted) {
|
||||||
final String tmp = eatAndGetOptionalQuotedString();
|
final String tmp = eatAndGetOptionalQuotedString();
|
||||||
final String tmp2 = context.applyFunctionsAndVariables(memory, tmp);
|
final String tmp2 = context.applyFunctionsAndVariables(memory, getLineLocation(), tmp);
|
||||||
// final TVariable var = memory.getVariable(tmp);
|
// final TVariable var = memory.getVariable(tmp);
|
||||||
// final TValue result = var == null ? TValue.fromString(tmp) : var.getValue2();
|
// final TValue result = var == null ? TValue.fromString(tmp) : var.getValue2();
|
||||||
final TValue result = TValue.fromString(tmp2);
|
final TValue result = TValue.fromString(tmp2);
|
||||||
@ -74,7 +75,7 @@ public class EaterFunctionCall extends Eater {
|
|||||||
} else {
|
} else {
|
||||||
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
|
final TokenStack tokens = TokenStack.eatUntilCloseParenthesisOrComma(this).withoutSpace();
|
||||||
tokens.guessFunctions();
|
tokens.guessFunctions();
|
||||||
final TValue result = tokens.getResult(context, memory);
|
final TValue result = tokens.getResult(getLineLocation(), context, memory);
|
||||||
values.add(result);
|
values.add(result);
|
||||||
}
|
}
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -85,7 +86,7 @@ public class EaterFunctionCall extends Eater {
|
|||||||
if (ch == ')') {
|
if (ch == ')') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
throw new EaterException("call001");
|
throw EaterException.located("call001", getStringLocated());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,18 +34,19 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterIf extends Eater {
|
public class EaterIf extends Eater {
|
||||||
|
|
||||||
private boolean booleanValue;
|
private boolean booleanValue;
|
||||||
|
|
||||||
public EaterIf(String s) {
|
public EaterIf(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!if");
|
checkAndEatChar("!if");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
|
@ -34,19 +34,21 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.preproc.EvalBoolean;
|
import net.sourceforge.plantuml.preproc.EvalBoolean;
|
||||||
import net.sourceforge.plantuml.preproc.Truth;
|
import net.sourceforge.plantuml.preproc.Truth;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterIfdef extends Eater {
|
public class EaterIfdef extends Eater {
|
||||||
|
|
||||||
private String expression;
|
private String expression;
|
||||||
|
|
||||||
public EaterIfdef(String s) {
|
public EaterIfdef(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!ifdef");
|
checkAndEatChar("!ifdef");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -57,7 +59,7 @@ public class EaterIfdef extends Eater {
|
|||||||
final EvalBoolean eval = new EvalBoolean(expression, new Truth() {
|
final EvalBoolean eval = new EvalBoolean(expression, new Truth() {
|
||||||
|
|
||||||
public boolean isTrue(String varname) {
|
public boolean isTrue(String varname) {
|
||||||
final TVariable currentValue = memory.getVariable(varname);
|
final TValue currentValue = memory.getVariable(varname);
|
||||||
return currentValue != null || context.doesFunctionExist(varname);
|
return currentValue != null || context.doesFunctionExist(varname);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -34,16 +34,19 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterIfndef extends Eater {
|
public class EaterIfndef extends Eater {
|
||||||
|
|
||||||
private String varname;
|
private String varname;
|
||||||
|
|
||||||
public EaterIfndef(String s) {
|
public EaterIfndef(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!ifndef");
|
checkAndEatChar("!ifndef");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
@ -51,7 +54,7 @@ public class EaterIfndef extends Eater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTrue(TContext context, TMemory memory) {
|
public boolean isTrue(TContext context, TMemory memory) {
|
||||||
final TVariable currentValue = memory.getVariable(varname);
|
final TValue currentValue = memory.getVariable(varname);
|
||||||
return currentValue == null && context.doesFunctionExist(varname) == false;
|
return currentValue == null && context.doesFunctionExist(varname) == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,20 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterImport extends Eater {
|
public class EaterImport extends Eater {
|
||||||
|
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
public EaterImport(String s) {
|
public EaterImport(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!import");
|
checkAndEatChar("!import");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd());
|
this.location = context.applyFunctionsAndVariables(memory, getLineLocation(), this.eatAllToEnd());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy;
|
import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy;
|
||||||
|
|
||||||
public class EaterInclude extends Eater {
|
public class EaterInclude extends Eater {
|
||||||
@ -41,12 +42,12 @@ public class EaterInclude extends Eater {
|
|||||||
private String location;
|
private String location;
|
||||||
private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.DEFAULT;
|
private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.DEFAULT;
|
||||||
|
|
||||||
public EaterInclude(String s) {
|
public EaterInclude(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!include");
|
checkAndEatChar("!include");
|
||||||
final char peekChar = peekChar();
|
final char peekChar = peekChar();
|
||||||
@ -64,7 +65,7 @@ public class EaterInclude extends Eater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd());
|
this.location = context.applyFunctionsAndVariables(memory, getLineLocation(), this.eatAllToEnd());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,21 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterIncludeDef extends Eater {
|
public class EaterIncludeDef extends Eater {
|
||||||
|
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
public EaterIncludeDef(String s) {
|
public EaterIncludeDef(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!includedef");
|
checkAndEatChar("!includedef");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd());
|
this.location = context.applyFunctionsAndVariables(memory, getLineLocation(), this.eatAllToEnd());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,20 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterIncludesub extends Eater {
|
public class EaterIncludesub extends Eater {
|
||||||
|
|
||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
public EaterIncludesub(String s) {
|
public EaterIncludesub(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!includesub");
|
checkAndEatChar("!includesub");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
this.location = context.applyFunctionsAndVariables(memory, this.eatAllToEnd());
|
this.location = context.applyFunctionsAndVariables(memory, getLineLocation(), this.eatAllToEnd());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,25 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.LineLocation;
|
|
||||||
import net.sourceforge.plantuml.StringLocated;
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterLegacyDefine extends Eater {
|
public class EaterLegacyDefine extends Eater {
|
||||||
|
|
||||||
private TFunctionImpl function;
|
private TFunctionImpl function;
|
||||||
private final LineLocation location;
|
|
||||||
|
|
||||||
public EaterLegacyDefine(StringLocated s) {
|
public EaterLegacyDefine(StringLocated s) {
|
||||||
super(s.getTrimmed().getString());
|
super(s.getTrimmed());
|
||||||
this.location = s.getLocation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!define");
|
checkAndEatChar("!define");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
function = eatDeclareFunction(context, memory, true, location, false);
|
function = eatDeclareFunction(context, memory, true, getLineLocation(), false);
|
||||||
final String def = this.eatAllToEnd();
|
final String def = this.eatAllToEnd();
|
||||||
function.setFunctionType(TFunctionType.LEGACY_DEFINE);
|
function.setFunctionType(TFunctionType.LEGACY_DEFINE);
|
||||||
function.setLegacyDefinition(def);
|
function.setLegacyDefinition(def);
|
||||||
|
@ -34,25 +34,22 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.LineLocation;
|
|
||||||
import net.sourceforge.plantuml.StringLocated;
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterLegacyDefineLong extends Eater {
|
public class EaterLegacyDefineLong extends Eater {
|
||||||
|
|
||||||
private TFunctionImpl function;
|
private TFunctionImpl function;
|
||||||
private final LineLocation location;
|
|
||||||
|
|
||||||
public EaterLegacyDefineLong(StringLocated s) {
|
public EaterLegacyDefineLong(StringLocated s) {
|
||||||
super(s.getTrimmed().getString());
|
super(s.getTrimmed());
|
||||||
this.location = s.getLocation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!definelong");
|
checkAndEatChar("!definelong");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
function = eatDeclareFunction(context, memory, true, location, true);
|
function = eatDeclareFunction(context, memory, true, getLineLocation(), true);
|
||||||
function.setFunctionType(TFunctionType.LEGACY_DEFINELONG);
|
function.setFunctionType(TFunctionType.LEGACY_DEFINELONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,19 +35,20 @@
|
|||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.Log;
|
import net.sourceforge.plantuml.Log;
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterLog extends Eater {
|
public class EaterLog extends Eater {
|
||||||
|
|
||||||
public EaterLog(String s) {
|
public EaterLog(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!log");
|
checkAndEatChar("!log");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
final String logData = context.applyFunctionsAndVariables(memory, this.eatAllToEnd());
|
final String logData = context.applyFunctionsAndVariables(memory, getLineLocation(), this.eatAllToEnd());
|
||||||
Log.error("[Log] " + logData);
|
Log.error("[Log] " + logData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,18 +34,19 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class EaterReturn extends Eater {
|
public class EaterReturn extends Eater {
|
||||||
|
|
||||||
private TValue value;
|
private TValue value;
|
||||||
|
|
||||||
public EaterReturn(String s) {
|
public EaterReturn(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!return");
|
checkAndEatChar("!return");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
|
@ -34,22 +34,24 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
public class EaterStartsub extends Eater {
|
public class EaterStartsub extends Eater {
|
||||||
|
|
||||||
private String subname;
|
private String subname;
|
||||||
|
|
||||||
public EaterStartsub(String s) {
|
public EaterStartsub(StringLocated s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!startsub");
|
checkAndEatChar("!startsub");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
this.subname = eatAllToEnd();
|
this.subname = eatAllToEnd();
|
||||||
if (this.subname.matches("\\w+") == false) {
|
if (this.subname.matches("\\w+") == false) {
|
||||||
throw new EaterException("Bad sub name");
|
throw EaterException.located("Bad sub name", getStringLocated());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,11 @@ import net.sourceforge.plantuml.StringLocated;
|
|||||||
public class EaterUndef extends Eater {
|
public class EaterUndef extends Eater {
|
||||||
|
|
||||||
public EaterUndef(StringLocated s) {
|
public EaterUndef(StringLocated s) {
|
||||||
super(s.getTrimmed().getString());
|
super(s.getTrimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(TContext context, TMemory memory) throws EaterException {
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
checkAndEatChar("!undef");
|
checkAndEatChar("!undef");
|
||||||
skipSpaces();
|
skipSpaces();
|
||||||
|
59
src/net/sourceforge/plantuml/tim/EaterWhile.java
Normal file
59
src/net/sourceforge/plantuml/tim/EaterWhile.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TokenStack;
|
||||||
|
|
||||||
|
public class EaterWhile extends Eater {
|
||||||
|
|
||||||
|
private TokenStack expression;
|
||||||
|
|
||||||
|
public EaterWhile(StringLocated s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(TContext context, TMemory memory) throws EaterException {
|
||||||
|
skipSpaces();
|
||||||
|
checkAndEatChar("!while");
|
||||||
|
skipSpaces();
|
||||||
|
this.expression = eatTokenStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final TokenStack getWhileExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.json.JsonArray;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodePosition;
|
||||||
|
|
||||||
|
public class ExecutionContextForeach {
|
||||||
|
|
||||||
|
private final String varname;
|
||||||
|
private final JsonArray jsonArray;
|
||||||
|
private final CodePosition codePosition;
|
||||||
|
private boolean skipMe;
|
||||||
|
private int currentIndex;
|
||||||
|
|
||||||
|
private ExecutionContextForeach(String varname, JsonArray jsonArray, CodePosition codePosition) {
|
||||||
|
this.varname = varname;
|
||||||
|
this.jsonArray = jsonArray;
|
||||||
|
this.codePosition = codePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExecutionContextForeach fromValue(String varname, JsonArray jsonArray, CodePosition codePosition) {
|
||||||
|
return new ExecutionContextForeach(varname, jsonArray, codePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipMeNow() {
|
||||||
|
skipMe = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isSkipMe() {
|
||||||
|
return skipMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodePosition getStartForeach() {
|
||||||
|
return codePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int currentIndex() {
|
||||||
|
return currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void inc() {
|
||||||
|
this.currentIndex++;
|
||||||
|
if (currentIndex >= jsonArray.size()) {
|
||||||
|
this.skipMe = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getVarname() {
|
||||||
|
return varname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final JsonArray getJsonArray() {
|
||||||
|
return jsonArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -34,20 +34,20 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
public class ConditionalContext {
|
public class ExecutionContextIf {
|
||||||
|
|
||||||
private boolean isTrue;
|
private boolean isTrue;
|
||||||
private boolean hasBeenBurn;
|
private boolean hasBeenBurn;
|
||||||
|
|
||||||
private ConditionalContext(boolean isTrue) {
|
private ExecutionContextIf(boolean isTrue) {
|
||||||
this.isTrue = isTrue;
|
this.isTrue = isTrue;
|
||||||
if (this.isTrue) {
|
if (this.isTrue) {
|
||||||
hasBeenBurn = true;
|
hasBeenBurn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConditionalContext fromValue(boolean isTrue) {
|
public static ExecutionContextIf fromValue(boolean isTrue) {
|
||||||
return new ConditionalContext(isTrue);
|
return new ExecutionContextIf(isTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean conditionIsOkHere() {
|
public boolean conditionIsOkHere() {
|
78
src/net/sourceforge/plantuml/tim/ExecutionContextWhile.java
Normal file
78
src/net/sourceforge/plantuml/tim/ExecutionContextWhile.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TokenStack;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodePosition;
|
||||||
|
|
||||||
|
public class ExecutionContextWhile {
|
||||||
|
|
||||||
|
private final TokenStack whileExpression;
|
||||||
|
private final CodePosition codePosition;
|
||||||
|
private boolean skipMe;
|
||||||
|
|
||||||
|
private ExecutionContextWhile(TokenStack whileExpression, CodePosition codePosition) {
|
||||||
|
this.whileExpression = whileExpression;
|
||||||
|
this.codePosition = codePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return whileExpression.toString() + " " + codePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExecutionContextWhile fromValue(TokenStack whileExpression, CodePosition codePosition) {
|
||||||
|
return new ExecutionContextWhile(whileExpression, codePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue conditionValue(LineLocation location, TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
|
return whileExpression.getResult(location, context, memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipMe() {
|
||||||
|
skipMe = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isSkipMe() {
|
||||||
|
return skipMe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodePosition getStartWhile() {
|
||||||
|
return codePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
91
src/net/sourceforge/plantuml/tim/ExecutionContexts.java
Normal file
91
src/net/sourceforge/plantuml/tim/ExecutionContexts.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public abstract class ExecutionContexts {
|
||||||
|
|
||||||
|
private final Deque<ExecutionContextIf> allIfs = new LinkedList<ExecutionContextIf>();
|
||||||
|
private final Deque<ExecutionContextWhile> allWhiles = new LinkedList<ExecutionContextWhile>();
|
||||||
|
private final Deque<ExecutionContextForeach> allForeachs = new LinkedList<ExecutionContextForeach>();
|
||||||
|
|
||||||
|
public void addIf(ExecutionContextIf value) {
|
||||||
|
allIfs.addLast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWhile(ExecutionContextWhile value) {
|
||||||
|
allWhiles.addLast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addForeach(ExecutionContextForeach value) {
|
||||||
|
allForeachs.addLast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextIf peekIf() {
|
||||||
|
return allIfs.peekLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextWhile peekWhile() {
|
||||||
|
return allWhiles.peekLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextForeach peekForeach() {
|
||||||
|
return allForeachs.peekLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextIf pollIf() {
|
||||||
|
return allIfs.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextWhile pollWhile() {
|
||||||
|
return allWhiles.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutionContextForeach pollForeach() {
|
||||||
|
return allForeachs.pollLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean areAllIfOk(TContext context, TMemory memory) throws EaterException {
|
||||||
|
for (ExecutionContextIf conditionalContext : allIfs) {
|
||||||
|
if (conditionalContext.conditionIsOkHere() == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
src/net/sourceforge/plantuml/tim/FunctionsSet.java
Normal file
139
src/net/sourceforge/plantuml/tim/FunctionsSet.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
|
||||||
|
public class FunctionsSet {
|
||||||
|
|
||||||
|
private final Map<TFunctionSignature, TFunction> functions = new HashMap<TFunctionSignature, TFunction>();
|
||||||
|
private final Set<TFunctionSignature> functionsFinal = new HashSet<TFunctionSignature>();
|
||||||
|
private final Trie functions3 = new TrieImpl();
|
||||||
|
private TFunctionImpl pendingFunction;
|
||||||
|
|
||||||
|
public TFunction getFunctionSmart(TFunctionSignature searched) {
|
||||||
|
final TFunction func = this.functions.get(searched);
|
||||||
|
if (func != null) {
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
for (TFunction candidate : this.functions.values()) {
|
||||||
|
if (candidate.getSignature().sameNameAs(searched) == false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (candidate.canCover(searched.getNbArg())) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return functions().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<TFunctionSignature, TFunction> functions() {
|
||||||
|
return Collections.unmodifiableMap(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLonguestMatchStartingIn(String s) {
|
||||||
|
return functions3.getLonguestMatchStartingIn(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TFunctionImpl pendingFunction() {
|
||||||
|
return pendingFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFunction(TFunction func) {
|
||||||
|
if (func.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) {
|
||||||
|
((TFunctionImpl) func).finalizeEnddefinelong();
|
||||||
|
}
|
||||||
|
this.functions.put(func.getSignature(), func);
|
||||||
|
this.functions3.add(func.getSignature().getFunctionName() + "(");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeEndfunction() {
|
||||||
|
this.addFunction(this.pendingFunction);
|
||||||
|
this.pendingFunction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeLegacyDefine(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
if (this.pendingFunction != null) {
|
||||||
|
throw EaterException.located("already0048", s);
|
||||||
|
}
|
||||||
|
final EaterLegacyDefine legacyDefine = new EaterLegacyDefine(s);
|
||||||
|
legacyDefine.analyze(context, memory);
|
||||||
|
final TFunction function = legacyDefine.getFunction();
|
||||||
|
this.functions.put(function.getSignature(), function);
|
||||||
|
this.functions3.add(function.getSignature().getFunctionName() + "(");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeLegacyDefineLong(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
if (this.pendingFunction != null) {
|
||||||
|
throw EaterException.located("already0068", s);
|
||||||
|
}
|
||||||
|
final EaterLegacyDefineLong legacyDefineLong = new EaterLegacyDefineLong(s);
|
||||||
|
legacyDefineLong.analyze(context, memory);
|
||||||
|
this.pendingFunction = legacyDefineLong.getFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeDeclareFunction(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
if (this.pendingFunction != null) {
|
||||||
|
throw EaterException.located("already0068", s);
|
||||||
|
}
|
||||||
|
final EaterDeclareFunction declareFunction = new EaterDeclareFunction(s);
|
||||||
|
declareFunction.analyze(context, memory);
|
||||||
|
final boolean finalFlag = declareFunction.getFinalFlag();
|
||||||
|
final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature();
|
||||||
|
final TFunction previous = this.functions.get(declaredSignature);
|
||||||
|
if (previous != null && (finalFlag || this.functionsFinal.contains(declaredSignature))) {
|
||||||
|
throw EaterException.located("This function is already defined", s);
|
||||||
|
}
|
||||||
|
if (finalFlag) {
|
||||||
|
this.functionsFinal.add(declaredSignature);
|
||||||
|
}
|
||||||
|
if (declareFunction.getFunction().hasBody()) {
|
||||||
|
this.addFunction(declareFunction.getFunction());
|
||||||
|
} else {
|
||||||
|
this.pendingFunction = declareFunction.getFunction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -47,6 +47,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import net.sourceforge.plantuml.DefinitionsContainer;
|
import net.sourceforge.plantuml.DefinitionsContainer;
|
||||||
import net.sourceforge.plantuml.FileSystem;
|
import net.sourceforge.plantuml.FileSystem;
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.StringLocated;
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
import net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||||
import net.sourceforge.plantuml.json.JsonObject;
|
import net.sourceforge.plantuml.json.JsonObject;
|
||||||
@ -64,6 +65,18 @@ import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy;
|
|||||||
import net.sourceforge.plantuml.preproc2.PreprocessorUtils;
|
import net.sourceforge.plantuml.preproc2.PreprocessorUtils;
|
||||||
import net.sourceforge.plantuml.tim.expression.Knowledge;
|
import net.sourceforge.plantuml.tim.expression.Knowledge;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIterator;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorAffectation;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorForeach;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorFunction;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorIf;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorImpl;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorInnerComment;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorLegacyDefine;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorLongComment;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorShortComment;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorSub;
|
||||||
|
import net.sourceforge.plantuml.tim.iterator.CodeIteratorWhile;
|
||||||
import net.sourceforge.plantuml.tim.stdlib.AlwaysFalse;
|
import net.sourceforge.plantuml.tim.stdlib.AlwaysFalse;
|
||||||
import net.sourceforge.plantuml.tim.stdlib.AlwaysTrue;
|
import net.sourceforge.plantuml.tim.stdlib.AlwaysTrue;
|
||||||
import net.sourceforge.plantuml.tim.stdlib.CallUserFunction;
|
import net.sourceforge.plantuml.tim.stdlib.CallUserFunction;
|
||||||
@ -91,15 +104,12 @@ public class TContext {
|
|||||||
|
|
||||||
private final List<StringLocated> resultList = new ArrayList<StringLocated>();
|
private final List<StringLocated> resultList = new ArrayList<StringLocated>();
|
||||||
private final List<StringLocated> debug = new ArrayList<StringLocated>();
|
private final List<StringLocated> debug = new ArrayList<StringLocated>();
|
||||||
private final Map<TFunctionSignature, TFunction> functions2 = new HashMap<TFunctionSignature, TFunction>();
|
|
||||||
private final Set<TFunctionSignature> functionsFinal = new HashSet<TFunctionSignature>();
|
public final FunctionsSet functionsSet = new FunctionsSet();
|
||||||
private final Trie functions3 = new TrieImpl();
|
|
||||||
private ImportedFiles importedFiles;
|
private ImportedFiles importedFiles;
|
||||||
private final String charset;
|
private final String charset;
|
||||||
|
|
||||||
private TFunctionImpl pendingFunction;
|
|
||||||
private Sub pendingSub;
|
|
||||||
private boolean inLongComment;
|
|
||||||
private final Map<String, Sub> subs = new HashMap<String, Sub>();
|
private final Map<String, Sub> subs = new HashMap<String, Sub>();
|
||||||
private final DefinitionsContainer definitionsContainer;
|
private final DefinitionsContainer definitionsContainer;
|
||||||
|
|
||||||
@ -107,28 +117,28 @@ public class TContext {
|
|||||||
private final Set<FileWithSuffix> filesUsedCurrent = new HashSet<FileWithSuffix>();
|
private final Set<FileWithSuffix> filesUsedCurrent = new HashSet<FileWithSuffix>();
|
||||||
|
|
||||||
private void addStandardFunctions(Defines defines) {
|
private void addStandardFunctions(Defines defines) {
|
||||||
addFunction(new Strlen());
|
functionsSet.addFunction(new Strlen());
|
||||||
addFunction(new Substr());
|
functionsSet.addFunction(new Substr());
|
||||||
addFunction(new FileExists());
|
functionsSet.addFunction(new FileExists());
|
||||||
addFunction(new Getenv());
|
functionsSet.addFunction(new Getenv());
|
||||||
addFunction(new Dirpath(defines));
|
functionsSet.addFunction(new Dirpath(defines));
|
||||||
addFunction(new Filename(defines));
|
functionsSet.addFunction(new Filename(defines));
|
||||||
addFunction(new DateFunction());
|
functionsSet.addFunction(new DateFunction());
|
||||||
addFunction(new Strpos());
|
functionsSet.addFunction(new Strpos());
|
||||||
addFunction(new InvokeVoidFunction());
|
functionsSet.addFunction(new InvokeVoidFunction());
|
||||||
addFunction(new AlwaysFalse());
|
functionsSet.addFunction(new AlwaysFalse());
|
||||||
addFunction(new AlwaysTrue());
|
functionsSet.addFunction(new AlwaysTrue());
|
||||||
addFunction(new LogicalNot());
|
functionsSet.addFunction(new LogicalNot());
|
||||||
addFunction(new FunctionExists());
|
functionsSet.addFunction(new FunctionExists());
|
||||||
addFunction(new VariableExists());
|
functionsSet.addFunction(new VariableExists());
|
||||||
addFunction(new CallUserFunction());
|
functionsSet.addFunction(new CallUserFunction());
|
||||||
addFunction(new RetrieveVoidFunction());
|
functionsSet.addFunction(new RetrieveVoidFunction());
|
||||||
addFunction(new SetVariableValue());
|
functionsSet.addFunction(new SetVariableValue());
|
||||||
addFunction(new GetVariableValue());
|
functionsSet.addFunction(new GetVariableValue());
|
||||||
addFunction(new IntVal());
|
functionsSet.addFunction(new IntVal());
|
||||||
addFunction(new GetVersion());
|
functionsSet.addFunction(new GetVersion());
|
||||||
addFunction(new Upper());
|
functionsSet.addFunction(new Upper());
|
||||||
addFunction(new Lower());
|
functionsSet.addFunction(new Lower());
|
||||||
// !exit
|
// !exit
|
||||||
// !log
|
// !log
|
||||||
// %min
|
// %min
|
||||||
@ -151,155 +161,101 @@ public class TContext {
|
|||||||
public Knowledge asKnowledge(final TMemory memory) {
|
public Knowledge asKnowledge(final TMemory memory) {
|
||||||
return new Knowledge() {
|
return new Knowledge() {
|
||||||
|
|
||||||
public TVariable getVariable(String name) {
|
public TValue getVariable(String name) {
|
||||||
|
if (name.contains(".")) {
|
||||||
|
return fromJson(memory, name);
|
||||||
|
}
|
||||||
return memory.getVariable(name);
|
return memory.getVariable(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TFunction getFunction(TFunctionSignature name) {
|
public TFunction getFunction(TFunctionSignature name) {
|
||||||
return getFunctionSmart(name);
|
return functionsSet.getFunctionSmart(name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public TFunction getFunctionSmart(TFunctionSignature searched) {
|
private TValue fromJson(TMemory memory, String name) {
|
||||||
final TFunction func = functions2.get(searched);
|
final int x = name.indexOf('.');
|
||||||
if (func != null) {
|
final TValue data = memory.getVariable(name.substring(0, x));
|
||||||
return func;
|
if (data == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
for (TFunction candidate : functions2.values()) {
|
final JsonObject json = (JsonObject) data.toJson();
|
||||||
if (candidate.getSignature().sameNameAs(searched) == false) {
|
// System.err.println("json=" + json);
|
||||||
continue;
|
// System.err.println("json=" + json.getClass());
|
||||||
}
|
// System.err.println("json2=" + name.substring(x + 1));
|
||||||
if (candidate.canCover(searched.getNbArg())) {
|
final JsonValue result = json.get(name.substring(x + 1));
|
||||||
return candidate;
|
// System.err.println("result=" + result);
|
||||||
}
|
return TValue.fromJson(result);
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeOneLine(TMemory memory, TLineType type, StringLocated s, TFunctionType fromType)
|
private CodeIterator buildCodeIterator(TMemory memory, List<StringLocated> body) {
|
||||||
throws EaterException {
|
final CodeIterator it10 = new CodeIteratorImpl(body);
|
||||||
|
final CodeIterator it20 = new CodeIteratorLongComment(it10, debug);
|
||||||
|
final CodeIterator it30 = new CodeIteratorShortComment(it20, debug);
|
||||||
|
final CodeIterator it40 = new CodeIteratorInnerComment(it30);
|
||||||
|
final CodeIterator it50 = new CodeIteratorSub(it40, subs, this, memory);
|
||||||
|
final CodeIterator it60 = new CodeIteratorFunction(it50, this, memory, functionsSet, debug);
|
||||||
|
final CodeIterator it70 = new CodeIteratorIf(it60, this, memory, debug);
|
||||||
|
final CodeIterator it80 = new CodeIteratorLegacyDefine(it70, this, memory, functionsSet, debug);
|
||||||
|
final CodeIterator it90 = new CodeIteratorWhile(it80, this, memory, debug);
|
||||||
|
final CodeIterator it100 = new CodeIteratorForeach(it90, this, memory, debug);
|
||||||
|
final CodeIterator it110 = new CodeIteratorAffectation(it100, this, memory, debug);
|
||||||
|
|
||||||
this.debug.add(s);
|
final CodeIterator it = it110;
|
||||||
assert type == TLineType.getFromLine(s.getString());
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.inLongComment == false && type == TLineType.STARTSUB) {
|
public void executeLines(TMemory memory, List<StringLocated> body, TFunctionType ftype)
|
||||||
if (pendingSub != null) {
|
throws EaterExceptionLocated {
|
||||||
throw new EaterException("Cannot nest sub");
|
final CodeIterator it = buildCodeIterator(memory, body);
|
||||||
|
|
||||||
|
StringLocated s = null;
|
||||||
|
try {
|
||||||
|
while ((s = it.peek()) != null) {
|
||||||
|
executeOneLineSafe(memory, s, ftype);
|
||||||
|
it.next();
|
||||||
}
|
}
|
||||||
final EaterStartsub eater = new EaterStartsub(s.getTrimmed().getString());
|
} catch (EaterException e) {
|
||||||
eater.execute(this, memory);
|
throw e.withLocation(s);
|
||||||
this.pendingSub = new Sub(eater.getSubname());
|
|
||||||
this.subs.put(eater.getSubname(), this.pendingSub);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.inLongComment == false && type == TLineType.ENDSUB) {
|
|
||||||
if (pendingSub == null) {
|
|
||||||
throw new EaterException("No corresponding !startsub");
|
|
||||||
}
|
|
||||||
final Sub newly = this.pendingSub;
|
|
||||||
this.pendingSub = null;
|
|
||||||
this.runSub(memory, newly);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if (this.inLongComment == false && type == TLineType.INCLUDESUB) {
|
|
||||||
// this.executeIncludesub(memory, s);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (pendingSub != null) {
|
|
||||||
pendingSub.add(s);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getPendingFunction() != null) {
|
}
|
||||||
if (this.inLongComment == false && type == TLineType.END_FUNCTION) {
|
|
||||||
this.executeEndfunction();
|
private void executeLinesInternal(TMemory memory, List<StringLocated> body, TFunctionType ftype)
|
||||||
} else {
|
throws EaterExceptionLocated, EaterException {
|
||||||
this.getPendingFunction().addBody(s);
|
final CodeIterator it = buildCodeIterator(memory, body);
|
||||||
}
|
|
||||||
return;
|
StringLocated s = null;
|
||||||
|
while ((s = it.peek()) != null) {
|
||||||
|
executeOneLineSafe(memory, s, ftype);
|
||||||
|
it.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.inLongComment && s.getTrimmed().getString().endsWith("'/")) {
|
}
|
||||||
this.inLongComment = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == TLineType.COMMENT_LONG_START) {
|
private void executeOneLineSafe(TMemory memory, StringLocated s, TFunctionType ftype)
|
||||||
this.inLongComment = true;
|
throws EaterException, EaterExceptionLocated {
|
||||||
return;
|
try {
|
||||||
|
this.debug.add(s);
|
||||||
|
executeOneLineNotSafe(memory, s, ftype);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof EaterException)
|
||||||
|
throw (EaterException) e;
|
||||||
|
if (e instanceof EaterExceptionLocated)
|
||||||
|
throw (EaterExceptionLocated) e;
|
||||||
|
e.printStackTrace();
|
||||||
|
throw EaterException.located("Fatal parsing error", s);
|
||||||
}
|
}
|
||||||
if (this.inLongComment) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (type == TLineType.COMMENT_SIMPLE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
s = s.removeInnerComment();
|
|
||||||
|
|
||||||
if (type == TLineType.IF) {
|
private void executeOneLineNotSafe(TMemory memory, StringLocated s, TFunctionType ftype)
|
||||||
this.executeIf(memory, s.getTrimmed().getString());
|
throws EaterException, EaterExceptionLocated {
|
||||||
return;
|
final TLineType type = s.getType();
|
||||||
} else if (type == TLineType.IFDEF) {
|
|
||||||
this.executeIfdef(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.IFNDEF) {
|
|
||||||
this.executeIfndef(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.ELSE) {
|
|
||||||
this.executeElse(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.ELSEIF) {
|
|
||||||
this.executeElseIf(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.ENDIF) {
|
|
||||||
this.executeEndif(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ConditionalContext conditionalContext = memory.peekConditionalContext();
|
if (type == TLineType.INCLUDESUB) {
|
||||||
if (conditionalContext != null && memory.areAllIfOk() == false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.inLongComment == false && type == TLineType.INCLUDESUB) {
|
|
||||||
this.executeIncludesub(memory, s);
|
this.executeIncludesub(memory, s);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (type == TLineType.DUMP_MEMORY) {
|
|
||||||
this.executeDumpMemory(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.ASSERT) {
|
|
||||||
this.executeAssert(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.UNDEF) {
|
|
||||||
this.executeUndef(memory, s);
|
|
||||||
return;
|
|
||||||
} else if (fromType != TFunctionType.RETURN && type == TLineType.PLAIN) {
|
|
||||||
this.addPlain(memory, s);
|
|
||||||
return;
|
|
||||||
} else if (fromType == TFunctionType.RETURN && type == TLineType.RETURN) {
|
|
||||||
// Actually, ignore because we are in a if
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.LEGACY_DEFINE) {
|
|
||||||
this.executeLegacyDefine(memory, s);
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.LEGACY_DEFINELONG) {
|
|
||||||
this.executeLegacyDefineLong(memory, s);
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.AFFECTATION_DEFINE) {
|
|
||||||
this.executeAffectationDefine(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.AFFECTATION) {
|
|
||||||
this.executeAffectation(memory, s.getTrimmed().getString());
|
|
||||||
return;
|
|
||||||
} else if (fromType == null && type == TLineType.DECLARE_FUNCTION) {
|
|
||||||
this.executeDeclareFunction(memory, s);
|
|
||||||
return;
|
|
||||||
} else if (fromType == null && type == TLineType.END_FUNCTION) {
|
|
||||||
CommandExecutionResult.error("error endfunc");
|
|
||||||
return;
|
|
||||||
} else if (type == TLineType.INCLUDE) {
|
} else if (type == TLineType.INCLUDE) {
|
||||||
this.executeInclude(memory, s);
|
this.executeInclude(memory, s);
|
||||||
return;
|
return;
|
||||||
@ -309,18 +265,39 @@ public class TContext {
|
|||||||
} else if (type == TLineType.IMPORT) {
|
} else if (type == TLineType.IMPORT) {
|
||||||
this.executeImport(memory, s);
|
this.executeImport(memory, s);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == TLineType.DUMP_MEMORY) {
|
||||||
|
this.executeDumpMemory(memory, s.getTrimmed());
|
||||||
|
return;
|
||||||
|
} else if (type == TLineType.ASSERT) {
|
||||||
|
this.executeAssert(memory, s.getTrimmed());
|
||||||
|
return;
|
||||||
|
} else if (type == TLineType.UNDEF) {
|
||||||
|
this.executeUndef(memory, s);
|
||||||
|
return;
|
||||||
|
} else if (ftype != TFunctionType.RETURN && type == TLineType.PLAIN) {
|
||||||
|
this.addPlain(memory, s);
|
||||||
|
return;
|
||||||
|
} else if (ftype == TFunctionType.RETURN && type == TLineType.RETURN) {
|
||||||
|
// Actually, ignore because we are in a if
|
||||||
|
return;
|
||||||
|
} else if (type == TLineType.AFFECTATION_DEFINE) {
|
||||||
|
this.executeAffectationDefine(memory, s);
|
||||||
|
return;
|
||||||
|
} else if (ftype == null && type == TLineType.END_FUNCTION) {
|
||||||
|
CommandExecutionResult.error("error endfunc");
|
||||||
|
return;
|
||||||
} else if (type == TLineType.LOG) {
|
} else if (type == TLineType.LOG) {
|
||||||
this.executeLog(memory, s);
|
this.executeLog(memory, s);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Thread.dumpStack();
|
throw EaterException.located("Parsing Error", s);
|
||||||
throw new EaterException("Parsing Error");
|
|
||||||
// throw new UnsupportedOperationException("type=" + type + " fromType=" + fromType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addPlain(TMemory memory, StringLocated s) throws EaterException {
|
private void addPlain(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
StringLocated tmp = applyFunctionsAndVariables(memory, s);
|
StringLocated tmp = applyFunctionsAndVariablesInternal(memory, s);
|
||||||
if (tmp != null) {
|
if (tmp != null) {
|
||||||
if (pendingAdd != null) {
|
if (pendingAdd != null) {
|
||||||
tmp = new StringLocated(pendingAdd + tmp.getString(), tmp.getLocation());
|
tmp = new StringLocated(pendingAdd + tmp.getString(), tmp.getLocation());
|
||||||
@ -330,136 +307,32 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeAffectationDefine(TMemory memory, String s) throws EaterException {
|
private void executeAffectationDefine(TMemory memory, StringLocated s)
|
||||||
new EaterAffectationDefine(s).execute(this, memory);
|
throws EaterException, EaterExceptionLocated {
|
||||||
|
new EaterAffectationDefine(s).analyze(this, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeAffectation(TMemory memory, String s) throws EaterException {
|
private void executeDumpMemory(TMemory memory, StringLocated s) throws EaterException {
|
||||||
new EaterAffectation(s).execute(this, memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeIf(TMemory memory, String s) throws EaterException {
|
|
||||||
final EaterIf condition = new EaterIf(s);
|
|
||||||
condition.execute(this, memory);
|
|
||||||
final boolean isTrue = condition.isTrue();
|
|
||||||
memory.addConditionalContext(ConditionalContext.fromValue(isTrue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeElseIf(TMemory memory, String s) throws EaterException {
|
|
||||||
final ConditionalContext poll = memory.peekConditionalContext();
|
|
||||||
if (poll == null) {
|
|
||||||
throw new EaterException("No if related to this else");
|
|
||||||
}
|
|
||||||
|
|
||||||
poll.enteringElseIf();
|
|
||||||
if (poll.hasBeenBurn() == false) {
|
|
||||||
final EaterElseIf condition = new EaterElseIf(s);
|
|
||||||
condition.execute(this, memory);
|
|
||||||
final boolean isTrue = condition.isTrue();
|
|
||||||
if (isTrue) {
|
|
||||||
poll.nowInSomeElseIf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeDumpMemory(TMemory memory, String s) throws EaterException {
|
|
||||||
final EaterDumpMemory condition = new EaterDumpMemory(s);
|
final EaterDumpMemory condition = new EaterDumpMemory(s);
|
||||||
condition.execute(this, memory);
|
condition.analyze(this, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeAssert(TMemory memory, String s) throws EaterException {
|
private void executeAssert(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
final EaterAssert condition = new EaterAssert(s);
|
final EaterAssert condition = new EaterAssert(s);
|
||||||
condition.execute(this, memory);
|
condition.analyze(this, memory);
|
||||||
}
|
|
||||||
|
|
||||||
private void executeIfdef(TMemory memory, String s) throws EaterException {
|
|
||||||
final EaterIfdef condition = new EaterIfdef(s);
|
|
||||||
condition.execute(this, memory);
|
|
||||||
final boolean isTrue = condition.isTrue(this, memory);
|
|
||||||
memory.addConditionalContext(ConditionalContext.fromValue(isTrue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeIfndef(TMemory memory, String s) throws EaterException {
|
|
||||||
final EaterIfndef condition = new EaterIfndef(s);
|
|
||||||
condition.execute(this, memory);
|
|
||||||
final boolean isTrue = condition.isTrue(this, memory);
|
|
||||||
memory.addConditionalContext(ConditionalContext.fromValue(isTrue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeElse(TMemory memory, String s) throws EaterException {
|
|
||||||
final ConditionalContext poll = memory.peekConditionalContext();
|
|
||||||
if (poll == null) {
|
|
||||||
throw new EaterException("No if related to this else");
|
|
||||||
}
|
|
||||||
poll.nowInElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeEndif(TMemory memory, String s) throws EaterException {
|
|
||||||
final ConditionalContext poll = memory.pollConditionalContext();
|
|
||||||
if (poll == null) {
|
|
||||||
throw new EaterException("No if related to this endif");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeDeclareFunction(TMemory memory, StringLocated s) throws EaterException {
|
|
||||||
if (this.pendingFunction != null) {
|
|
||||||
throw new EaterException("already0068");
|
|
||||||
}
|
|
||||||
final EaterDeclareFunction declareFunction = new EaterDeclareFunction(s);
|
|
||||||
declareFunction.execute(this, memory);
|
|
||||||
final boolean finalFlag = declareFunction.getFinalFlag();
|
|
||||||
final TFunctionSignature declaredSignature = declareFunction.getFunction().getSignature();
|
|
||||||
final TFunction previous = functions2.get(declaredSignature);
|
|
||||||
if (previous != null && (finalFlag || functionsFinal.contains(declaredSignature))) {
|
|
||||||
throw new EaterException("This function is already defined");
|
|
||||||
}
|
|
||||||
if (finalFlag) {
|
|
||||||
functionsFinal.add(declaredSignature);
|
|
||||||
}
|
|
||||||
if (declareFunction.getFunction().hasBody()) {
|
|
||||||
addFunction(declareFunction.getFunction());
|
|
||||||
} else {
|
|
||||||
this.pendingFunction = declareFunction.getFunction();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeUndef(TMemory memory, StringLocated s) throws EaterException {
|
private void executeUndef(TMemory memory, StringLocated s) throws EaterException {
|
||||||
final EaterUndef undef = new EaterUndef(s);
|
final EaterUndef undef = new EaterUndef(s);
|
||||||
undef.execute(this, memory);
|
undef.analyze(this, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeLegacyDefine(TMemory memory, StringLocated s) throws EaterException {
|
private StringLocated applyFunctionsAndVariablesInternal(TMemory memory, StringLocated located)
|
||||||
if (this.pendingFunction != null) {
|
throws EaterException, EaterExceptionLocated {
|
||||||
throw new EaterException("already0048");
|
if (memory.isEmpty() && functionsSet.size() == 0) {
|
||||||
}
|
|
||||||
final EaterLegacyDefine legacyDefine = new EaterLegacyDefine(s);
|
|
||||||
legacyDefine.execute(this, memory);
|
|
||||||
final TFunction function = legacyDefine.getFunction();
|
|
||||||
// if (functions2.containsKey(function.getSignature())) {
|
|
||||||
// throw new EaterException("already0047");
|
|
||||||
// }
|
|
||||||
this.functions2.put(function.getSignature(), function);
|
|
||||||
this.functions3.add(function.getSignature().getFunctionName() + "(");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeLegacyDefineLong(TMemory memory, StringLocated s) throws EaterException {
|
|
||||||
if (this.pendingFunction != null) {
|
|
||||||
throw new EaterException("already0068");
|
|
||||||
}
|
|
||||||
final EaterLegacyDefineLong legacyDefineLong = new EaterLegacyDefineLong(s);
|
|
||||||
legacyDefineLong.execute(this, memory);
|
|
||||||
// if (functions2.containsKey(legacyDefineLong.getFunction().getSignature())) {
|
|
||||||
// throw new EaterException("already0066");
|
|
||||||
// }
|
|
||||||
this.pendingFunction = legacyDefineLong.getFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
private StringLocated applyFunctionsAndVariables(TMemory memory, StringLocated located) throws EaterException {
|
|
||||||
if (memory.isEmpty() && functions2.size() == 0) {
|
|
||||||
return located;
|
return located;
|
||||||
}
|
}
|
||||||
final String s = located.getString();
|
final String result = applyFunctionsAndVariables(memory, located.getLocation(), located.getString());
|
||||||
final String result = applyFunctionsAndVariables(memory, s);
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -468,127 +341,89 @@ public class TContext {
|
|||||||
|
|
||||||
private String pendingAdd = null;
|
private String pendingAdd = null;
|
||||||
|
|
||||||
public String applyFunctionsAndVariables(TMemory memory, String s) throws EaterException {
|
public String applyFunctionsAndVariables(TMemory memory, LineLocation location, String str)
|
||||||
|
throws EaterException, EaterExceptionLocated {
|
||||||
// https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
|
// https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
|
||||||
// https://stackoverflow.com/questions/1326682/java-replacing-multiple-different-substring-in-a-string-at-once-or-in-the-most
|
// https://stackoverflow.com/questions/1326682/java-replacing-multiple-different-substring-in-a-string-at-once-or-in-the-most
|
||||||
// https://en.wikipedia.org/wiki/String-searching_algorithm
|
// https://en.wikipedia.org/wiki/String-searching_algorithm
|
||||||
// https://www.quora.com/What-is-the-most-efficient-algorithm-to-replace-all-occurrences-of-a-pattern-P-in-a-string-with-a-pattern-P
|
// https://www.quora.com/What-is-the-most-efficient-algorithm-to-replace-all-occurrences-of-a-pattern-P-in-a-string-with-a-pattern-P
|
||||||
// https://en.wikipedia.org/wiki/Trie
|
// https://en.wikipedia.org/wiki/Trie
|
||||||
if (memory.isEmpty() && functions2.size() == 0) {
|
if (memory.isEmpty() && functionsSet.size() == 0) {
|
||||||
return s;
|
return str;
|
||||||
}
|
}
|
||||||
final StringBuilder result = new StringBuilder();
|
final StringBuilder result = new StringBuilder();
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < str.length(); i++) {
|
||||||
final char c = s.charAt(i);
|
final char c = str.charAt(i);
|
||||||
final String presentFunction = getFunctionNameAt(s, i);
|
final String presentFunction = getFunctionNameAt(str, i);
|
||||||
if (presentFunction != null) {
|
if (presentFunction != null) {
|
||||||
final String sub = s.substring(i);
|
final String sub = str.substring(i);
|
||||||
final EaterFunctionCall call = new EaterFunctionCall(sub, isLegacyDefine(presentFunction),
|
final EaterFunctionCall call = new EaterFunctionCall(new StringLocated(sub, location),
|
||||||
isUnquoted(presentFunction));
|
isLegacyDefine(presentFunction), isUnquoted(presentFunction));
|
||||||
call.execute(this, memory);
|
call.analyze(this, memory);
|
||||||
final TFunction function = getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues()
|
final TFunction function = functionsSet
|
||||||
.size()));
|
.getFunctionSmart(new TFunctionSignature(presentFunction, call.getValues().size()));
|
||||||
if (function == null) {
|
if (function == null) {
|
||||||
throw new EaterException("Function not found " + presentFunction);
|
throw EaterException.located("Function not found " + presentFunction,
|
||||||
|
new StringLocated(str, location));
|
||||||
}
|
}
|
||||||
if (function.getFunctionType() == TFunctionType.VOID) {
|
if (function.getFunctionType() == TFunctionType.VOID) {
|
||||||
this.pendingAdd = result.toString();
|
this.pendingAdd = result.toString();
|
||||||
executeVoid3(memory, sub, function);
|
executeVoid3(location, memory, sub, function);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (function.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) {
|
if (function.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) {
|
||||||
this.pendingAdd = s.substring(0, i);
|
this.pendingAdd = str.substring(0, i);
|
||||||
executeVoid3(memory, sub, function);
|
executeVoid3(location, memory, sub, function);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
assert function.getFunctionType() == TFunctionType.RETURN
|
assert function.getFunctionType() == TFunctionType.RETURN
|
||||||
|| function.getFunctionType() == TFunctionType.LEGACY_DEFINE;
|
|| function.getFunctionType() == TFunctionType.LEGACY_DEFINE;
|
||||||
final TValue functionReturn = function.executeReturn(this, memory, call.getValues());
|
final TValue functionReturn = function.executeReturn(this, memory, location, call.getValues());
|
||||||
result.append(functionReturn.toString());
|
result.append(functionReturn.toString());
|
||||||
i += call.getCurrentPosition() - 1;
|
i += call.getCurrentPosition() - 1;
|
||||||
continue;
|
} else if (new VariableManager(this, memory, location).getVarnameAt(str, i) != null) {
|
||||||
|
i = new VariableManager(this, memory, location).replaceVariables(str, i, result);
|
||||||
|
} else {
|
||||||
|
result.append(c);
|
||||||
}
|
}
|
||||||
final String presentVariable = getVarnameAt(memory, s, i);
|
|
||||||
if (presentVariable != null) {
|
|
||||||
if (result.toString().endsWith("##")) {
|
|
||||||
result.setLength(result.length() - 2);
|
|
||||||
}
|
|
||||||
final TValue value = memory.getVariable(presentVariable).getValue();
|
|
||||||
i += presentVariable.length() - 1;
|
|
||||||
if (value.isJson()) {
|
|
||||||
JsonValue jsonValue = (JsonObject) value.toJson();
|
|
||||||
// System.err.println("jsonValue1=" + jsonValue);
|
|
||||||
i++;
|
|
||||||
while (true) {
|
|
||||||
final char n = s.charAt(i);
|
|
||||||
// System.err.println("n=" + n);
|
|
||||||
if (n != '.') {
|
|
||||||
if (jsonValue.isString()) {
|
|
||||||
result.append(jsonValue.asString());
|
|
||||||
} else {
|
|
||||||
result.append(jsonValue.toString());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
final StringBuilder fieldName = new StringBuilder();
|
|
||||||
while (true) {
|
|
||||||
if (Character.isJavaIdentifierPart(s.charAt(i)) == false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fieldName.append(s.charAt(i));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
// System.err.println("fieldName=" + fieldName);
|
|
||||||
jsonValue = ((JsonObject) jsonValue).get(fieldName.toString());
|
|
||||||
// System.err.println("jsonValue2=" + jsonValue);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.append(value.toString());
|
|
||||||
}
|
|
||||||
if (i + 2 < s.length() && s.charAt(i + 1) == '#' && s.charAt(i + 2) == '#') {
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
result.append(c);
|
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeVoid3(TMemory memory, String s, TFunction function) throws EaterException {
|
private void executeVoid3(LineLocation location, TMemory memory, String s, TFunction function)
|
||||||
function.executeVoid(this, memory, s);
|
throws EaterException, EaterExceptionLocated {
|
||||||
|
function.executeVoid(this, memory, location, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeImport(TMemory memory, StringLocated s) throws EaterException {
|
private void executeImport(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
final EaterImport _import = new EaterImport(s.getTrimmed().getString());
|
final EaterImport _import = new EaterImport(s.getTrimmed());
|
||||||
_import.execute(this, memory);
|
_import.analyze(this, memory);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final File file = FileSystem.getInstance().getFile(
|
final File file = FileSystem.getInstance()
|
||||||
applyFunctionsAndVariables(memory, _import.getLocation()));
|
.getFile(applyFunctionsAndVariables(memory, s.getLocation(), _import.getLocation()));
|
||||||
if (file.exists() && file.isDirectory() == false) {
|
if (file.exists() && file.isDirectory() == false) {
|
||||||
importedFiles.add(file);
|
importedFiles.add(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new EaterException("Cannot import " + e.getMessage());
|
throw EaterException.located("Cannot import " + e.getMessage(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new EaterException("Cannot import");
|
throw EaterException.located("Cannot import", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeLog(TMemory memory, StringLocated s) throws EaterException {
|
private void executeLog(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
final EaterLog log = new EaterLog(s.getTrimmed().getString());
|
final EaterLog log = new EaterLog(s.getTrimmed());
|
||||||
log.execute(this, memory);
|
log.analyze(this, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeIncludesub(TMemory memory, StringLocated s) throws EaterException {
|
private void executeIncludesub(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
ImportedFiles saveImportedFiles = null;
|
ImportedFiles saveImportedFiles = null;
|
||||||
try {
|
try {
|
||||||
final EaterIncludesub include = new EaterIncludesub(s.getTrimmed().getString());
|
final EaterIncludesub include = new EaterIncludesub(s.getTrimmed());
|
||||||
include.execute(this, memory);
|
include.analyze(this, memory);
|
||||||
final String location = include.getLocation();
|
final String location = include.getLocation();
|
||||||
final int idx = location.indexOf('!');
|
final int idx = location.indexOf('!');
|
||||||
Sub sub = null;
|
Sub sub = null;
|
||||||
@ -603,21 +438,20 @@ public class TContext {
|
|||||||
final Reader reader = f2.getReader(charset);
|
final Reader reader = f2.getReader(charset);
|
||||||
ReadLine readerline = ReadLineReader.create(reader, location, s.getLocation());
|
ReadLine readerline = ReadLineReader.create(reader, location, s.getLocation());
|
||||||
readerline = new UncommentReadLine(readerline);
|
readerline = new UncommentReadLine(readerline);
|
||||||
// readerline = new ReadLineQuoteComment(true).applyFilter(readerline);
|
|
||||||
sub = Sub.fromFile(readerline, blocname, this, memory);
|
sub = Sub.fromFile(readerline, blocname, this, memory);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new EaterException("cannot include " + e);
|
throw EaterException.located("cannot include " + e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sub == null) {
|
if (sub == null) {
|
||||||
sub = subs.get(location);
|
sub = subs.get(location);
|
||||||
}
|
}
|
||||||
if (sub == null) {
|
if (sub == null) {
|
||||||
throw new EaterException("cannot include " + location);
|
throw EaterException.located("cannot include " + location, s);
|
||||||
}
|
}
|
||||||
runSub(memory, sub);
|
executeLinesInternal(memory, sub.lines(), null);
|
||||||
} finally {
|
} finally {
|
||||||
if (saveImportedFiles != null) {
|
if (saveImportedFiles != null) {
|
||||||
this.importedFiles = saveImportedFiles;
|
this.importedFiles = saveImportedFiles;
|
||||||
@ -625,37 +459,32 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runSub(TMemory memory, final Sub sub) throws EaterException {
|
private void executeIncludeDef(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
for (StringLocated sl : sub.lines()) {
|
final EaterIncludeDef include = new EaterIncludeDef(s.getTrimmed());
|
||||||
executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null);
|
include.analyze(this, memory);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void executeIncludeDef(TMemory memory, StringLocated s) throws EaterException {
|
|
||||||
final EaterIncludeDef include = new EaterIncludeDef(s.getTrimmed().getString());
|
|
||||||
include.execute(this, memory);
|
|
||||||
final String definitionName = include.getLocation();
|
final String definitionName = include.getLocation();
|
||||||
final List<String> definition = definitionsContainer.getDefinition(definitionName);
|
final List<String> definition = definitionsContainer.getDefinition(definitionName);
|
||||||
ReadLine reader2 = new ReadLineList(definition, s.getLocation());
|
ReadLine reader2 = new ReadLineList(definition, s.getLocation());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// reader2 = new ReadLineQuoteComment(true).applyFilter(reader2);
|
final List<StringLocated> body = new ArrayList<StringLocated>();
|
||||||
do {
|
do {
|
||||||
final StringLocated sl = reader2.readLine();
|
final StringLocated sl = reader2.readLine();
|
||||||
if (sl == null) {
|
if (sl == null) {
|
||||||
|
executeLinesInternal(memory, body, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null);
|
body.add(sl);
|
||||||
} while (true);
|
} while (true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new EaterException("" + e);
|
throw EaterException.located("" + e, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeInclude(TMemory memory, StringLocated s) throws EaterException {
|
private void executeInclude(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
final EaterInclude include = new EaterInclude(s.getTrimmed().getString());
|
final EaterInclude include = new EaterInclude(s.getTrimmed());
|
||||||
include.execute(this, memory);
|
include.analyze(this, memory);
|
||||||
String location = include.getLocation();
|
String location = include.getLocation();
|
||||||
final PreprocessorIncludeStrategy strategy = include.getPreprocessorIncludeStrategy();
|
final PreprocessorIncludeStrategy strategy = include.getPreprocessorIncludeStrategy();
|
||||||
final int idx = location.lastIndexOf('!');
|
final int idx = location.lastIndexOf('!');
|
||||||
@ -682,7 +511,7 @@ public class TContext {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strategy == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) {
|
if (strategy == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) {
|
||||||
throw new EaterException("This file has already been included");
|
throw EaterException.located("This file has already been included", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) {
|
if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) {
|
||||||
@ -690,7 +519,7 @@ public class TContext {
|
|||||||
} else {
|
} else {
|
||||||
final Reader reader = f2.getReader(charset);
|
final Reader reader = f2.getReader(charset);
|
||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
throw new EaterException("Cannot include file");
|
throw EaterException.located("Cannot include file", s);
|
||||||
}
|
}
|
||||||
reader2 = ReadLineReader.create(reader, location, s.getLocation());
|
reader2 = ReadLineReader.create(reader, location, s.getLocation());
|
||||||
}
|
}
|
||||||
@ -698,18 +527,18 @@ public class TContext {
|
|||||||
this.importedFiles = this.importedFiles.withCurrentDir(f2.getParentFile());
|
this.importedFiles = this.importedFiles.withCurrentDir(f2.getParentFile());
|
||||||
assert reader2 != null;
|
assert reader2 != null;
|
||||||
filesUsedCurrent.add(f2);
|
filesUsedCurrent.add(f2);
|
||||||
// filesUsedGlobal.add(f2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (reader2 != null) {
|
if (reader2 != null) {
|
||||||
// reader2 = new ReadLineQuoteComment(true).applyFilter(reader2);
|
|
||||||
try {
|
try {
|
||||||
|
final List<StringLocated> body = new ArrayList<StringLocated>();
|
||||||
do {
|
do {
|
||||||
final StringLocated sl = reader2.readLine();
|
final StringLocated sl = reader2.readLine();
|
||||||
if (sl == null) {
|
if (sl == null) {
|
||||||
|
executeLines(memory, body, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null);
|
body.add(sl);
|
||||||
} while (true);
|
} while (true);
|
||||||
} finally {
|
} finally {
|
||||||
if (saveImportedFiles != null) {
|
if (saveImportedFiles != null) {
|
||||||
@ -719,14 +548,14 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new EaterException("cannot include " + e);
|
throw EaterException.located("cannot include " + e, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new EaterException("cannot include " + location);
|
throw EaterException.located("cannot include " + location, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLegacyDefine(String functionName) {
|
public boolean isLegacyDefine(String functionName) {
|
||||||
for (Map.Entry<TFunctionSignature, TFunction> ent : functions2.entrySet()) {
|
for (Map.Entry<TFunctionSignature, TFunction> ent : functionsSet.functions().entrySet()) {
|
||||||
if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().getFunctionType().isLegacy()) {
|
if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().getFunctionType().isLegacy()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -735,7 +564,7 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnquoted(String functionName) {
|
public boolean isUnquoted(String functionName) {
|
||||||
for (Map.Entry<TFunctionSignature, TFunction> ent : functions2.entrySet()) {
|
for (Map.Entry<TFunctionSignature, TFunction> ent : functionsSet.functions().entrySet()) {
|
||||||
if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().isUnquoted()) {
|
if (ent.getKey().getFunctionName().equals(functionName) && ent.getValue().isUnquoted()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -744,7 +573,7 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean doesFunctionExist(String functionName) {
|
public boolean doesFunctionExist(String functionName) {
|
||||||
for (Map.Entry<TFunctionSignature, TFunction> ent : functions2.entrySet()) {
|
for (Map.Entry<TFunctionSignature, TFunction> ent : functionsSet.functions().entrySet()) {
|
||||||
if (ent.getKey().getFunctionName().equals(functionName)) {
|
if (ent.getKey().getFunctionName().equals(functionName)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -752,30 +581,12 @@ public class TContext {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getVarnameAt(TMemory memory, String s, int pos) {
|
|
||||||
if (pos > 0 && TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos - 1)) && justAfterBackslashN(s, pos) == false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final String varname = memory.variablesNames3().getLonguestMatchStartingIn(s.substring(pos));
|
|
||||||
if (varname.length() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (pos + varname.length() == s.length()
|
|
||||||
|| TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos + varname.length())) == false) {
|
|
||||||
return varname;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean justAfterBackslashN(String s, int pos) {
|
|
||||||
return pos > 1 && s.charAt(pos - 2) == '\\' && s.charAt(pos - 1) == 'n';
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFunctionNameAt(String s, int pos) {
|
private String getFunctionNameAt(String s, int pos) {
|
||||||
if (pos > 0 && TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos - 1)) && justAfterBackslashN(s, pos) == false) {
|
if (pos > 0 && TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos - 1))
|
||||||
|
&& VariableManager.justAfterBackslashN(s, pos) == false) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final String fname = functions3.getLonguestMatchStartingIn(s.substring(pos));
|
final String fname = functionsSet.getLonguestMatchStartingIn(s.substring(pos));
|
||||||
if (fname.length() == 0) {
|
if (fname.length() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -790,23 +601,6 @@ public class TContext {
|
|||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final TFunctionImpl getPendingFunction() {
|
|
||||||
return pendingFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addFunction(TFunction func) {
|
|
||||||
if (func.getFunctionType() == TFunctionType.LEGACY_DEFINELONG) {
|
|
||||||
((TFunctionImpl) func).finalizeEnddefinelong();
|
|
||||||
}
|
|
||||||
this.functions2.put(func.getSignature(), func);
|
|
||||||
this.functions3.add(func.getSignature().getFunctionName() + "(");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void executeEndfunction() {
|
|
||||||
addFunction(pendingFunction);
|
|
||||||
pendingFunction = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String extractFromResultList(int n1) {
|
public String extractFromResultList(int n1) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
while (resultList.size() > n1) {
|
while (resultList.size() > n1) {
|
||||||
@ -828,4 +622,8 @@ public class TContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TFunction getFunctionSmart(TFunctionSignature signature) {
|
||||||
|
return functionsSet.getFunctionSmart(signature);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public interface TFunction {
|
public interface TFunction {
|
||||||
@ -46,11 +47,11 @@ public interface TFunction {
|
|||||||
|
|
||||||
public TFunctionType getFunctionType();
|
public TFunctionType getFunctionType();
|
||||||
|
|
||||||
public void executeVoid(TContext context, TMemory memory, String s) throws EaterException;
|
public void executeVoid(TContext context, TMemory memory, LineLocation location, String s) throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException;
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
public void executeVoidInternal(TContext context, TMemory memory, List<TValue> args) throws EaterException;
|
public void executeVoidInternal(TContext context, TMemory memory, List<TValue> args) throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
public boolean isUnquoted();
|
public boolean isUnquoted();
|
||||||
|
|
||||||
|
@ -35,10 +35,12 @@
|
|||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.StringLocated;
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
@ -76,72 +78,75 @@ public class TFunctionImpl implements TFunction {
|
|||||||
|
|
||||||
public void addBody(StringLocated s) {
|
public void addBody(StringLocated s) {
|
||||||
body.add(s);
|
body.add(s);
|
||||||
if (TLineType.getFromLine(s.getString()) == TLineType.RETURN) {
|
if (s.getType() == TLineType.RETURN) {
|
||||||
this.functionType = TFunctionType.RETURN;
|
this.functionType = TFunctionType.RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeVoid(TContext context, TMemory memory, String s) throws EaterException {
|
public void executeVoid(TContext context, TMemory memory, LineLocation location, String s)
|
||||||
final EaterFunctionCall call = new EaterFunctionCall(s, context.isLegacyDefine(signature.getFunctionName()),
|
throws EaterException, EaterExceptionLocated {
|
||||||
unquoted);
|
final EaterFunctionCall call = new EaterFunctionCall(new StringLocated(s, location),
|
||||||
call.execute(context, memory);
|
context.isLegacyDefine(signature.getFunctionName()), unquoted);
|
||||||
|
call.analyze(context, memory);
|
||||||
final String endOfLine = call.getEndOfLine();
|
final String endOfLine = call.getEndOfLine();
|
||||||
final List<TValue> args = call.getValues();
|
final List<TValue> args = call.getValues();
|
||||||
executeVoidInternal(context, memory, args);
|
executeVoidInternal(context, memory, args);
|
||||||
context.appendEndOfLine(endOfLine);
|
context.appendEndOfLine(endOfLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeVoidInternal(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public void executeVoidInternal(TContext context, TMemory memory, List<TValue> args)
|
||||||
|
throws EaterException, EaterExceptionLocated {
|
||||||
if (functionType != TFunctionType.VOID && functionType != TFunctionType.LEGACY_DEFINELONG) {
|
if (functionType != TFunctionType.VOID && functionType != TFunctionType.LEGACY_DEFINELONG) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
final TMemory copy = getNewMemory(memory, args);
|
final TMemory copy = getNewMemory(memory, args);
|
||||||
for (StringLocated sl : body) {
|
context.executeLines(copy, body, TFunctionType.VOID);
|
||||||
context.executeOneLine(copy, TLineType.getFromLine(sl.getString()), sl, TFunctionType.VOID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TMemory getNewMemory(TMemory memory, List<TValue> values) {
|
private TMemory getNewMemory(TMemory memory, List<TValue> values) {
|
||||||
final Map<String, TVariable> foo = new HashMap<String, TVariable>();
|
final Map<String, TValue> foo = new HashMap<String, TValue>();
|
||||||
for (int i = 0; i < args.size(); i++) {
|
for (int i = 0; i < args.size(); i++) {
|
||||||
final TValue tmp = i < values.size() ? values.get(i) : args.get(i).getOptionalDefaultValue();
|
final TValue tmp = i < values.size() ? values.get(i) : args.get(i).getOptionalDefaultValue();
|
||||||
foo.put(args.get(i).getName(), new TVariable(tmp));
|
foo.put(args.get(i).getName(), tmp);
|
||||||
}
|
}
|
||||||
final TMemory copy = memory.forkFromGlobal(foo);
|
final TMemory copy = memory.forkFromGlobal(foo);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args)
|
||||||
|
throws EaterException, EaterExceptionLocated {
|
||||||
if (functionType == TFunctionType.LEGACY_DEFINE) {
|
if (functionType == TFunctionType.LEGACY_DEFINE) {
|
||||||
return executeReturnLegacyDefine(context, memory, args);
|
return executeReturnLegacyDefine(location, context, memory, args);
|
||||||
}
|
}
|
||||||
if (functionType != TFunctionType.RETURN) {
|
if (functionType != TFunctionType.RETURN) {
|
||||||
throw new EaterException("Illegal call here");
|
throw EaterException.unlocated("Illegal call here");
|
||||||
}
|
}
|
||||||
final TMemory copy = getNewMemory(memory, args);
|
final TMemory copy = getNewMemory(memory, args);
|
||||||
|
|
||||||
for (StringLocated sl : body) {
|
for (StringLocated sl : body) {
|
||||||
final TLineType lineType = TLineType.getFromLine(sl.getString());
|
final TLineType lineType = sl.getType();
|
||||||
final ConditionalContext conditionalContext = copy.peekConditionalContext();
|
final ExecutionContextIf conditionalContext = copy.peekIf();
|
||||||
if ((conditionalContext == null || conditionalContext.conditionIsOkHere()) && lineType == TLineType.RETURN) {
|
if ((conditionalContext == null || ((ExecutionContextIf) conditionalContext).conditionIsOkHere())
|
||||||
|
&& lineType == TLineType.RETURN) {
|
||||||
// System.err.println("s2=" + sl.getString());
|
// System.err.println("s2=" + sl.getString());
|
||||||
final EaterReturn eaterReturn = new EaterReturn(sl.getString());
|
final EaterReturn eaterReturn = new EaterReturn(sl);
|
||||||
eaterReturn.execute(context, copy);
|
eaterReturn.analyze(context, copy);
|
||||||
// System.err.println("s3=" + eaterReturn.getValue2());
|
// System.err.println("s3=" + eaterReturn.getValue2());
|
||||||
return eaterReturn.getValue2();
|
return eaterReturn.getValue2();
|
||||||
}
|
}
|
||||||
context.executeOneLine(copy, lineType, sl, TFunctionType.RETURN);
|
context.executeLines(copy, Arrays.asList(sl), TFunctionType.RETURN);
|
||||||
}
|
}
|
||||||
throw new EaterException("no return");
|
throw EaterException.unlocated("no return");
|
||||||
// return TValue.fromString("(NONE)");
|
// return TValue.fromString("(NONE)");
|
||||||
}
|
}
|
||||||
|
|
||||||
private TValue executeReturnLegacyDefine(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
private TValue executeReturnLegacyDefine(LineLocation location, TContext context, TMemory memory, List<TValue> args)
|
||||||
|
throws EaterException, EaterExceptionLocated {
|
||||||
if (legacyDefinition == null) {
|
if (legacyDefinition == null) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
final TMemory copy = getNewMemory(memory, args);
|
final TMemory copy = getNewMemory(memory, args);
|
||||||
final String tmp = context.applyFunctionsAndVariables(copy, legacyDefinition);
|
final String tmp = context.applyFunctionsAndVariables(copy, location, legacyDefinition);
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
return TValue.fromString("");
|
return TValue.fromString("");
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,23 @@ package net.sourceforge.plantuml.tim;
|
|||||||
|
|
||||||
public enum TLineType {
|
public enum TLineType {
|
||||||
|
|
||||||
PLAIN, AFFECTATION_DEFINE, AFFECTATION, ASSERT, IF, IFDEF, UNDEF, IFNDEF, ELSE, ELSEIF, ENDIF, DECLARE_FUNCTION, END_FUNCTION, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG, INCLUDE, INCLUDE_DEF, IMPORT, STARTSUB, ENDSUB, INCLUDESUB, LOG, DUMP_MEMORY, COMMENT_SIMPLE, COMMENT_LONG_START;
|
PLAIN, AFFECTATION_DEFINE, AFFECTATION, ASSERT, IF, IFDEF, UNDEF, IFNDEF, ELSE, ELSEIF, ENDIF, WHILE, ENDWHILE,
|
||||||
|
FOREACH, ENDFOREACH, DECLARE_FUNCTION, END_FUNCTION, RETURN, LEGACY_DEFINE, LEGACY_DEFINELONG, INCLUDE, INCLUDE_DEF,
|
||||||
|
IMPORT, STARTSUB, ENDSUB, INCLUDESUB, LOG, DUMP_MEMORY, COMMENT_SIMPLE, COMMENT_LONG_START;
|
||||||
|
|
||||||
public static TLineType getFromLine(String s) {
|
// private boolean elseLike() {
|
||||||
|
// return this == ELSE || this == ELSEIF;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public boolean incIndentAfter() {
|
||||||
|
// return this == IF || this == IFDEF || this == IFNDEF || elseLike();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public boolean decIndentBefore() {
|
||||||
|
// return this == ENDIF || elseLike();
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static TLineType getFromLineInternal(String s) {
|
||||||
if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) {
|
if (s.matches("^\\s*!define\\s+[\\p{L}_][\\p{L}_0-9]*\\(.*")) {
|
||||||
return LEGACY_DEFINE;
|
return LEGACY_DEFINE;
|
||||||
}
|
}
|
||||||
@ -87,6 +101,18 @@ public enum TLineType {
|
|||||||
if (s.matches("^\\s*!endif\\b.*")) {
|
if (s.matches("^\\s*!endif\\b.*")) {
|
||||||
return ENDIF;
|
return ENDIF;
|
||||||
}
|
}
|
||||||
|
if (s.matches("^\\s*!while\\s+.*")) {
|
||||||
|
return WHILE;
|
||||||
|
}
|
||||||
|
if (s.matches("^\\s*!endwhile\\b.*")) {
|
||||||
|
return ENDWHILE;
|
||||||
|
}
|
||||||
|
if (s.matches("^\\s*!foreach\\s+.*")) {
|
||||||
|
return FOREACH;
|
||||||
|
}
|
||||||
|
if (s.matches("^\\s*!endfor\\b.*")) {
|
||||||
|
return ENDFOREACH;
|
||||||
|
}
|
||||||
if (s.matches("^\\s*!(endfunction|enddefinelong)\\b.*")) {
|
if (s.matches("^\\s*!(endfunction|enddefinelong)\\b.*")) {
|
||||||
return END_FUNCTION;
|
return END_FUNCTION;
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,13 @@ package net.sourceforge.plantuml.tim;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public interface TMemory {
|
public interface TMemory {
|
||||||
|
|
||||||
public TVariable getVariable(String varname);
|
public TValue getVariable(String varname);
|
||||||
|
|
||||||
public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException;
|
public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException;
|
||||||
|
|
||||||
public void removeVariable(String varname);
|
public void removeVariable(String varname);
|
||||||
|
|
||||||
@ -51,15 +53,28 @@ public interface TMemory {
|
|||||||
|
|
||||||
public Trie variablesNames3();
|
public Trie variablesNames3();
|
||||||
|
|
||||||
public TMemory forkFromGlobal(Map<String, TVariable> input);
|
public TMemory forkFromGlobal(Map<String, TValue> input);
|
||||||
|
|
||||||
public ConditionalContext peekConditionalContext();
|
public ExecutionContextIf peekIf();
|
||||||
|
|
||||||
public boolean areAllIfOk();
|
public boolean areAllIfOk(TContext context, TMemory memory) throws EaterException;
|
||||||
|
|
||||||
public void addConditionalContext(ConditionalContext context);
|
public void addIf(ExecutionContextIf context);
|
||||||
|
|
||||||
public ConditionalContext pollConditionalContext();
|
public void addWhile(ExecutionContextWhile value);
|
||||||
|
|
||||||
|
public void addForeach(ExecutionContextForeach value);
|
||||||
|
|
||||||
|
public ExecutionContextIf pollIf();
|
||||||
|
|
||||||
|
public ExecutionContextWhile pollWhile();
|
||||||
|
|
||||||
|
public ExecutionContextWhile peekWhile();
|
||||||
|
|
||||||
|
public ExecutionContextForeach pollForeach();
|
||||||
|
|
||||||
|
public ExecutionContextForeach peekForeach();
|
||||||
|
|
||||||
public void dumpDebug(String message);
|
public void dumpDebug(String message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,12 @@ import java.util.TreeMap;
|
|||||||
import net.sourceforge.plantuml.Log;
|
import net.sourceforge.plantuml.Log;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class TMemoryGlobal extends ConditionalContexts implements TMemory {
|
public class TMemoryGlobal extends ExecutionContexts implements TMemory {
|
||||||
|
|
||||||
private final Map<String, TVariable> globalVariables = new HashMap<String, TVariable>();
|
private final Map<String, TValue> globalVariables = new HashMap<String, TValue>();
|
||||||
private final TrieImpl variables = new TrieImpl();
|
private final TrieImpl variables = new TrieImpl();
|
||||||
|
|
||||||
public TVariable getVariable(String varname) {
|
public TValue getVariable(String varname) {
|
||||||
return this.globalVariables.get(varname);
|
return this.globalVariables.get(varname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,17 +61,17 @@ public class TMemoryGlobal extends ConditionalContexts implements TMemory {
|
|||||||
|
|
||||||
void dumpMemoryInternal() {
|
void dumpMemoryInternal() {
|
||||||
Log.error("[MemGlobal] Number of variable(s) : " + globalVariables.size());
|
Log.error("[MemGlobal] Number of variable(s) : " + globalVariables.size());
|
||||||
for (Entry<String, TVariable> ent : new TreeMap<String, TVariable>(globalVariables).entrySet()) {
|
for (Entry<String, TValue> ent : new TreeMap<String, TValue>(globalVariables).entrySet()) {
|
||||||
final String name = ent.getKey();
|
final String name = ent.getKey();
|
||||||
final TValue value = ent.getValue().getValue();
|
final TValue value = ent.getValue();
|
||||||
Log.error("[MemGlobal] " + name + " = " + value);
|
Log.error("[MemGlobal] " + name + " = " + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException {
|
public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException {
|
||||||
Log.info("[MemGlobal] Setting " + varname);
|
Log.info("[MemGlobal] Setting " + varname);
|
||||||
if (scope == TVariableScope.LOCAL) {
|
if (scope == TVariableScope.LOCAL) {
|
||||||
throw new EaterException("Cannot use local variable here");
|
throw EaterException.unlocated("Cannot use local variable here");
|
||||||
}
|
}
|
||||||
this.globalVariables.put(varname, value);
|
this.globalVariables.put(varname, value);
|
||||||
this.variables.add(varname);
|
this.variables.add(varname);
|
||||||
@ -94,7 +94,7 @@ public class TMemoryGlobal extends ConditionalContexts implements TMemory {
|
|||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TMemory forkFromGlobal(Map<String, TVariable> input) {
|
public TMemory forkFromGlobal(Map<String, TValue> input) {
|
||||||
return new TMemoryLocal(this, input);
|
return new TMemoryLocal(this, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,15 @@ import java.util.TreeMap;
|
|||||||
import net.sourceforge.plantuml.Log;
|
import net.sourceforge.plantuml.Log;
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class TMemoryLocal extends ConditionalContexts implements TMemory {
|
public class TMemoryLocal extends ExecutionContexts implements TMemory {
|
||||||
|
|
||||||
private final TMemoryGlobal memoryGlobal;
|
private final TMemoryGlobal memoryGlobal;
|
||||||
private TrieImpl overridenVariables00;
|
private TrieImpl overridenVariables00;
|
||||||
private final Map<String, TVariable> overridenVariables01 = new HashMap<String, TVariable>();
|
private final Map<String, TValue> overridenVariables01 = new HashMap<String, TValue>();
|
||||||
private final TrieImpl localVariables00 = new TrieImpl();
|
private final TrieImpl localVariables00 = new TrieImpl();
|
||||||
private final Map<String, TVariable> localVariables01 = new HashMap<String, TVariable>();
|
private final Map<String, TValue> localVariables01 = new HashMap<String, TValue>();
|
||||||
|
|
||||||
public TMemoryLocal(TMemoryGlobal global, Map<String, TVariable> input) {
|
public TMemoryLocal(TMemoryGlobal global, Map<String, TValue> input) {
|
||||||
this.memoryGlobal = global;
|
this.memoryGlobal = global;
|
||||||
this.overridenVariables01.putAll(input);
|
this.overridenVariables01.putAll(input);
|
||||||
}
|
}
|
||||||
@ -59,24 +59,24 @@ public class TMemoryLocal extends ConditionalContexts implements TMemory {
|
|||||||
public void dumpDebug(String message) {
|
public void dumpDebug(String message) {
|
||||||
Log.error("[MemLocal] Start of memory_dump " + message);
|
Log.error("[MemLocal] Start of memory_dump " + message);
|
||||||
memoryGlobal.dumpMemoryInternal();
|
memoryGlobal.dumpMemoryInternal();
|
||||||
final TreeMap<String, TVariable> over = new TreeMap<String, TVariable>(overridenVariables01);
|
final TreeMap<String, TValue> over = new TreeMap<String, TValue>(overridenVariables01);
|
||||||
Log.error("[MemLocal] Number of overriden variable(s) : " + over.size());
|
Log.error("[MemLocal] Number of overriden variable(s) : " + over.size());
|
||||||
for (Entry<String, TVariable> ent : over.entrySet()) {
|
for (Entry<String, TValue> ent : over.entrySet()) {
|
||||||
final String name = ent.getKey();
|
final String name = ent.getKey();
|
||||||
final TValue value = ent.getValue().getValue();
|
final TValue value = ent.getValue();
|
||||||
Log.error("[MemLocal] " + name + " = " + value);
|
Log.error("[MemLocal] " + name + " = " + value);
|
||||||
}
|
}
|
||||||
final TreeMap<String, TVariable> local = new TreeMap<String, TVariable>(localVariables01);
|
final TreeMap<String, TValue> local = new TreeMap<String, TValue>(localVariables01);
|
||||||
Log.error("[MemLocal] Number of local variable(s) : " + local.size());
|
Log.error("[MemLocal] Number of local variable(s) : " + local.size());
|
||||||
for (Entry<String, TVariable> ent : local.entrySet()) {
|
for (Entry<String, TValue> ent : local.entrySet()) {
|
||||||
final String name = ent.getKey();
|
final String name = ent.getKey();
|
||||||
final TValue value = ent.getValue().getValue();
|
final TValue value = ent.getValue();
|
||||||
Log.error("[MemLocal] " + name + " = " + value);
|
Log.error("[MemLocal] " + name + " = " + value);
|
||||||
}
|
}
|
||||||
Log.error("[MemGlobal] End of memory_dump");
|
Log.error("[MemGlobal] End of memory_dump");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVariable(String varname, TVariable value, TVariableScope scope) throws EaterException {
|
public void putVariable(String varname, TValue value, TVariableScope scope) throws EaterException {
|
||||||
if (scope == TVariableScope.GLOBAL) {
|
if (scope == TVariableScope.GLOBAL) {
|
||||||
memoryGlobal.putVariable(varname, value, scope);
|
memoryGlobal.putVariable(varname, value, scope);
|
||||||
return;
|
return;
|
||||||
@ -110,8 +110,8 @@ public class TMemoryLocal extends ConditionalContexts implements TMemory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TVariable getVariable(String varname) {
|
public TValue getVariable(String varname) {
|
||||||
TVariable result = overridenVariables01.get(varname);
|
TValue result = overridenVariables01.get(varname);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -170,7 +170,7 @@ public class TMemoryLocal extends ConditionalContexts implements TMemory {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TMemory forkFromGlobal(Map<String, TVariable> input) {
|
public TMemory forkFromGlobal(Map<String, TValue> input) {
|
||||||
return new TMemoryLocal(memoryGlobal, input);
|
return new TMemoryLocal(memoryGlobal, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,18 +58,14 @@ public class TimLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(List<StringLocated> input) {
|
public void load(List<StringLocated> list) {
|
||||||
for (StringLocated s : input) {
|
// CodeIteratorImpl.indentNow(list);
|
||||||
final TLineType type = TLineType.getFromLine(s.getTrimmed().getString());
|
try {
|
||||||
try {
|
context.executeLines(global, list, null);
|
||||||
context.executeOneLine(global, type, s, null);
|
} catch (EaterExceptionLocated e) {
|
||||||
} catch (EaterException e) {
|
context.getResultList().add(e.getLocation().withErrorPreprocessor(e.getMessage()));
|
||||||
context.getResultList().add(s.withErrorPreprocessor(e.getMessage()));
|
changeLastLine(context.getDebug(), e.getMessage());
|
||||||
this.resultList = context.getResultList();
|
this.preprocessorError = true;
|
||||||
changeLastLine(context.getDebug(), e.getMessage());
|
|
||||||
this.preprocessorError = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.resultList = context.getResultList();
|
this.resultList = context.getResultList();
|
||||||
}
|
}
|
||||||
|
143
src/net/sourceforge/plantuml/tim/VariableManager.java
Normal file
143
src/net/sourceforge/plantuml/tim/VariableManager.java
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
|
import net.sourceforge.plantuml.json.JsonArray;
|
||||||
|
import net.sourceforge.plantuml.json.JsonObject;
|
||||||
|
import net.sourceforge.plantuml.json.JsonValue;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
|
public class VariableManager {
|
||||||
|
|
||||||
|
private final TMemory memory;
|
||||||
|
private final TContext context;
|
||||||
|
private final LineLocation location;
|
||||||
|
|
||||||
|
public VariableManager(TContext context, TMemory memory, LineLocation location) {
|
||||||
|
this.memory = memory;
|
||||||
|
this.context = context;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int replaceVariables(String str, int i, StringBuilder result) throws EaterException, EaterExceptionLocated {
|
||||||
|
final String presentVariable = getVarnameAt(str, i);
|
||||||
|
if (result.toString().endsWith("##")) {
|
||||||
|
result.setLength(result.length() - 2);
|
||||||
|
}
|
||||||
|
final TValue value = memory.getVariable(presentVariable);
|
||||||
|
i += presentVariable.length() - 1;
|
||||||
|
if (value.isJson()) {
|
||||||
|
if (value.toJson().isString()) {
|
||||||
|
result.append(value.toJson().asString());
|
||||||
|
} else {
|
||||||
|
JsonValue jsonValue = (JsonObject) value.toJson();
|
||||||
|
i++;
|
||||||
|
i = replaceJson(jsonValue, str, i, result) - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.append(value.toString());
|
||||||
|
}
|
||||||
|
if (i + 2 < str.length() && str.charAt(i + 1) == '#' && str.charAt(i + 2) == '#') {
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int replaceJson(JsonValue jsonValue, String str, int i, StringBuilder result)
|
||||||
|
throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final char n = str.charAt(i);
|
||||||
|
if (n == '.') {
|
||||||
|
i++;
|
||||||
|
final StringBuilder fieldName = new StringBuilder();
|
||||||
|
while (true) {
|
||||||
|
if (i >= str.length()) {
|
||||||
|
throw EaterException.unlocated("Parsing error");
|
||||||
|
}
|
||||||
|
if (Character.isJavaIdentifierPart(str.charAt(i)) == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fieldName.append(str.charAt(i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
jsonValue = ((JsonObject) jsonValue).get(fieldName.toString());
|
||||||
|
} else if (n == '[') {
|
||||||
|
i++;
|
||||||
|
final StringBuilder inBracket = new StringBuilder();
|
||||||
|
while (true) {
|
||||||
|
if (str.charAt(i) == ']') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inBracket.append(str.charAt(i));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
final String nbString = context.applyFunctionsAndVariables(memory, location, inBracket.toString());
|
||||||
|
final int nb = Integer.parseInt(nbString);
|
||||||
|
jsonValue = ((JsonArray) jsonValue).get(nb);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
if (jsonValue.isString()) {
|
||||||
|
result.append(jsonValue.asString());
|
||||||
|
} else {
|
||||||
|
result.append(jsonValue.toString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVarnameAt(String s, int pos) {
|
||||||
|
if (pos > 0 && TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos - 1))
|
||||||
|
&& justAfterBackslashN(s, pos) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String varname = memory.variablesNames3().getLonguestMatchStartingIn(s.substring(pos));
|
||||||
|
if (varname.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (pos + varname.length() == s.length()
|
||||||
|
|| TLineType.isLetterOrUnderscoreOrDigit(s.charAt(pos + varname.length())) == false) {
|
||||||
|
return varname;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean justAfterBackslashN(String s, int pos) {
|
||||||
|
return pos > 1 && s.charAt(pos - 2) == '\\' && s.charAt(pos - 1) == 'n';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -36,11 +36,10 @@ package net.sourceforge.plantuml.tim.expression;
|
|||||||
|
|
||||||
import net.sourceforge.plantuml.tim.TFunction;
|
import net.sourceforge.plantuml.tim.TFunction;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
import net.sourceforge.plantuml.tim.TVariable;
|
|
||||||
|
|
||||||
public interface Knowledge {
|
public interface Knowledge {
|
||||||
|
|
||||||
public TVariable getVariable(String name);
|
public TValue getVariable(String name);
|
||||||
|
|
||||||
public TFunction getFunction(TFunctionSignature signature);
|
public TFunction getFunction(TFunctionSignature signature);
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunction;
|
import net.sourceforge.plantuml.tim.TFunction;
|
||||||
@ -51,7 +53,12 @@ public class ReversePolishInterpretor {
|
|||||||
private boolean trace = false;
|
private boolean trace = false;
|
||||||
|
|
||||||
public ReversePolishInterpretor(TokenStack queue, Knowledge knowledge, TMemory memory, TContext context)
|
public ReversePolishInterpretor(TokenStack queue, Knowledge knowledge, TMemory memory, TContext context)
|
||||||
throws EaterException {
|
throws EaterException, EaterExceptionLocated {
|
||||||
|
this(null, queue, knowledge, memory, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReversePolishInterpretor(LineLocation location, TokenStack queue, Knowledge knowledge, TMemory memory,
|
||||||
|
TContext context) throws EaterException, EaterExceptionLocated {
|
||||||
|
|
||||||
final Deque<TValue> stack = new ArrayDeque<TValue>();
|
final Deque<TValue> stack = new ArrayDeque<TValue>();
|
||||||
if (trace)
|
if (trace)
|
||||||
@ -64,12 +71,14 @@ public class ReversePolishInterpretor {
|
|||||||
stack.addFirst(TValue.fromNumber(token));
|
stack.addFirst(TValue.fromNumber(token));
|
||||||
} else if (token.getTokenType() == TokenType.QUOTED_STRING) {
|
} else if (token.getTokenType() == TokenType.QUOTED_STRING) {
|
||||||
stack.addFirst(TValue.fromString(token));
|
stack.addFirst(TValue.fromString(token));
|
||||||
|
} else if (token.getTokenType() == TokenType.JSON_DATA) {
|
||||||
|
stack.addFirst(TValue.fromJson(token.getJson()));
|
||||||
} else if (token.getTokenType() == TokenType.OPERATOR) {
|
} else if (token.getTokenType() == TokenType.OPERATOR) {
|
||||||
final TValue v2 = stack.removeFirst();
|
final TValue v2 = stack.removeFirst();
|
||||||
final TValue v1 = stack.removeFirst();
|
final TValue v1 = stack.removeFirst();
|
||||||
final TokenOperator op = token.getTokenOperator();
|
final TokenOperator op = token.getTokenOperator();
|
||||||
if (op == null) {
|
if (op == null) {
|
||||||
throw new EaterException("bad op");
|
throw EaterException.unlocated("bad op");
|
||||||
}
|
}
|
||||||
final TValue tmp = op.operate(v1, v2);
|
final TValue tmp = op.operate(v1, v2);
|
||||||
stack.addFirst(tmp);
|
stack.addFirst(tmp);
|
||||||
@ -77,7 +86,7 @@ public class ReversePolishInterpretor {
|
|||||||
final int nb = Integer.parseInt(token.getSurface());
|
final int nb = Integer.parseInt(token.getSurface());
|
||||||
final Token token2 = it.nextToken();
|
final Token token2 = it.nextToken();
|
||||||
if (token2.getTokenType() != TokenType.FUNCTION_NAME) {
|
if (token2.getTokenType() != TokenType.FUNCTION_NAME) {
|
||||||
throw new EaterException("rpn43");
|
throw EaterException.unlocated("rpn43");
|
||||||
}
|
}
|
||||||
if (trace)
|
if (trace)
|
||||||
System.err.println("token2=" + token2);
|
System.err.println("token2=" + token2);
|
||||||
@ -85,10 +94,11 @@ public class ReversePolishInterpretor {
|
|||||||
if (trace)
|
if (trace)
|
||||||
System.err.println("function=" + function);
|
System.err.println("function=" + function);
|
||||||
if (function == null) {
|
if (function == null) {
|
||||||
throw new EaterException("Unknow built-in function " + token2.getSurface());
|
throw EaterException.unlocated("Unknow built-in function " + token2.getSurface());
|
||||||
}
|
}
|
||||||
if (function.canCover(nb) == false) {
|
if (function.canCover(nb) == false) {
|
||||||
throw new EaterException("Bad number of arguments for " + function.getSignature().getFunctionName());
|
throw EaterException
|
||||||
|
.unlocated("Bad number of arguments for " + function.getSignature().getFunctionName());
|
||||||
}
|
}
|
||||||
final List<TValue> args = new ArrayList<TValue>();
|
final List<TValue> args = new ArrayList<TValue>();
|
||||||
for (int i = 0; i < nb; i++) {
|
for (int i = 0; i < nb; i++) {
|
||||||
@ -96,12 +106,15 @@ public class ReversePolishInterpretor {
|
|||||||
}
|
}
|
||||||
if (trace)
|
if (trace)
|
||||||
System.err.println("args=" + args);
|
System.err.println("args=" + args);
|
||||||
final TValue r = function.executeReturn(context, memory, args);
|
if (location == null) {
|
||||||
|
throw EaterException.unlocated("rpn44");
|
||||||
|
}
|
||||||
|
final TValue r = function.executeReturn(context, memory, location, args);
|
||||||
if (trace)
|
if (trace)
|
||||||
System.err.println("r=" + r);
|
System.err.println("r=" + r);
|
||||||
stack.addFirst(r);
|
stack.addFirst(r);
|
||||||
} else {
|
} else {
|
||||||
throw new EaterException("rpn41");
|
throw EaterException.unlocated("rpn41");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = stack.removeFirst();
|
result = stack.removeFirst();
|
||||||
|
@ -37,9 +37,6 @@ package net.sourceforge.plantuml.tim.expression;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
|
||||||
import net.sourceforge.plantuml.tim.TVariable;
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
// https://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
||||||
// https://en.cppreference.com/w/c/language/operator_precedence
|
// https://en.cppreference.com/w/c/language/operator_precedence
|
||||||
public class ShuntingYard {
|
public class ShuntingYard {
|
||||||
@ -58,7 +55,7 @@ public class ShuntingYard {
|
|||||||
System.err.println("");
|
System.err.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShuntingYard(TokenIterator it, Knowledge knowledge) throws EaterException {
|
public ShuntingYard(TokenIterator it, Knowledge knowledge) {
|
||||||
|
|
||||||
while (it.hasMoreTokens()) {
|
while (it.hasMoreTokens()) {
|
||||||
final Token token = it.nextToken();
|
final Token token = it.nextToken();
|
||||||
@ -71,15 +68,16 @@ public class ShuntingYard {
|
|||||||
operatorStack.addFirst(token);
|
operatorStack.addFirst(token);
|
||||||
} else if (token.getTokenType() == TokenType.PLAIN_TEXT) {
|
} else if (token.getTokenType() == TokenType.PLAIN_TEXT) {
|
||||||
final String name = token.getSurface();
|
final String name = token.getSurface();
|
||||||
final TVariable variable = knowledge.getVariable(name);
|
final TValue variable = knowledge.getVariable(name);
|
||||||
if (variable == null) {
|
if (variable == null) {
|
||||||
throw new EaterException("Unknown variable " + name);
|
ouputQueue.add(new Token("undefined", TokenType.QUOTED_STRING, null));
|
||||||
|
} else {
|
||||||
|
ouputQueue.add(variable.toToken());
|
||||||
}
|
}
|
||||||
ouputQueue.add(variable.getValue().toToken());
|
|
||||||
} else if (token.getTokenType() == TokenType.OPERATOR) {
|
} else if (token.getTokenType() == TokenType.OPERATOR) {
|
||||||
while ((thereIsAFunctionAtTheTopOfTheOperatorStack(token) //
|
while ((thereIsAFunctionAtTheTopOfTheOperatorStack(token) //
|
||||||
|| thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(token) //
|
|| thereIsAnOperatorAtTheTopOfTheOperatorStackWithGreaterPrecedence(token) //
|
||||||
|| theOperatorAtTheTopOfTheOperatorStackHasEqualPrecedenceAndIsLeftAssociative(token)) //
|
|| theOperatorAtTheTopOfTheOperatorStackHasEqualPrecedenceAndIsLeftAssociative(token)) //
|
||||||
&& theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(token)) {
|
&& theOperatorAtTheTopOfTheOperatorStackIsNotALeftParenthesis(token)) {
|
||||||
ouputQueue.add(operatorStack.removeFirst());
|
ouputQueue.add(operatorStack.removeFirst());
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,12 @@ public class TValue {
|
|||||||
|
|
||||||
public Token toToken() {
|
public Token toToken() {
|
||||||
if (isNumber()) {
|
if (isNumber()) {
|
||||||
return new Token(toString(), TokenType.NUMBER);
|
return new Token(toString(), TokenType.NUMBER, null);
|
||||||
}
|
}
|
||||||
return new Token(toString(), TokenType.QUOTED_STRING);
|
if (isJson()) {
|
||||||
|
return new Token(toString(), TokenType.JSON_DATA, jsonValue);
|
||||||
|
}
|
||||||
|
return new Token(toString(), TokenType.QUOTED_STRING, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue greaterThanOrEquals(TValue v2) {
|
public TValue greaterThanOrEquals(TValue v2) {
|
||||||
|
@ -34,9 +34,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim.expression;
|
package net.sourceforge.plantuml.tim.expression;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.json.JsonValue;
|
||||||
|
|
||||||
public class Token {
|
public class Token {
|
||||||
|
|
||||||
private final String surface;
|
private final String surface;
|
||||||
|
private final JsonValue json;
|
||||||
private final TokenType tokenType;
|
private final TokenType tokenType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,13 +47,14 @@ public class Token {
|
|||||||
return tokenType + "{" + surface + "}";
|
return tokenType + "{" + surface + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Token(char surface, TokenType tokenType) {
|
public Token(char surface, TokenType tokenType, JsonValue json) {
|
||||||
this("" + surface, tokenType);
|
this("" + surface, tokenType, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Token(String surface, TokenType tokenType) {
|
public Token(String surface, TokenType tokenType, JsonValue json) {
|
||||||
this.surface = surface;
|
this.surface = surface;
|
||||||
this.tokenType = tokenType;
|
this.tokenType = tokenType;
|
||||||
|
this.json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenOperator getTokenOperator() {
|
public TokenOperator getTokenOperator() {
|
||||||
@ -73,7 +77,14 @@ public class Token {
|
|||||||
if (this.tokenType != TokenType.PLAIN_TEXT) {
|
if (this.tokenType != TokenType.PLAIN_TEXT) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
return new Token(surface, TokenType.FUNCTION_NAME);
|
return new Token(surface, TokenType.FUNCTION_NAME, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonValue getJson() {
|
||||||
|
if (this.tokenType != TokenType.JSON_DATA) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,9 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.Eater;
|
import net.sourceforge.plantuml.tim.Eater;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TMemory;
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
@ -93,7 +95,7 @@ public class TokenStack {
|
|||||||
eater.skipSpaces();
|
eater.skipSpaces();
|
||||||
final char ch = eater.peekChar();
|
final char ch = eater.peekChar();
|
||||||
if (ch == 0) {
|
if (ch == 0) {
|
||||||
throw new EaterException("until001");
|
throw EaterException.unlocated("until001");
|
||||||
}
|
}
|
||||||
if (level == 0 && (ch == ',' || ch == ')')) {
|
if (level == 0 && (ch == ',' || ch == ')')) {
|
||||||
return result;
|
return result;
|
||||||
@ -114,7 +116,7 @@ public class TokenStack {
|
|||||||
while (true) {
|
while (true) {
|
||||||
final Token ch = it.peekToken();
|
final Token ch = it.peekToken();
|
||||||
if (ch == null) {
|
if (ch == null) {
|
||||||
throw new EaterException("until002");
|
throw EaterException.unlocated("until002");
|
||||||
}
|
}
|
||||||
final TokenType typech = ch.getTokenType();
|
final TokenType typech = ch.getTokenType();
|
||||||
if (level == 0 && (typech == TokenType.COMMA || typech == TokenType.CLOSE_PAREN_MATH)
|
if (level == 0 && (typech == TokenType.COMMA || typech == TokenType.CLOSE_PAREN_MATH)
|
||||||
@ -147,10 +149,10 @@ public class TokenStack {
|
|||||||
} else if (type == TokenType.COMMA) {
|
} else if (type == TokenType.COMMA) {
|
||||||
result++;
|
result++;
|
||||||
} else {
|
} else {
|
||||||
throw new EaterException("count13");
|
throw EaterException.unlocated("count13");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new EaterException("count12");
|
throw EaterException.unlocated("count12");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void guessFunctions() throws EaterException {
|
public void guessFunctions() throws EaterException {
|
||||||
@ -172,10 +174,10 @@ public class TokenStack {
|
|||||||
assert tokens.get(iopen).getTokenType() == TokenType.OPEN_PAREN_MATH;
|
assert tokens.get(iopen).getTokenType() == TokenType.OPEN_PAREN_MATH;
|
||||||
assert tokens.get(iclose).getTokenType() == TokenType.CLOSE_PAREN_MATH;
|
assert tokens.get(iclose).getTokenType() == TokenType.CLOSE_PAREN_MATH;
|
||||||
if (iopen > 0 && tokens.get(iopen - 1).getTokenType() == TokenType.PLAIN_TEXT) {
|
if (iopen > 0 && tokens.get(iopen - 1).getTokenType() == TokenType.PLAIN_TEXT) {
|
||||||
tokens.set(iopen - 1, new Token(tokens.get(iopen - 1).getSurface(), TokenType.FUNCTION_NAME));
|
tokens.set(iopen - 1, new Token(tokens.get(iopen - 1).getSurface(), TokenType.FUNCTION_NAME, null));
|
||||||
final int nbArg = countFunctionArg(subTokenStack(iopen + 1).tokenIterator());
|
final int nbArg = countFunctionArg(subTokenStack(iopen + 1).tokenIterator());
|
||||||
tokens.set(iopen, new Token("" + nbArg, TokenType.OPEN_PAREN_FUNC));
|
tokens.set(iopen, new Token("" + nbArg, TokenType.OPEN_PAREN_FUNC, null));
|
||||||
tokens.set(iclose, new Token(")", TokenType.CLOSE_PAREN_FUNC));
|
tokens.set(iclose, new Token(")", TokenType.CLOSE_PAREN_FUNC, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// System.err.println("after=" + toString());
|
// System.err.println("after=" + toString());
|
||||||
@ -206,14 +208,14 @@ public class TokenStack {
|
|||||||
return new InternalIterator();
|
return new InternalIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue getResult(TContext context, TMemory memory) throws EaterException {
|
public TValue getResult(LineLocation location, TContext context, TMemory memory) throws EaterException, EaterExceptionLocated {
|
||||||
final Knowledge knowledge = context.asKnowledge(memory);
|
final Knowledge knowledge = context.asKnowledge(memory);
|
||||||
final TokenStack tmp = withoutSpace();
|
final TokenStack tmp = withoutSpace();
|
||||||
tmp.guessFunctions();
|
tmp.guessFunctions();
|
||||||
final TokenIterator it = tmp.tokenIterator();
|
final TokenIterator it = tmp.tokenIterator();
|
||||||
final ShuntingYard shuntingYard = new ShuntingYard(it, knowledge);
|
final ShuntingYard shuntingYard = new ShuntingYard(it, knowledge);
|
||||||
final ReversePolishInterpretor rpn = new ReversePolishInterpretor(shuntingYard.getQueue(), knowledge, memory,
|
final ReversePolishInterpretor rpn = new ReversePolishInterpretor(location, shuntingYard.getQueue(), knowledge,
|
||||||
context);
|
memory, context);
|
||||||
return rpn.getResult();
|
return rpn.getResult();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ import net.sourceforge.plantuml.tim.EaterException;
|
|||||||
import net.sourceforge.plantuml.tim.TLineType;
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
|
||||||
public enum TokenType {
|
public enum TokenType {
|
||||||
QUOTED_STRING, OPERATOR, OPEN_PAREN_MATH, COMMA, CLOSE_PAREN_MATH, NUMBER, PLAIN_TEXT, SPACES, FUNCTION_NAME, OPEN_PAREN_FUNC, CLOSE_PAREN_FUNC;
|
QUOTED_STRING, JSON_DATA, OPERATOR, OPEN_PAREN_MATH, COMMA, CLOSE_PAREN_MATH, NUMBER, PLAIN_TEXT, SPACES, FUNCTION_NAME, OPEN_PAREN_FUNC, CLOSE_PAREN_FUNC;
|
||||||
|
|
||||||
private boolean isSingleChar1() {
|
private boolean isSingleChar1() {
|
||||||
return this == OPEN_PAREN_MATH || this == COMMA || this == CLOSE_PAREN_MATH;
|
return this == OPEN_PAREN_MATH || this == COMMA || this == CLOSE_PAREN_MATH;
|
||||||
@ -83,24 +83,24 @@ public enum TokenType {
|
|||||||
}
|
}
|
||||||
final TokenOperator tokenOperator = TokenOperator.getTokenOperator(ch, eater.peekCharN2());
|
final TokenOperator tokenOperator = TokenOperator.getTokenOperator(ch, eater.peekCharN2());
|
||||||
if (TLineType.isQuote(ch)) {
|
if (TLineType.isQuote(ch)) {
|
||||||
return new Token(eater.eatAndGetQuotedString(), TokenType.QUOTED_STRING);
|
return new Token(eater.eatAndGetQuotedString(), TokenType.QUOTED_STRING, null);
|
||||||
} else if (tokenOperator != null) {
|
} else if (tokenOperator != null) {
|
||||||
if (tokenOperator.getDisplay().length() == 1) {
|
if (tokenOperator.getDisplay().length() == 1) {
|
||||||
return new Token(eater.eatOneChar(), TokenType.OPERATOR);
|
return new Token(eater.eatOneChar(), TokenType.OPERATOR, null);
|
||||||
}
|
}
|
||||||
return new Token("" + eater.eatOneChar() + eater.eatOneChar(), TokenType.OPERATOR);
|
return new Token("" + eater.eatOneChar() + eater.eatOneChar(), TokenType.OPERATOR, null);
|
||||||
} else if (ch == '(') {
|
} else if (ch == '(') {
|
||||||
return new Token(eater.eatOneChar(), TokenType.OPEN_PAREN_MATH);
|
return new Token(eater.eatOneChar(), TokenType.OPEN_PAREN_MATH, null);
|
||||||
} else if (ch == ')') {
|
} else if (ch == ')') {
|
||||||
return new Token(eater.eatOneChar(), TokenType.CLOSE_PAREN_MATH);
|
return new Token(eater.eatOneChar(), TokenType.CLOSE_PAREN_MATH, null);
|
||||||
} else if (ch == ',') {
|
} else if (ch == ',') {
|
||||||
return new Token(eater.eatOneChar(), TokenType.COMMA);
|
return new Token(eater.eatOneChar(), TokenType.COMMA, null);
|
||||||
} else if (TLineType.isLatinDigit(ch)) {
|
} else if (TLineType.isLatinDigit(ch)) {
|
||||||
return new Token(eater.eatAndGetNumber(), TokenType.NUMBER);
|
return new Token(eater.eatAndGetNumber(), TokenType.NUMBER, null);
|
||||||
} else if (TLineType.isSpaceChar(ch)) {
|
} else if (TLineType.isSpaceChar(ch)) {
|
||||||
return new Token(eater.eatAndGetSpaces(), TokenType.SPACES);
|
return new Token(eater.eatAndGetSpaces(), TokenType.SPACES, null);
|
||||||
}
|
}
|
||||||
return new Token(eatAndGetTokenPlainText(eater), TokenType.PLAIN_TEXT);
|
return new Token(eatAndGetTokenPlainText(eater), TokenType.PLAIN_TEXT, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private String eatAndGetTokenPlainText(Eater eater) throws EaterException {
|
static private String eatAndGetTokenPlainText(Eater eater) throws EaterException {
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
|
||||||
|
public abstract class AbstractCodeIterator implements CodeIterator {
|
||||||
|
|
||||||
|
protected final CodeIterator source;
|
||||||
|
|
||||||
|
public AbstractCodeIterator(CodeIterator source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void next() throws EaterException, EaterExceptionLocated {
|
||||||
|
source.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
final public CodePosition getCodePosition() {
|
||||||
|
return source.getCodePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
final public void jumpToCodePosition(CodePosition newPosition) throws EaterException {
|
||||||
|
source.jumpToCodePosition(newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
51
src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java
Normal file
51
src/net/sourceforge/plantuml/tim/iterator/CodeIterator.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
|
||||||
|
public interface CodeIterator {
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
|
public void next() throws EaterException, EaterExceptionLocated;
|
||||||
|
|
||||||
|
public CodePosition getCodePosition();
|
||||||
|
|
||||||
|
public void jumpToCodePosition(CodePosition newPosition) throws EaterException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.json.ParseException;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterAffectation;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
|
||||||
|
public class CodeIteratorAffectation extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorAffectation(CodeIterator source, TContext context, TMemory memory, List<StringLocated> log) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.memory = memory;
|
||||||
|
this.logs = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (result.getType() == TLineType.AFFECTATION) {
|
||||||
|
logs.add(result);
|
||||||
|
doAffectation(result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAffectation(StringLocated result) throws EaterException, EaterExceptionLocated {
|
||||||
|
int lastLocation = -1;
|
||||||
|
for (int i = 0; i < 100; i++)
|
||||||
|
try {
|
||||||
|
this.executeAffectation(context, memory, result);
|
||||||
|
return;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
if (e.getColumn() <= lastLocation) {
|
||||||
|
throw EaterException.located("Error in JSON format", result);
|
||||||
|
}
|
||||||
|
lastLocation = e.getColumn();
|
||||||
|
next();
|
||||||
|
final StringLocated forward = source.peek();
|
||||||
|
result = result.append(forward.getString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeAffectation(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
new EaterAffectation(s).analyze(context, memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.json.JsonValue;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterForeach;
|
||||||
|
import net.sourceforge.plantuml.tim.ExecutionContextForeach;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
import net.sourceforge.plantuml.tim.TVariableScope;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
|
public class CodeIteratorForeach extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorForeach(CodeIterator source, TContext context, TMemory memory, List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.memory = memory;
|
||||||
|
this.logs = logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
int level = 0;
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ExecutionContextForeach foreach = memory.peekForeach();
|
||||||
|
if (foreach != null && foreach.isSkipMe()) {
|
||||||
|
if (result.getType() == TLineType.FOREACH) {
|
||||||
|
level++;
|
||||||
|
} else if (result.getType() == TLineType.ENDFOREACH) {
|
||||||
|
level--;
|
||||||
|
if (level == -1) {
|
||||||
|
memory.pollForeach();
|
||||||
|
level = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getType() == TLineType.FOREACH) {
|
||||||
|
logs.add(result);
|
||||||
|
executeForeach(memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.ENDFOREACH) {
|
||||||
|
logs.add(result);
|
||||||
|
if (foreach == null) {
|
||||||
|
throw EaterException.located("No foreach related to this endforeach", result);
|
||||||
|
}
|
||||||
|
foreach.inc();
|
||||||
|
if (foreach.isSkipMe()) {
|
||||||
|
memory.pollForeach();
|
||||||
|
} else {
|
||||||
|
setLoopVariable(memory, foreach, result);
|
||||||
|
source.jumpToCodePosition(foreach.getStartForeach());
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeForeach(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
final EaterForeach condition = new EaterForeach(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final ExecutionContextForeach foreach = ExecutionContextForeach.fromValue(condition.getVarname(),
|
||||||
|
condition.getJsonArray(), source.getCodePosition());
|
||||||
|
if (condition.isSkip()) {
|
||||||
|
foreach.skipMeNow();
|
||||||
|
} else {
|
||||||
|
setLoopVariable(memory, foreach, s);
|
||||||
|
}
|
||||||
|
memory.addForeach(foreach);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLoopVariable(TMemory memory, ExecutionContextForeach foreach, StringLocated position)
|
||||||
|
throws EaterException {
|
||||||
|
final JsonValue first = foreach.getJsonArray().get(foreach.currentIndex());
|
||||||
|
memory.putVariable(foreach.getVarname(), TValue.fromJson(first), TVariableScope.GLOBAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.FunctionsSet;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
|
||||||
|
public class CodeIteratorFunction extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final FunctionsSet functionsSet;
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorFunction(CodeIterator source, TContext context, TMemory memory, FunctionsSet functionsSet,
|
||||||
|
List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.functionsSet = functionsSet;
|
||||||
|
this.logs = logs;
|
||||||
|
this.memory = memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functionsSet.pendingFunction() != null) {
|
||||||
|
logs.add(result);
|
||||||
|
if (result.getType() == TLineType.END_FUNCTION) {
|
||||||
|
functionsSet.executeEndfunction();
|
||||||
|
} else {
|
||||||
|
functionsSet.pendingFunction().addBody(result);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getType() == TLineType.DECLARE_FUNCTION) {
|
||||||
|
logs.add(result);
|
||||||
|
functionsSet.executeDeclareFunction(context, memory, result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
163
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java
Normal file
163
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorIf.java
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterElseIf;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterIf;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterIfdef;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterIfndef;
|
||||||
|
import net.sourceforge.plantuml.tim.ExecutionContextIf;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
|
||||||
|
public class CodeIteratorIf extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorIf(CodeIterator source, TContext context, TMemory memory, List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.memory = memory;
|
||||||
|
this.logs = logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (result.getType() == TLineType.IF) {
|
||||||
|
logs.add(result);
|
||||||
|
executeIf(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.IFDEF) {
|
||||||
|
logs.add(result);
|
||||||
|
executeIfdef(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.IFNDEF) {
|
||||||
|
logs.add(result);
|
||||||
|
executeIfndef(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.ELSE) {
|
||||||
|
logs.add(result);
|
||||||
|
executeElse(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.ELSEIF) {
|
||||||
|
logs.add(result);
|
||||||
|
executeElseIf(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.ENDIF) {
|
||||||
|
logs.add(result);
|
||||||
|
executeEndif(context, memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (memory.peekIf() != null && (memory.areAllIfOk(context, memory) == false)) {
|
||||||
|
logs.add(result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeIf(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
final EaterIf condition = new EaterIf(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final boolean isTrue = condition.isTrue();
|
||||||
|
memory.addIf(ExecutionContextIf.fromValue(isTrue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeElseIf(TContext context, TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf();
|
||||||
|
if (poll == null) {
|
||||||
|
throw EaterException.located("No if related to this else", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
poll.enteringElseIf();
|
||||||
|
if (poll.hasBeenBurn() == false) {
|
||||||
|
final EaterElseIf condition = new EaterElseIf(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final boolean isTrue = condition.isTrue();
|
||||||
|
if (isTrue) {
|
||||||
|
poll.nowInSomeElseIf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeIfdef(TContext context, TMemory memory, StringLocated s) throws EaterException {
|
||||||
|
final EaterIfdef condition = new EaterIfdef(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final boolean isTrue = condition.isTrue(context, memory);
|
||||||
|
memory.addIf(ExecutionContextIf.fromValue(isTrue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeIfndef(TContext context, TMemory memory, StringLocated s) throws EaterException {
|
||||||
|
final EaterIfndef condition = new EaterIfndef(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final boolean isTrue = condition.isTrue(context, memory);
|
||||||
|
memory.addIf(ExecutionContextIf.fromValue(isTrue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeElse(TContext context, TMemory memory, StringLocated s) throws EaterException {
|
||||||
|
final ExecutionContextIf poll = (ExecutionContextIf) memory.peekIf();
|
||||||
|
if (poll == null) {
|
||||||
|
throw EaterException.located("No if related to this else", s);
|
||||||
|
}
|
||||||
|
poll.nowInElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeEndif(TContext context, TMemory memory, StringLocated s) throws EaterException {
|
||||||
|
final ExecutionContextIf poll = (ExecutionContextIf) memory.pollIf();
|
||||||
|
if (poll == null) {
|
||||||
|
throw EaterException.located("No if related to this endif", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
|
||||||
|
public class CodeIteratorImpl implements CodeIterator {
|
||||||
|
|
||||||
|
private final List<StringLocated> list;
|
||||||
|
private int current = 0;
|
||||||
|
private int countJump = 0;
|
||||||
|
|
||||||
|
static class Position implements CodePosition {
|
||||||
|
final int pos;
|
||||||
|
|
||||||
|
Position(int pos) {
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// return "-->" + list.get(pos);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeIteratorImpl(List<StringLocated> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() {
|
||||||
|
if (current == list.size()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (current > list.size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return list.get(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void next() {
|
||||||
|
if (current >= list.size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
assert current < list.size();
|
||||||
|
current++;
|
||||||
|
assert current <= list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodePosition getCodePosition() {
|
||||||
|
return new Position(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jumpToCodePosition(CodePosition newPosition) throws EaterException {
|
||||||
|
this.countJump++;
|
||||||
|
if (this.countJump > 999) {
|
||||||
|
throw EaterException.unlocated("Infinite loop?");
|
||||||
|
}
|
||||||
|
final Position pos = (Position) newPosition;
|
||||||
|
this.current = pos.pos;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
|
||||||
|
public class CodeIteratorInnerComment extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
public CodeIteratorInnerComment(CodeIterator source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return result.removeInnerComment();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.FunctionsSet;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
|
||||||
|
public class CodeIteratorLegacyDefine extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final FunctionsSet functionsSet;
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorLegacyDefine(CodeIterator source, TContext context, TMemory memory, FunctionsSet functionsSet,
|
||||||
|
List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.functionsSet = functionsSet;
|
||||||
|
this.logs = logs;
|
||||||
|
this.memory = memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (result.getType() == TLineType.LEGACY_DEFINE) {
|
||||||
|
logs.add(result);
|
||||||
|
functionsSet.executeLegacyDefine(context, memory, result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.LEGACY_DEFINELONG) {
|
||||||
|
logs.add(result);
|
||||||
|
functionsSet.executeLegacyDefineLong(context, memory, result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
|
||||||
|
public class CodeIteratorLongComment extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorLongComment(CodeIterator source, List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.logs = logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
if (source.peek() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (source.peek().getType() != TLineType.COMMENT_LONG_START) {
|
||||||
|
return source.peek();
|
||||||
|
}
|
||||||
|
StringLocated s = null;
|
||||||
|
while ((s = source.peek()) != null && s.getTrimmed().getString().endsWith("'/") == false) {
|
||||||
|
logs.add(s);
|
||||||
|
source.next();
|
||||||
|
}
|
||||||
|
assert source.peek() == null || s.getTrimmed().getString().endsWith("'/");
|
||||||
|
if (source.peek() != null) {
|
||||||
|
assert s.getTrimmed().getString().endsWith("'/");
|
||||||
|
logs.add(source.peek());
|
||||||
|
source.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
|
||||||
|
public class CodeIteratorShortComment extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorShortComment(CodeIterator source, List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.logs = logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (result.getType() == TLineType.COMMENT_SIMPLE) {
|
||||||
|
logs.add(result);
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert result != null && result.getType() != TLineType.COMMENT_SIMPLE;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
112
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java
Normal file
112
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorSub.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.preproc.Sub;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterStartsub;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
|
||||||
|
public class CodeIteratorSub extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final Map<String, Sub> subs;
|
||||||
|
|
||||||
|
private CodeIterator readingInProgress;
|
||||||
|
|
||||||
|
private final TMemory memory;
|
||||||
|
private final TContext context;
|
||||||
|
|
||||||
|
public CodeIteratorSub(CodeIterator source, Map<String, Sub> subs, TContext context, TMemory memory) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.memory = memory;
|
||||||
|
this.subs = subs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Sub> getSubs() {
|
||||||
|
return Collections.unmodifiableMap(subs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (result.getType() == TLineType.STARTSUB) {
|
||||||
|
final EaterStartsub eater = new EaterStartsub(result.getTrimmed());
|
||||||
|
eater.analyze(context, memory);
|
||||||
|
final Sub created = new Sub(eater.getSubname());
|
||||||
|
this.subs.put(eater.getSubname(), created);
|
||||||
|
source.next();
|
||||||
|
StringLocated s = null;
|
||||||
|
while ((s = source.peek()) != null) {
|
||||||
|
if (s.getType() == TLineType.STARTSUB) {
|
||||||
|
throw EaterException.located("Cannot nest sub", s);
|
||||||
|
} else if (s.getType() == TLineType.ENDSUB) {
|
||||||
|
source.next();
|
||||||
|
readingInProgress = new CodeIteratorImpl(created.lines());
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
created.add(s);
|
||||||
|
source.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readingInProgress != null) {
|
||||||
|
return readingInProgress.peek();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void next() throws EaterException, EaterExceptionLocated {
|
||||||
|
if (readingInProgress == null) {
|
||||||
|
source.next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
readingInProgress.next();
|
||||||
|
if (readingInProgress.peek() == null) {
|
||||||
|
readingInProgress = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
123
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java
Normal file
123
src/net/sourceforge/plantuml/tim/iterator/CodeIteratorWhile.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* ========================================================================
|
||||||
|
* PlantUML : a free UML diagram generator
|
||||||
|
* ========================================================================
|
||||||
|
*
|
||||||
|
* (C) Copyright 2009-2020, Arnaud Roques
|
||||||
|
*
|
||||||
|
* Project Info: http://plantuml.com
|
||||||
|
*
|
||||||
|
* If you like this project or if you find it useful, you can support us at:
|
||||||
|
*
|
||||||
|
* http://plantuml.com/patreon (only 1$ per month!)
|
||||||
|
* http://plantuml.com/paypal
|
||||||
|
*
|
||||||
|
* This file is part of PlantUML.
|
||||||
|
*
|
||||||
|
* PlantUML is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PlantUML distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Original Author: Arnaud Roques
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.StringLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterWhile;
|
||||||
|
import net.sourceforge.plantuml.tim.ExecutionContextWhile;
|
||||||
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
|
import net.sourceforge.plantuml.tim.TLineType;
|
||||||
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
import net.sourceforge.plantuml.tim.expression.TokenStack;
|
||||||
|
|
||||||
|
public class CodeIteratorWhile extends AbstractCodeIterator {
|
||||||
|
|
||||||
|
private final TContext context;
|
||||||
|
private final TMemory memory;
|
||||||
|
private final List<StringLocated> logs;
|
||||||
|
|
||||||
|
public CodeIteratorWhile(CodeIterator source, TContext context, TMemory memory, List<StringLocated> logs) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
this.memory = memory;
|
||||||
|
this.logs = logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringLocated peek() throws EaterException, EaterExceptionLocated {
|
||||||
|
int level = 0;
|
||||||
|
while (true) {
|
||||||
|
final StringLocated result = source.peek();
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ExecutionContextWhile currentWhile = memory.peekWhile();
|
||||||
|
if (currentWhile != null && currentWhile.isSkipMe()) {
|
||||||
|
if (result.getType() == TLineType.WHILE) {
|
||||||
|
level++;
|
||||||
|
} else if (result.getType() == TLineType.ENDWHILE) {
|
||||||
|
level--;
|
||||||
|
if (level == -1) {
|
||||||
|
memory.pollWhile();
|
||||||
|
level = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getType() == TLineType.WHILE) {
|
||||||
|
logs.add(result);
|
||||||
|
executeWhile(memory, result.getTrimmed());
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
} else if (result.getType() == TLineType.ENDWHILE) {
|
||||||
|
logs.add(result);
|
||||||
|
if (currentWhile == null) {
|
||||||
|
throw EaterException.located("No while related to this endwhile", result);
|
||||||
|
}
|
||||||
|
final TValue value = currentWhile.conditionValue(result.getLocation(), context, memory);
|
||||||
|
if (value.toBoolean()) {
|
||||||
|
source.jumpToCodePosition(currentWhile.getStartWhile());
|
||||||
|
} else {
|
||||||
|
memory.pollWhile();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeWhile(TMemory memory, StringLocated s) throws EaterException, EaterExceptionLocated {
|
||||||
|
final EaterWhile condition = new EaterWhile(s);
|
||||||
|
condition.analyze(context, memory);
|
||||||
|
final TokenStack whileExpression = condition.getWhileExpression();
|
||||||
|
final ExecutionContextWhile theWhile = ExecutionContextWhile.fromValue(whileExpression,
|
||||||
|
source.getCodePosition());
|
||||||
|
final TValue value = theWhile.conditionValue(s.getLocation(), context, memory);
|
||||||
|
if (value.toBoolean() == false) {
|
||||||
|
theWhile.skipMe();
|
||||||
|
}
|
||||||
|
memory.addWhile(theWhile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,28 +32,8 @@
|
|||||||
* Original Author: Arnaud Roques
|
* Original Author: Arnaud Roques
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml.tim;
|
package net.sourceforge.plantuml.tim.iterator;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
public interface CodePosition {
|
||||||
|
|
||||||
public class TVariable {
|
|
||||||
|
|
||||||
private final TValue value;
|
|
||||||
|
|
||||||
public TVariable(TValue value) {
|
|
||||||
if (value == null) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " " + value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TValue getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
@ -52,7 +53,7 @@ public class AlwaysFalse extends SimpleReturnFunction {
|
|||||||
return nbArg == 0;
|
return nbArg == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
return TValue.fromBoolean(false);
|
return TValue.fromBoolean(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
@ -52,7 +53,7 @@ public class AlwaysTrue extends SimpleReturnFunction {
|
|||||||
return nbArg == 0;
|
return nbArg == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
return TValue.fromBoolean(true);
|
return TValue.fromBoolean(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,8 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
|
import net.sourceforge.plantuml.tim.EaterExceptionLocated;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunction;
|
import net.sourceforge.plantuml.tim.TFunction;
|
||||||
@ -53,15 +55,15 @@ public class CallUserFunction extends SimpleReturnFunction {
|
|||||||
return nbArg > 0;
|
return nbArg > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> values) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> values) throws EaterException, EaterExceptionLocated {
|
||||||
final String fname = values.get(0).toString();
|
final String fname = values.get(0).toString();
|
||||||
final List<TValue> args = values.subList(1, values.size());
|
final List<TValue> args = values.subList(1, values.size());
|
||||||
final TFunctionSignature signature = new TFunctionSignature(fname, args.size());
|
final TFunctionSignature signature = new TFunctionSignature(fname, args.size());
|
||||||
final TFunction func = context.getFunctionSmart(signature);
|
final TFunction func = context.getFunctionSmart(signature);
|
||||||
if (func == null) {
|
if (func == null) {
|
||||||
throw new EaterException("Cannot find void function " + fname);
|
throw EaterException.unlocated("Cannot find void function " + fname);
|
||||||
}
|
}
|
||||||
return func.executeReturn(context, memory, args);
|
return func.executeReturn(context, memory, location, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
@ -54,7 +55,7 @@ public class DateFunction extends SimpleReturnFunction {
|
|||||||
return nbArg == 0 || nbArg == 1;
|
return nbArg == 0 || nbArg == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
return TValue.fromString(new Date().toString());
|
return TValue.fromString(new Date().toString());
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ public class DateFunction extends SimpleReturnFunction {
|
|||||||
try {
|
try {
|
||||||
return TValue.fromString(new SimpleDateFormat(format).format(new Date()));
|
return TValue.fromString(new SimpleDateFormat(format).format(new Date()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new EaterException("Bad date pattern");
|
throw EaterException.unlocated("Bad date pattern");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.preproc.Defines;
|
import net.sourceforge.plantuml.preproc.Defines;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
@ -59,7 +60,7 @@ public class Dirpath extends SimpleReturnFunction {
|
|||||||
return nbArg == 0;
|
return nbArg == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return TValue.fromString("");
|
return TValue.fromString("");
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.OptionFlags;
|
import net.sourceforge.plantuml.OptionFlags;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
@ -54,7 +55,7 @@ public class FileExists extends SimpleReturnFunction {
|
|||||||
return nbArg == 1;
|
return nbArg == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
if (OptionFlags.ALLOW_INCLUDE == false) {
|
if (OptionFlags.ALLOW_INCLUDE == false) {
|
||||||
return TValue.fromBoolean(false);
|
return TValue.fromBoolean(false);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.preproc.Defines;
|
import net.sourceforge.plantuml.preproc.Defines;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
@ -59,7 +60,7 @@ public class Filename extends SimpleReturnFunction {
|
|||||||
return nbArg == 0;
|
return nbArg == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return TValue.fromString("");
|
return TValue.fromString("");
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
@ -52,7 +53,7 @@ public class FunctionExists extends SimpleReturnFunction {
|
|||||||
return nbArg == 1;
|
return nbArg == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
final String name = args.get(0).toString();
|
final String name = args.get(0).toString();
|
||||||
return TValue.fromBoolean(context.doesFunctionExist(name));
|
return TValue.fromBoolean(context.doesFunctionExist(name));
|
||||||
}
|
}
|
||||||
|
@ -36,11 +36,11 @@ package net.sourceforge.plantuml.tim.stdlib;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sourceforge.plantuml.LineLocation;
|
||||||
import net.sourceforge.plantuml.tim.EaterException;
|
import net.sourceforge.plantuml.tim.EaterException;
|
||||||
import net.sourceforge.plantuml.tim.TContext;
|
import net.sourceforge.plantuml.tim.TContext;
|
||||||
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
import net.sourceforge.plantuml.tim.TFunctionSignature;
|
||||||
import net.sourceforge.plantuml.tim.TMemory;
|
import net.sourceforge.plantuml.tim.TMemory;
|
||||||
import net.sourceforge.plantuml.tim.TVariable;
|
|
||||||
import net.sourceforge.plantuml.tim.expression.TValue;
|
import net.sourceforge.plantuml.tim.expression.TValue;
|
||||||
|
|
||||||
public class GetVariableValue extends SimpleReturnFunction {
|
public class GetVariableValue extends SimpleReturnFunction {
|
||||||
@ -53,13 +53,13 @@ public class GetVariableValue extends SimpleReturnFunction {
|
|||||||
return nbArg == 1;
|
return nbArg == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue executeReturn(TContext context, TMemory memory, List<TValue> args) throws EaterException {
|
public TValue executeReturn(TContext context, TMemory memory, LineLocation location, List<TValue> args) throws EaterException {
|
||||||
final String name = args.get(0).toString();
|
final String name = args.get(0).toString();
|
||||||
final TVariable variable = memory.getVariable(name);
|
final TValue variable = memory.getVariable(name);
|
||||||
if (variable == null) {
|
if (variable == null) {
|
||||||
return TValue.fromString("");
|
return TValue.fromString("");
|
||||||
}
|
}
|
||||||
return variable.getValue();
|
return variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user