[Libre-soc-bugs] [Bug 980] Implement C-based Power ISA pseudocode compiler

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Sun Jan 14 23:18:42 GMT 2024


https://bugs.libre-soc.org/show_bug.cgi?id=980

--- Comment #111 from Jacob Lifshay <programmerjake at gmail.com> ---
(In reply to Jacob Lifshay from comment #98)
for adding strings, since there are only string constants, we can add them like
so:

typedef enum oppc_type_tag {
    oppc_tt_sel_int,
    oppc_tt_str,
    // add more stuff later
} oppc_type_tag;

typedef enum oppc_str {
    // for every string constant, add an entry here
    oppc_str_abc, // "abc"
    oppc_str_foo, // "foo"
    oppc_str_bar, // "bar"
} oppc_str;

// for debugging and other places you need the actual text
const char * const oppc_strings[] = {
    // for every string constant, add an entry here
    [(int)oppc_str_abc] = "abc",
    [(int)oppc_str_foo] = "foo",
    [(int)oppc_str_bar] = "bar",
};

typedef struct oppc_value {
    oppc_type_tag type : 4;
    bool ok : 1;
    : 0; // terminate bitfield
    union {
        oppc_sel_int si;
        oppc_str str;
        // add more stuff later
    };
} oppc_value;

in python, you'd generate this by having a hard-coded list of all string
constants (since you're not always parsing everything and you need to emit
consistent type definitions or that's a ODR violation -- aka. UB):

all_strings = (
    "abc",
    "foo",
    "bar",
)

def make_oppc_str_enumerant(v):
    name = ["oppc_str_"]
    # escape string into unambiguous C identifier
    for ch in v:
        if ch.isascii() and ch.isalnum():
            name.append(ch)
        elif ch == "_":
            # 2 underlines to not confuse with escaped char
            name.append("__")
        else:
            name.append("_%x_" % (ord(ch),))
    return "".join(name)

def translate_str_lit(v):
    assert f in all_strings, "%r is not in all_strings" % (v,)
    return "(oppc_value){.type = oppc_tt_str, .ok = true, .str = %s}" % (
        make_oppc_str_enumerant(v),)

def c_str(v):
    v = v.replace("\\", "\\\\")
    v = v.replace("\n", "\\n")
    v = v.replace("\t", "\\t")
    v = v.replace("\"", "\\"")
    return '"' + v + '"'

def create_oppc_str_definition():
    yield "typedef enum oppc_str {"
    for i in all_strings:
        yield "    %s, // %s" % (make_oppc_str_enumerant(i), c_str(i))
    yield "} oppc_str;"
    yield ""
    yield "// for debugging and other places you need the actual text"
    yield "const char * const oppc_strings[] = {"
    for i in all_strings:
        yield "    [(int)%s] = %s," % (make_oppc_str_enumerant(i), c_str(i))
    yield "};"

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the libre-soc-bugs mailing list