aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java
blob: 3f135de9ec1b57e0c3ca06ff25dcd603c2f70162 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package org.zwobble.couscous.backends;

import com.google.common.base.Strings;
import org.zwobble.couscous.util.Action;

public class SourceCodeWriter {
    public interface WriterAction {
        void run(SourceCodeWriter writer);
    }

    private static final int SPACES_PER_INDENT = 4;
    private final StringBuilder builder = new StringBuilder();

    private final WriterAction blockStart;
    private final WriterAction blockEnd;
    private int depth = 0;

    public SourceCodeWriter(WriterAction blockStart, WriterAction blockEnd) {
        this.blockStart = blockStart;
        this.blockEnd = blockEnd;
    }
    
    public String asString() {
        return builder.toString();
    }

    public void writeInteger(int value) {
        builder.append(value);
    }

    public void writeStringLiteral(String value) {
        builder.append("\"");
        builder.append(value
            .replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\n", "\\n")
            .replace("\r", "\\r")
            .replace("\t", "\\t"));
        builder.append("\"");
    }

    public void writeKeyword(String keyword) {
        builder.append(keyword);
    }

    public void writeSpace() {
        builder.append(" ");
    }

    public void writeIdentifier(String name) {
        builder.append(name);
    }

    public void writeSymbol(String symbol) {
        builder.append(symbol);
    }

    public void startBlock() {
        runAction(blockStart);
        depth++;
        builder.append("\n");
    }

    public void endBlock() {
        depth--;
        runAction(blockEnd);
    }

    public void writeStatement(Action action) {
        startStatement();
        action.run();
        endStatement();
    }

    private void startStatement() {
        builder.append(Strings.repeat(" ", depth * SPACES_PER_INDENT));
    }

    private void endStatement() {
        if (builder.charAt(builder.length() - 1) != '\n') {
            builder.append("\n");   
        }
    }

    private void runAction(WriterAction action) {
        action.run(this);
    }
}