/*\ * LBPP - A GNU Compiler Compiler (GCC) Liberty Basic Frontend * Copyright (C) 2001 Anthony Liguori * * LBPP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * LBPP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*/ #include #include #include #include "lbpp.h" int current_line = 0; int check_assignment(char *buf) { char *ptr = skip_symbol(buf); ptr = skip_space(ptr); ptr = skip_param(ptr); ptr = skip_space(ptr); return (*ptr == '='); } char *skip_param(char *buf) { char *ptr = buf; if (*ptr == '(') { Type type = UNKNOWN; ptr = skip_space(++ptr); peek_expr(ptr, &type); if (type == DOUBLE) { ptr = skip_expr(ptr); } else if (type == STRING) { ptr = skip_string(ptr); } else if (type == HANDLE) { ptr = skip_symbol(ptr + 1); } ptr = skip_space(ptr); while (*ptr == ',') { ptr = skip_space(++ptr); type = UNKNOWN; peek_expr(ptr, &type); if (type == DOUBLE) { ptr = skip_expr(ptr); } else if (type == STRING) { ptr = skip_string(ptr); } else if (type == HANDLE) { ptr = skip_symbol(ptr + 1); } ptr = skip_space(ptr); } if (*ptr == ')') { ptr++; } ptr = skip_space(ptr); } return ptr; } char *skip_expr(char *buf) { char *ptr = buf; int done = 0; while (done == 0) { switch (*ptr) { case '(': ptr = skip_expr(++ptr); if (*ptr == ')') { ptr++; } break; default: if (isalpha(*ptr)) { ptr = skip_symbol(ptr); ptr = skip_space(ptr); ptr = skip_param(ptr); } else if(isdigit(*ptr) || (*ptr == '-' && isdigit(*(ptr+1)))) { ptr = skip_symbol(ptr); } else { done = 1; } break; } ptr = skip_space(ptr); switch (*ptr) { case '+': case '-': case '/': case '*': case '\\': ptr = skip_space(++ptr); break; default: done = 1; break; } } return ptr; } int get_line(char *buf, int size, FILE *f) { int position = 0; int need_line = 1; char *ret = 0; while (need_line && (ret = fgets(&buf[position], size - position, f))) { char *end = ret + strlen(ret) - 1; need_line = 0; if (*end == '\n') { *end = 0; if (end > ret && *(end - 1) == '\r') { *(--end) = 0; } } if ((end > ret) && (*(end - 1) == '_')) { need_line = 1; position = (end - buf) - 1; assert((size - position) > 0); } current_line++; } return (ret != 0); } char *skip_space(char *buf) { char *ret = buf; while (*ret && isspace(*ret)) ret++; return ret; } char *skip_symbol(char *buf) { char *ret = buf; if (((*ret == '-') && isdigit(ret[1])) || (*ret == '#')) { ret++; } while (*ret && (isalnum(*ret) || *ret == '.')) ret++; if (*ret == '$') ret++; return ret; } char *skip_string(char *buf) { char *ret = buf; do { if (*ret == '+') { ret = skip_space(++ret); } if (*ret == '\"') { ret = skip_string_lit(ret); } else { ret = skip_symbol(ret); ret = skip_space(ret); ret = skip_param(ret); } ret = skip_space(ret); } while (*ret == '+'); return ret; } char *skip_string_lit(char *buf) { char *ret = buf; while (*ret && *(++ret) != '\"'); if (*ret == '\"') { ret++; } return ret; } char *skip_bool_t(char *buf, Type type) { char *ptr = buf; int more = 0; do { if (*ptr == '(') { ptr = skip_bool_t(skip_space(ptr + 1), type); assert(*ptr == ')'); ptr++; } else { if (type == UNKNOWN) { peek_expr(ptr, &type); } if (type == DOUBLE) { ptr = skip_expr(ptr); } else if (type == STRING) { ptr = skip_string(ptr); } } more = 1; switch (*ptr) { case '>': if (*(++ptr) == '=') { ptr++; } break; case '<': if ((*(++ptr) == '=') || (*ptr == '>')) { ptr++; } break; case '=': ptr++; break; default: { char *end = skip_symbol(ptr); if (!strncasecmp(ptr, "and", 3) && ((end - ptr) == 3)) { ptr += 3; type = UNKNOWN; } else if (!strncasecmp(ptr, "or", 2) && ((end - ptr) == 2)) { ptr += 2; } else { more = 0; type = UNKNOWN; } } break; } ptr = skip_space(ptr); } while (more); return ptr; } void peek_expr(char *buf, Type *type) { int i; if (*buf == '(') { peek_expr(skip_space(buf + 1), type); } else if (*buf == '\"') { *type = STRING; } else if (*buf == '#') { *type = HANDLE; } else if (isdigit(*buf) || (*buf == '-' && isdigit(buf[1]))) { *type = DOUBLE; } else if ((i = lookup_function(buf)) != -1) { *type = function_table[i].type; } else if ((i = lookup_variable(buf)) != -1) { *type = var_table[i].type; } else if ((i = add_variable(buf)) != -1) { *type = var_table[i].type; } } char *skip_bool(char *buf) { Type type; peek_expr(buf, &type); return skip_bool_t(buf, type); } char *skip_vararg(char *buf) { char *ptr = buf; Type type = UNKNOWN; do { if ((*ptr == ';') || (*ptr == ',')) { ptr++; ptr = skip_space(ptr); } peek_expr(ptr, &type); if (type == STRING) { ptr = skip_string(ptr); } else if (type == DOUBLE) { ptr = skip_expr(ptr); } ptr = skip_space(ptr); } while (type != UNKNOWN && ((*ptr == ';') || (*ptr == ','))); return ptr; }