Sequence: Support nested and indirect lists for db / dw / dd.

Adds a sequence type for matching. Not used it in Expression getHead / getTail
yet because those are used in parameter matching where it doesn’t work yet.
M src/main/java/nl/grauw/glass/expressions/Expression.java +8 -2
@@ 95,8 95,14 @@ public abstract class Expression {
 		return list;
 	}
 
-	protected void addToList(List<Expression> list) {
-		list.add(this);
+	private void addToList(List<Expression> list) {
+		Expression tail = this;
+		while (tail.is(Type.SEQUENCE)) {
+			Expression sequence = tail.get(Type.SEQUENCE);
+			sequence.getHead().addToList(list);
+			tail = sequence.getTail();
+		}
+		list.add(tail);
 	}
 
 	public Expression getElement(int index) {

          
M src/main/java/nl/grauw/glass/expressions/Sequence.java +9 -9
@@ 1,7 1,5 @@ 
 package nl.grauw.glass.expressions;
 
-import java.util.List;
-
 public class Sequence extends BinaryOperator {
 
 	public Sequence(Expression head, Expression tail) {

          
@@ 24,13 22,15 @@ public class Sequence extends BinaryOper
 	}
 
 	@Override
-	protected void addToList(List<Expression> list) {
-		term1.addToList(list);
-		Expression tail = term2;
-		while (tail != null) {
-			tail.getHead().addToList(list);
-			tail = tail.getTail();
-		}
+	public boolean is(Type type) {
+		return type == Type.SEQUENCE;
+	}
+
+	@Override
+	public Expression get(Type type) {
+		if (type == Type.SEQUENCE)
+			return this;
+		return super.get(type);
 	}
 
 	@Override

          
M src/main/java/nl/grauw/glass/expressions/StringLiteral.java +10 -10
@@ 1,7 1,5 @@ 
 package nl.grauw.glass.expressions;
 
-import java.util.List;
-
 public class StringLiteral extends Literal {
 
 	private final String string;

          
@@ 21,7 19,9 @@ public class StringLiteral extends Liter
 
 	@Override
 	public boolean is(Type type) {
-		return type == Type.STRING || (type == Type.INTEGER && string.length() == 1);
+		return type == Type.STRING ||
+			(type == Type.INTEGER && string.length() == 1) ||
+			(type == Type.SEQUENCE && string.length() > 1);
 	}
 
 	@Override

          
@@ 29,16 29,16 @@ public class StringLiteral extends Liter
 		if (type == Type.STRING)
 			return this;
 		if (type == Type.INTEGER && string.length() == 1)
-			return IntegerLiteral.of(string.codePointAt(0));
+			return new CharacterLiteral(string.charAt(0));
+		if (type == Type.SEQUENCE && string.length() > 1) {
+			Expression tail = new CharacterLiteral(string.charAt(string.length() - 1));
+			for (int i = string.length() - 2; i >= 0; i--)
+				tail = new Sequence(new CharacterLiteral(string.charAt(i)), tail);
+			return tail;
+		}
 		return super.get(type);
 	}
 
-	@Override
-	protected void addToList(List<Expression> list) {
-		for (int i = 0, length = string.length(); i < length; i++)
-			list.add(new CharacterLiteral(string.charAt(i)));
-	}
-
 	public String toString() {
 		String escaped = string;
 		escaped = escaped.replace("\\", "\\\\");

          
M src/main/java/nl/grauw/glass/expressions/Type.java +1 -0
@@ 11,6 11,7 @@ public class Type {
 	public static final Type INSTRUCTION = new Type("Instruction");
 	public static final Type CONTEXT = new Type("Context");
 	public static final Type SECTIONCONTEXT = new Type("SectionContext");
+	public static final Type SEQUENCE = new Type("Sequence");
 
 	private String name;
 

          
M src/test/java/nl/grauw/glass/expressions/ExpressionTest.java +22 -1
@@ 2,6 2,8 @@ package nl.grauw.glass.expressions;
 
 import static org.junit.jupiter.api.Assertions.*;
 
+import java.util.List;
+
 import nl.grauw.glass.Line;
 import nl.grauw.glass.Parser;
 import nl.grauw.glass.Scope;

          
@@ 191,7 193,6 @@ public class ExpressionTest extends Test
 
 	@Test
 	public void testSequence() {
-		assertEquals(3, parse("4, 5, 6").getList().size());
 		assertEquals(4, parse("4, 5, 6").getElement(0).getInteger());
 		assertEquals(5, parse("4, 5, 6").getElement(1).getInteger());
 		assertEquals(6, parse("4, 5, 6").getElement(2).getInteger());

          
@@ 199,6 200,26 @@ public class ExpressionTest extends Test
 	}
 
 	@Test
+	public void testSequenceList() {
+		List<Expression> list = parse("4, 5, 6").getList();
+		assertEquals(3, list.size());
+		assertEquals(4, list.get(0).getInteger());
+		assertEquals(5, list.get(1).getInteger());
+		assertEquals(6, list.get(2).getInteger());
+	}
+
+	@Test
+	public void testSequenceListDeep() {
+		List<Expression> list = parse("4, (5, 6), (7, 8)").getList();
+		assertEquals(5, list.size());
+		assertEquals(4, list.get(0).getInteger());
+		assertEquals(5, list.get(1).getInteger());
+		assertEquals(6, list.get(2).getInteger());
+		assertEquals(7, list.get(3).getInteger());
+		assertEquals(8, list.get(4).getInteger());
+	}
+
+	@Test
 	public void testTernaryIfElse() {
 		assertEquals(2, parse("1 ? 2 : 3").getInteger());
 		assertEquals(3, parse("0 ? 2 : 3").getInteger());