Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4758ff1 authored by Jack Palevich's avatar Jack Palevich
Browse files

Implement string and character backslash constants.

Until now we only supported '\n'. Now we support everything, including
octal ('\033') and hex '\x27' constants.
parent 2ccc40d0
Loading
Loading
Loading
Loading
+97 −16
Original line number Diff line number Diff line
@@ -1841,14 +1841,93 @@ class Compiler : public ErrorSink {
        return isalnum(ch) | (ch == '_');
    }

    /* read a character constant */
    void getq() {
    /* read a character constant, advances ch to after end of constant */
    int getq() {
        int val = ch;
        if (ch == '\\') {
            inp();
            if (ch == 'n')
                ch = '\n';
            if (isoctal(ch)) {
                // 1 to 3 octal characters.
                val = 0;
                for(int i = 0; i < 3; i++) {
                    if (isoctal(ch)) {
                        val = (val << 3) + ch - '0';
                        inp();
                    }
                }
                return val;
            } else if (ch == 'x' || ch == 'X') {
                // N hex chars
                inp();
                if (! isxdigit(ch)) {
                    error("'x' character escape requires at least one digit.");
                } else {
                    val = 0;
                    while (isxdigit(ch)) {
                        int d = ch;
                        if (isdigit(d)) {
                            d -= '0';
                        } else if (d <= 'F') {
                            d = d - 'A' + 10;
                        } else {
                            d = d - 'a' + 10;
                        }
                        val = (val << 4) + d;
                        inp();
                    }
                }
            } else {
                int val = ch;
                switch (ch) {
                    case 'a':
                        val = '\a';
                        break;
                    case 'b':
                        val = '\b';
                        break;
                    case 'f':
                        val = '\f';
                        break;
                    case 'n':
                        val = '\n';
                        break;
                    case 'r':
                        val = '\r';
                        break;
                    case 't':
                        val = '\t';
                        break;
                    case 'v':
                        val = '\v';
                        break;
                    case '\\':
                        val = '\\';
                        break;
                    case '\'':
                        val = '\'';
                        break;
                    case '"':
                        val = '"';
                        break;
                    case '?':
                        val = '?';
                        break;
                    default:
                        error("Undefined character escape %c", ch);
                        break;
                }
                inp();
                return val;
            }
        } else {
            inp();
        }
        return val;
    }

    static bool isoctal(int ch) {
        return ch >= '0' && ch <= '7';
    }

    void next() {
        int l, a;
@@ -1908,10 +1987,12 @@ class Compiler : public ErrorSink {
            inp();
            if (tok == '\'') {
                tok = TOK_NUM;
                getq();
                tokc = ch;
                inp();
                tokc = getq();
                if (ch != '\'') {
                    error("Expected a ' character, got %c", ch);
                } else {
                  inp();
                }
            } else if ((tok == '/') & (ch == '*')) {
                inp();
                while (ch) {
@@ -2071,14 +2152,14 @@ class Compiler : public ErrorSink {
        int c;
        String tString;
        t = 0;
        n = 1; /* type of expression 0 = forward, 1 = value, other =
         lvalue */
        n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */
        if (tok == '\"') {
            pGen->li((int) glo);
            while (ch != '\"') {
                getq();
                *allocGlobalSpace(1) = ch;
                inp();
            while (ch != '\"' && ch != EOF) {
                *allocGlobalSpace(1) = getq();
            }
            if (ch != '\"') {
                error("Unterminated string constant.");
            }
            *glo = 0;
            /* align heap */
@@ -2176,7 +2257,7 @@ class Compiler : public ErrorSink {
            a = pGen->beginFunctionCallArguments();
            next();
            l = 0;
            while (tok != ')') {
            while (tok != ')' && tok != EOF) {
                expr();
                pGen->storeR0ToArg(l);
                if (tok == ',')
@@ -2184,7 +2265,7 @@ class Compiler : public ErrorSink {
                l = l + 4;
            }
            pGen->endFunctionCallArguments(a, l);
            next();
            skip(')');
            if (!n) {
                /* forward reference */
                t = t + 4;
+30 −0
Original line number Diff line number Diff line
#define FOO 0x10

int main() {
    printf("0 = %d\n", 0);
    printf("010 = %d\n", 010);
    printf("0x10 = %d\n", FOO);
    printf("'\\a' = %d\n", '\a');
    printf("'\\b' = %d\n", '\b');
    printf("'\\f' = %d\n", '\f');
    printf("'\\n' = %d\n", '\n');
    printf("'\\r' = %d\n", '\r');
    printf("'\\t' = %d\n", '\t');
    printf("'\\v' = %d\n", '\v');
    // Undefined
    // printf("'\\z' = %d\n", '\z');
    printf("'\\\\' = %d\n", '\\');
    printf("'\\'' = %d\n", '\'');
    printf("'\\\"' = %d\n", '\"');
    printf("'\\?' = %d\n", '\?');
    printf("'\\0' = %d\n", '\0');
    printf("'\\1' = %d\n", '\1');
    printf("'\\12' = %d\n", '\12');
    printf("'\\123' = %d\n", '\123');
    printf("'\\x0' = %d\n", '\x0');
    printf("'\\x1' = %d\n", '\x1');
    printf("'\\x12' = %d\n", '\x12');
    printf("'\\x123' = %d\n", '\x123');
    printf("'\\x1f' = %d\n", '\x1f');
    printf("'\\x1F' = %d\n", '\x1F');
}