package scotch.compiler.parser; import static scotch.symbol.Symbol.symbol; import static scotch.compiler.syntax.value.InitializerField.field; import java.util.ArrayDeque; import java.util.Deque; import scotch.compiler.syntax.util.SymbolGenerator; import scotch.compiler.syntax.builder.SyntaxBuilder; import scotch.compiler.syntax.value.ConstantValue; import scotch.compiler.syntax.value.Identifier; import scotch.compiler.syntax.value.Initializer; import scotch.compiler.syntax.value.Value; import scotch.compiler.text.SourceLocation; public class ListBuilder implements SyntaxBuilder<Value> { public static ListBuilder builder(SymbolGenerator generator) { return new ListBuilder(generator); } private final SymbolGenerator generator; private final Deque<Value> values; private ListBuilder(SymbolGenerator generator) { this.generator = generator; this.values = new ArrayDeque<>(); } @Override public Value build() { Value tail = ConstantValue.builder() .withDataType(symbol("scotch.data.list.[]")) .withSymbol(symbol("scotch.data.list.[]")) .withType(generator.reserveType()) .withSourceLocation(values.peek().getSourceLocation().getEndPoint()) .build(); while (!values.isEmpty()) { Value head = values.pop(); Initializer.Builder builder = Initializer.builder() .withSourceLocation(head.getSourceLocation().extend(tail.getSourceLocation())) .withType(generator.reserveType()) .withValue(Identifier.builder() .withType(generator.reserveType()) .withSourceLocation(head.getSourceLocation().getStartPoint()) .withSymbol(symbol("scotch.data.list.(:)")) .build()); builder.addField(field(head.getSourceLocation(), "_0", head)); builder.addField(field(tail.getSourceLocation(), "_1", tail)); tail = builder.build(); } return tail; } @Override public ListBuilder withSourceLocation(SourceLocation sourceLocation) { // noop return this; } public ListBuilder addValue(Value value) { values.push(value); return this; } }