/* $Header$ */ /* Language dependant support; this one is default */ #include #include #include "position.h" #include "class.h" #include "langdep.h" #include "Lpars.h" #include "idf.h" #include "token.h" #include "expr.h" #include "tree.h" #include "operator.h" extern FILE *db_out, *db_in; extern int get_name(); extern double atof(); static int print_string(), get_number(), get_string(), get_token(), print_op(), op_prio(); static long array_elsize(); static struct langdep def = { 0, "%ld", "0%lo", "0x%lX", "%lu", "0x%lX", "%g", "'\\%o'", "[", "]", "(", ")", "{", "}", print_string, array_elsize, op_prio, get_string, get_name, get_number, get_token, print_op }; struct langdep *def_dep = &def; static int print_string(s, len) char *s; int len; { register char *str = s; int delim = '\''; while (*str) { if (*str++ == '\'') delim = '"'; } fprintf(db_out, "%c%.*s%c", delim, len, s, delim); } extern long int_size; static long array_elsize(size) long size; { if (! (int_size % size)) return size; if (! (size % int_size)) return size; return ((size + int_size - 1) / int_size) * int_size; } /*ARGSUSED*/ static int op_prio(op) int op; { return 1; } static int val_in_base(c, base) register int c; { return is_dig(c) ? c - '0' : base != 16 ? -1 : is_hex(c) ? (c - 'a' + 10) & 017 : -1; } static int get_number(c) register int c; { char buf[512+1]; register int base = 10; register char *p = &buf[0]; register long val = 0; register int val_c; if (c == '0') { /* check if next char is an 'x' or an 'X' */ c = getc(db_in); if (c == 'x' || c == 'X') { base = 16; c = getc(db_in); } else base = 8; } while (val_c = val_in_base(c, base), val_c >= 0) { val = val * base + val_c; if (p - buf < 512) *p++ = c; c = getc(db_in); } if (base == 16 || !((c == '.' || c == 'e' || c == 'E'))) { ungetc(c, db_in); tok.ival = val; return INTEGER; } if (c == '.') { if (p - buf < 512) *p++ = c; c = getc(db_in); } while (is_dig(c)) { if (p - buf < 512) *p++ = c; c = getc(db_in); } if (c == 'e' || c == 'E') { if (p - buf < 512) *p++ = c; c = getc(db_in); if (c == '+' || c == '-') { if (p - buf < 512) *p++ = c; c = getc(db_in); } if (! is_dig(c)) { error("malformed floating constant"); } while (is_dig(c)) { if (p - buf < 512) *p++ = c; c = getc(db_in); } } ungetc(c, db_in); *p++ = 0; if (p == &buf[512+1]) { error("floating point constant too long"); } tok.fval = atof(buf); return REAL; } static int get_token(c) register int c; { switch(c) { case '`': case ':': case ',': return c; case '.': return get_number(c); default: error("illegal character 0%o", c); return LLlex(); } } static int quoted(ch) int ch; { /* quoted() replaces an escaped character sequence by the character meant. */ /* first char after backslash already in ch */ if (!is_oct(ch)) { /* a quoted char */ switch (ch) { case 'n': ch = '\n'; break; case 't': ch = '\t'; break; case 'b': ch = '\b'; break; case 'r': ch = '\r'; break; case 'f': ch = '\f'; break; } } else { /* a quoted octal */ register int oct = 0, cnt = 0; do { oct = oct*8 + (ch-'0'); ch = getc(db_in); } while (is_oct(ch) && ++cnt < 3); ungetc(ch, db_in); ch = oct; } return ch&0377; } static int get_string(c) int c; { register int ch; char buf[512]; register int len = 0; while (ch = getc(db_in), ch != c) { if (ch == '\n') { error("newline in string"); break; } if (ch == '\\') { ch = getc(db_in); ch = quoted(ch); } buf[len++] = ch; } buf[len++] = 0; tok.str = Salloc(buf, (unsigned) len); return STRING; } static int print_op(p) p_tree p; { switch(p->t_oper) { case OP_UNOP: switch(p->t_whichoper) { case E_MIN: fputs("-", db_out); print_node(p->t_args[0], 0); break; case E_PLUS: fputs("+", db_out); print_node(p->t_args[0], 0); break; case E_NOT: fputs("~", db_out); print_node(p->t_args[0], 0); break; case E_DEREF: fputs("*", db_out); print_node(p->t_args[0], 0); break; } break; case OP_BINOP: fputs("(", db_out); print_node(p->t_args[0], 0); switch(p->t_whichoper) { case E_AND: fputs("&&", db_out); break; case E_OR: fputs("||", db_out); break; case E_ZDIV: fputs("/", db_out); break; case E_ZMOD: fputs("%", db_out); break; case E_DIV: fputs(" div ", db_out); break; case E_MOD: fputs(" mod ", db_out); break; case E_IN: fputs(" in ", db_out); break; case E_PLUS: fputs("+", db_out); break; case E_MIN: fputs("-", db_out); break; case E_MUL: fputs("*", db_out); break; case E_EQUAL: fputs("==", db_out); break; case E_NOTEQUAL: fputs("!=", db_out); break; case E_LTEQUAL: fputs("<=", db_out); break; case E_GTEQUAL: fputs(">=", db_out); break; case E_LT: fputs("<", db_out); break; case E_GT: fputs(">", db_out); break; case E_SELECT: fputs(".", db_out); break; } print_node(p->t_args[1], 0); fputs(")", db_out); break; } }