// File: /workspace/github_c_makefile_star2_O0/simh[P]simtools/crossassemblers/macro11/parse.c
// Function: parse_unary
EX_TREE        *parse_unary(
    char *cp)
{
    EX_TREE        *tp;

    /* Skip leading whitespace */
    cp = skipwhite(cp);

    if (*cp == '%') {                  /* Register notation */
        unsigned        reg;

        cp++;
        reg = strtoul(cp, &cp, 8);
        if (reg > 7)
            return ex_err(NULL, cp);

        /* This returns references to the built-in register symbols */
        tp = new_ex_tree();
        tp->type = EX_SYM;
        tp->data.symbol = reg_sym[reg];
        tp->cp = cp;
        return tp;
    }

    /* Unary negate */
    if (*cp == '-') {
        tp = new_ex_tree();
        tp->type = EX_NEG;
        tp->data.child.left = parse_unary(cp + 1);
        tp->cp = tp->data.child.left->cp;
        return tp;
    }

    /* Unary + I can ignore. */
    if (*cp == '+')
        return parse_unary(cp + 1);

    if (*cp == '^') {
        int             save_radix;

        switch (tolower((unsigned char)cp[1])) {
        case 'c':
            /* ^C, ones complement */
            tp = new_ex_tree();
            tp->type = EX_COM;
            tp->data.child.left = parse_unary(cp + 2);
            tp->cp = tp->data.child.left->cp;
            return tp;
        case 'b':
            /* ^B, binary radix modifier */
            save_radix = radix;
            radix = 2;
            tp = parse_unary(cp + 2);
            radix = save_radix;
            return tp;
        case 'o':
            /* ^O, octal radix modifier */
            save_radix = radix;
            radix = 8;
            tp = parse_unary(cp + 2);
            radix = save_radix;
            return tp;
        case 'd':
            /* ^D, decimal radix modifier */
            save_radix = radix;
            radix = 10;
            tp = parse_unary(cp + 2);
            radix = save_radix;
            return tp;
        case 'x':
            /* ^X, hexadecimal radix modifier */
            save_radix = radix;
            radix = 16;
            tp = parse_unary(cp + 2);
            radix = save_radix;
            return tp;
        case 'r':
            /* ^R, RAD50 literal */  {
                int             start,
                                len;
                char           *endcp;
                unsigned        value;

                cp += 2; /* bracketed range is an extension */
                if (brackrange(cp, &start, &len, &endcp))
                    value = rad50(cp + start, NULL);
                else
                    value = rad50(cp, &endcp);
                tp = new_ex_lit(value);
                tp->cp = endcp;
                return tp;
            }
        case 'f':
            /* ^F, single-word floating point literal indicator */  {
                unsigned        flt[1];
                char           *endcp;

                if (!parse_float(cp + 2, &endcp, 1, flt)) {
                    tp = ex_err(NULL, cp + 2);
                } else {
                    tp = new_ex_lit(flt[0]);
                    tp->cp = endcp;
                }
                return tp;
            }
        }

        if (ispunct((unsigned char)cp[1])) {
            char           *ecp;

            /* oddly-bracketed expression like this: ^/expression/ */
            tp = parse_binary(cp + 2, cp[1], 0);
            ecp = skipwhite(tp->cp);

            if (*ecp != cp[1])
                return ex_err(tp, ecp);

            tp->cp = ecp + 1;
            return tp;
        }
    }

    /* Bracketed subexpression */
    if (*cp == '<') {
        char           *ecp;

        tp = parse_binary(cp + 1, '>', 0);
        ecp = skipwhite(tp->cp);
        if (*ecp != '>')
            return ex_err(tp, ecp);

        tp->cp = ecp + 1;
        return tp;
    }

    /* Check for ASCII constants */

    if (*cp == '\'') {
        /* 'x single ASCII character */
        cp++;
        tp = new_ex_lit(*cp & 0xff);
        tp->cp = ++cp;
        return tp;
    }

    if (*cp == '\"') {
        /* "xx ASCII character pair */
        cp++;
        tp = new_ex_lit((cp[0] & 0xff) | ((cp[1] & 0xff) << 8));
        tp->cp = cp + 2;
        return tp;
    }

    /* Numeric constants are trickier than they need to be, */
    /* since local labels start with a digit too. */
    if (isdigit((unsigned char)*cp)) {
        char           *label;
        int             local;

        if ((label = get_symbol(cp, NULL, &local)) == NULL) {
            char           *endcp;
            unsigned long   value;
            int             rad = radix;

            /* get_symbol returning NULL assures me that it's not a
               local label.  */

            /* Look for a trailing period, to indicate decimal... */
            for (endcp = cp; isdigit((unsigned char)*endcp); endcp++) ;
            if (*endcp == '.')
                rad = 10;

            value = strtoul(cp, &endcp, rad);
            if (*endcp == '.')
                endcp++;

            tp = new_ex_lit(value);
            tp->cp = endcp;

            return tp;
        }

        free(label);
    }

    /* Now check for a symbol */
    {
        char           *label;
        int             local;
        SYMBOL         *sym;

        /* Optimization opportunity: I don't really need to call
           get_symbol a second time. */

        if (!(label = get_symbol(cp, &cp, &local))) {
            cp++;                      /*JH: eat first char of illegal label, else endless loop on implied .WORD */
            tp = ex_err(NULL, cp);     /* Not a valid label. */
            return tp;
        }

        sym = lookup_sym(label, &symbol_st);
        if (sym == NULL) {
            /* A symbol from the "PST", which means an instruction
               code. */
            sym = lookup_sym(label, &system_st);
        }

        if (sym != NULL) {
            tp = new_ex_tree();
            tp->cp = cp;
            tp->type = EX_SYM;
            tp->data.symbol = sym;

            free(label);
            return tp;
        }

        /* The symbol was not found. Create an "undefined symbol"
           reference. */
        sym = memcheck(malloc(sizeof(SYMBOL)));
        sym->label = label;
        sym->flags = SYMBOLFLAG_UNDEFINED | local;
        sym->stmtno = stmtno;
        sym->next = NULL;
        sym->section = &absolute_section;
        sym->value = 0;

        tp = new_ex_tree();
        tp->cp = cp;
        tp->type = EX_UNDEFINED_SYM;
        tp->data.symbol = sym;

        return tp;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0xb9e0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x25, %eax
jne 0xcddd
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x10(%rbp), %rsi
movl $0x8, %edx
callq 0x2280
movl %eax, -0x1c(%rbp)
cmpl $0x7, -0x1c(%rbp)
jbe 0xcd99
movq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0xa450
movq %rax, -0x8(%rbp)
jmp 0xd4f1
callq 0x9600
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl $0x2, (%rax)
movl -0x1c(%rbp), %eax
movl %eax, %ecx
leaq 0x128e8(%rip), %rax     # 0x1f6a0
movq (%rax,%rcx,8), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0xce35
callq 0x9600
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl $0x6, (%rax)
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
callq 0xcd30
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2b, %eax
jne 0xce57
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
callq 0xcd30
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x5e, %eax
jne 0xd15a
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %edi
callq 0x2210
addl $-0x62, %eax
movl %eax, %ecx
movq %rcx, -0x98(%rbp)
subl $0x16, %eax
ja 0xd0c7
movq -0x98(%rbp), %rax
leaq 0x8805(%rip), %rcx      # 0x1569c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
callq 0x9600
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl $0x5, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
callq 0xcd30
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
leaq 0xc29d(%rip), %rax      # 0x19190
movl (%rax), %eax
movl %eax, -0x20(%rbp)
leaq 0xc291(%rip), %rax      # 0x19190
movl $0x2, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
callq 0xcd30
movq %rax, -0x18(%rbp)
movl -0x20(%rbp), %ecx
leaq 0xc270(%rip), %rax      # 0x19190
movl %ecx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
leaq 0xc25a(%rip), %rax      # 0x19190
movl (%rax), %eax
movl %eax, -0x20(%rbp)
leaq 0xc24e(%rip), %rax      # 0x19190
movl $0x8, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
callq 0xcd30
movq %rax, -0x18(%rbp)
movl -0x20(%rbp), %ecx
leaq 0xc22d(%rip), %rax      # 0x19190
movl %ecx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
leaq 0xc217(%rip), %rax      # 0x19190
movl (%rax), %eax
movl %eax, -0x20(%rbp)
leaq 0xc20b(%rip), %rax      # 0x19190
movl $0xa, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
callq 0xcd30
movq %rax, -0x18(%rbp)
movl -0x20(%rbp), %ecx
leaq 0xc1ea(%rip), %rax      # 0x19190
movl %ecx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
leaq 0xc1d4(%rip), %rax      # 0x19190
movl (%rax), %eax
movl %eax, -0x20(%rbp)
leaq 0xc1c8(%rip), %rax      # 0x19190
movl $0x10, (%rax)
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
callq 0xcd30
movq %rax, -0x18(%rbp)
movl -0x20(%rbp), %ecx
leaq 0xc1a7(%rip), %rax      # 0x19190
movl %ecx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x24(%rbp), %rsi
leaq -0x28(%rbp), %rdx
leaq -0x30(%rbp), %rcx
callq 0xbb80
cmpl $0x0, %eax
je 0xd037
movq -0x10(%rbp), %rdi
movslq -0x24(%rbp), %rax
addq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13990
movl %eax, -0x34(%rbp)
jmp 0xd047
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x13990
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %edi
callq 0xa3c0
movq %rax, -0x18(%rbp)
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
leaq -0x38(%rbp), %rcx
leaq -0x40(%rbp), %rsi
movl $0x1, %edx
callq 0xc810
cmpl $0x0, %eax
jne 0xd0a2
movq -0x10(%rbp), %rsi
addq $0x2, %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0xa450
movq %rax, -0x18(%rbp)
jmp 0xd0ba
movl -0x38(%rbp), %edi
callq 0xa3c0
movq %rax, -0x18(%rbp)
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
callq 0x22e0
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0xd158
movq -0x10(%rbp), %rdi
addq $0x2, %rdi
movq -0x10(%rbp), %rax
xorl %edx, %edx
movsbl 0x1(%rax), %esi
callq 0xca40
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movsbl (%rax), %eax
movq -0x10(%rbp), %rcx
movsbl 0x1(%rcx), %ecx
cmpl %ecx, %eax
je 0xd13b
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xa450
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x48(%rbp), %rcx
addq $0x1, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
jmp 0xd15a
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3c, %eax
jne 0xd1ce
movq -0x10(%rbp), %rdi
addq $0x1, %rdi
movl $0x3e, %esi
xorl %edx, %edx
callq 0xca40
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb9e0
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
je 0xd1b1
movq -0x18(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0xa450
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x50(%rbp), %rcx
addq $0x1, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x27, %eax
jne 0xd21d
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %edi
andl $0xff, %edi
callq 0xa3c0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
addq $0x1, %rcx
movq %rcx, -0x10(%rbp)
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x22, %eax
jne 0xd27a
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl (%rax), %edi
andl $0xff, %edi
movq -0x10(%rbp), %rax
movsbl 0x1(%rax), %eax
andl $0xff, %eax
shll $0x8, %eax
orl %eax, %edi
callq 0xa3c0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
addq $0x2, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
callq 0x22e0
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movzbl (%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0xd371
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
leaq -0x5c(%rbp), %rdx
callq 0xbf60
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
jne 0xd368
leaq 0xbecc(%rip), %rax      # 0x19190
movl (%rax), %eax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
callq 0x22e0
movq (%rax), %rax
movq -0x68(%rbp), %rcx
movzbl (%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0xd301
jmp 0xd2f3
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0xd2d1
movq -0x68(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2e, %eax
jne 0xd314
movl $0xa, -0x74(%rbp)
movq -0x10(%rbp), %rdi
movl -0x74(%rbp), %edx
leaq -0x68(%rbp), %rsi
callq 0x2280
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2e, %eax
jne 0xd340
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
movq -0x70(%rbp), %rax
movl %eax, %edi
callq 0xa3c0
movq %rax, -0x18(%rbp)
movq -0x68(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x58(%rbp), %rdi
callq 0x2040
movq -0x10(%rbp), %rdi
leaq -0x10(%rbp), %rsi
leaq -0x84(%rbp), %rdx
callq 0xbf60
movq %rax, -0x80(%rbp)
cmpq $0x0, %rax
jne 0xd3b9
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0xa450
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movq -0x80(%rbp), %rdi
leaq 0xe2ec(%rip), %rsi      # 0x1b6b0
callq 0xe040
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0xd3f1
movq -0x80(%rbp), %rdi
leaq 0x102c3(%rip), %rsi     # 0x1d6a8
callq 0xe040
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
je 0xd43f
callq 0x9600
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movl $0x2, (%rax)
movq -0x90(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x80(%rbp), %rdi
callq 0x2040
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd4f1
movl $0x28, %edi
callq 0x2220
movq %rax, %rdi
callq 0x136a0
movq %rax, -0x90(%rbp)
movq -0x80(%rbp), %rcx
movq -0x90(%rbp), %rax
movq %rcx, (%rax)
movl -0x84(%rbp), %ecx
orl $0x10, %ecx
movq -0x90(%rbp), %rax
movl %ecx, 0x10(%rax)
leaq 0xc704(%rip), %rax      # 0x19b84
movl (%rax), %ecx
movq -0x90(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x90(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x90(%rbp), %rax
leaq 0xbd77(%rip), %rcx      # 0x19220
movq %rcx, 0x18(%rax)
movq -0x90(%rbp), %rax
movl $0x0, 0x8(%rax)
callq 0x9600
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movl $0x3, (%rax)
movq -0x90(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nop