aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioStrings.java
blob: d9e27190a4498af1b0dd591544d0e01285c53038 (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
89
package org.shedlang.compiler.shidtopatio;

import org.shedlang.compiler.patio.PatioDataElementImmutableDefinition;
import org.shedlang.compiler.patio.PatioFunctionDeclaration;
import org.shedlang.compiler.patio.PatioLocal;
import org.shedlang.compiler.patio.PatioVisibility;
import org.shedlang.compiler.patio.instructions.PatioCall;
import org.shedlang.compiler.patio.operands.PatioDataPtrConst;
import org.shedlang.compiler.patio.operands.PatioLocalRef;
import org.shedlang.compiler.patio.operands.PatioOperand;
import org.shedlang.compiler.patio.types.PatioDataLayouts;
import org.shedlang.compiler.patio.types.PatioDataValue;
import org.shedlang.compiler.patio.types.PatioDataValues;
import org.shedlang.compiler.patio.values.PatioDataPtrValueDataElement;
import org.shedlang.compiler.sources.Source;
import org.shedlang.compiler.sources.Sources;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class ShidToPatioStrings {
    public static final PatioFunctionDeclaration STRING_ADD_DECLARATION = new PatioFunctionDeclaration(
        "shed__runtime__string_add",
        List.of(
            PatioLocal.param("left", ShidToPatioTypes.VALUE_TYPE),
            PatioLocal.param("right", ShidToPatioTypes.VALUE_TYPE)
        ),
        List.of(ShidToPatioTypes.VALUE_TYPE),
        Sources.RUNTIME
    );

    private ShidToPatioStrings() {}

    public static ShidToPatioResult<PatioDataPtrConst> define(
        String value,
        Source source,
        ShidToPatioContext context
    ) {
        var codeUnits = value.getBytes(StandardCharsets.UTF_8);

        var codeUnitsDataValues = new ArrayList<PatioDataValue>();
        for (var codeUnit : codeUnits) {
            codeUnitsDataValues.add(PatioDataValues.byte_(codeUnit));
        }

        var dataValue = ShidToPatioGc.gcObjectStaticDataValue(PatioDataValues.struct(List.of(
            PatioDataValues.int_(codeUnits.length),
            PatioDataValues.array(PatioDataLayouts.BYTE, codeUnitsDataValues)
        )));

        var elementNameResult = context.allocateCompilationUnitElementName(
            ShidToPatioCompilationUnitElementSpace.STRING
        );
        var elementName = elementNameResult.value();
        context = elementNameResult.context();

        context = context.addCompilationUnitElement(new PatioDataElementImmutableDefinition(
            elementName,
            PatioVisibility.PRIVATE,
            dataValue,
            source
        ));

        return context.toResult(new PatioDataPtrConst(
            new PatioDataPtrValueDataElement(elementName)
        ));
    }

    public static ShidToPatioContext add(
        PatioLocalRef destination,
        PatioOperand left,
        PatioOperand right,
        Source source,
        ShidToPatioContext context
    ) {
        context = context.ensureCompilationUnitElement(STRING_ADD_DECLARATION);

        context = context.addInstruction(new PatioCall(
            List.of(destination),
            STRING_ADD_DECLARATION.name(),
            List.of(left, right),
            source
        ));

        return context;
    }
}