/*\ * 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 #include "lbpp.h" Variable *var_table = 0; int var_table_capacity = 0; int var_table_size = 0; Label *label_table = 0; int label_table_capacity = 0; int label_table_size = 0; Statement *statement_table = 0; int statement_table_capacity = 0; int statement_table_size = 0; Function *function_table = 0; int function_table_capacity = 0; int function_table_size = 0; int add_variable(char *ptr) { Variable *ret = 0; char *name = ptr; char *end = 0; end = skip_symbol(name); if (end == name) { return (-1); } if (++var_table_size > var_table_capacity) { var_table_capacity = var_table_size + 10; var_table = (Variable *)realloc(var_table, var_table_capacity * sizeof(Variable)); } ret = &var_table[var_table_size - 1]; ret->name = (char *)malloc((end - name) + 1); memcpy(ret->name, name, (end - name)); ret->name[(end - name)] = 0; ret->rows = ret->columns = 1; if (ret->name[(end - name) - 1] == '$') { ret->type = STRING; } else if (ret->name[0] == '#') { ret->type = HANDLE; } else { ret->type = DOUBLE; } name = skip_space(end); if (*name == '(') { name = skip_space(++name); ret->rows = atoi(name); name = skip_symbol(name); name = skip_space(name); if (*name == ',') { name = skip_space(++name); ret->columns = atoi(name); } } return (var_table_size - 1); } int lookup_variable(char *name) { int i; int name_len = (skip_symbol(name) - name); for (i = 0; i < var_table_size; i++) if (!strncmp(name, var_table[i].name, name_len) && (name_len == strlen(var_table[i].name))) return i; return (-1); } int lookup_function(char *name) { int i; int name_len = (skip_symbol(name) - name); for (i = 0; i < function_table_size; i++) if (!strncasecmp(name, function_table[i].name, name_len) && (name_len == strlen(function_table[i].name))) { function_table[i].dirty = 1; return i; } return (-1); } int add_label(char *ptr) { Label *ret = 0; char *name = (*ptr) ? ptr + 1 : ptr; int size = 0; if (++label_table_size > label_table_capacity) { label_table_capacity = label_table_size + 10; label_table = (Label *)realloc(label_table, label_table_capacity * sizeof(Label)); } ret = &label_table[label_table_size - 1]; while (name[size] && name[size] != ']') size++; ret->name = (char *)malloc(size + 1); memcpy(ret->name, name, size); ret->name[size] = 0; return (label_table_size - 1); } int lookup_label(char *ptr) { char *name = (*ptr == '[') ? ptr + 1 : ptr; int i; int name_len = (strchr(name, ']') - name); for (i = 0; i < label_table_size; i++) if (!strncmp(name, label_table[i].name, name_len) && (name_len == strlen(label_table[i].name))) return i; return (-1); } int add_statement(char *buf) { Statement *ret = 0; char *ptr = buf; char *end; if (++statement_table_size > statement_table_capacity) { statement_table_capacity = statement_table_size + 10; statement_table = (Statement *)realloc(statement_table, statement_table_capacity * sizeof(Statement)); } ret = &statement_table[statement_table_size - 1]; end = skip_symbol(ptr); ret->name = malloc(end - ptr + 1); ret->arg = 0; ret->arg_size = 0; ret->dirty = 0; memcpy(ret->name, ptr, end - ptr); ret->name[end - ptr] = 0; ptr = skip_space(end); while (*ptr) { Arg *arg; ret->arg = realloc(ret->arg, ++(ret->arg_size) * sizeof(Arg)); arg = &(ret->arg[ret->arg_size - 1]); arg->literal = 0; arg->reference = 0; arg->arg.string = 0; if (*ptr == '\"') { end = strchr(++ptr, '\"'); arg->literal = 1; arg->arg.string = malloc(end - ptr + 1); memcpy(arg->arg.string, ptr, end - ptr); arg->arg.string[end - ptr] = 0; end++; } else { if (*ptr == '&') { arg->reference = 1; ptr++; } end = skip_symbol(ptr); if (!strncasecmp(ptr, "handle", end - ptr) && (end - ptr) == 6) { arg->arg.type = HANDLE; } else if (!strncasecmp(ptr, "double", end - ptr) && (end - ptr) == 6) { arg->arg.type = DOUBLE; } else if (!strncasecmp(ptr, "string", end - ptr) && (end - ptr) == 6) { arg->arg.type = STRING; } else if (!strncasecmp(ptr, "label", end - ptr) && (end - ptr) == 5) { arg->arg.type = LABEL; } else if (!strncasecmp(ptr, "keyword", end - ptr) && (end - ptr) == 7) { arg->arg.type = KEYWORD; } else if (!strncasecmp(ptr, "vararg", end - ptr) && (end - ptr) == 6) { arg->arg.type = VAR_ARG; } } ptr = skip_space(end); } return (statement_table_size - 1); } int add_function_decl(char *buf) { Function *ret = 0; char *ptr = buf; char *end; int size = 0; if (++function_table_size > function_table_capacity) { function_table_capacity = function_table_size + 10; function_table = (Function *)realloc(function_table, function_table_capacity * sizeof(Function)); } ret = &function_table[function_table_size - 1]; end = skip_symbol(ptr); size = end - ptr; ret->name = malloc(size + 1); ret->arg = 0; ret->dirty = 0; ret->arg_size = 0; memcpy(ret->name, ptr, size); ret->name[size] = 0; ptr = skip_space(end); if (ret->name[size - 1] == '$') { ret->type = STRING; } else { ret->type = DOUBLE; } ptr = skip_space(end); while (*ptr) { Arg *arg; ret->arg = realloc(ret->arg, ++(ret->arg_size) * sizeof(Arg)); arg = &(ret->arg[ret->arg_size - 1]); arg->literal = arg->reference = 0; if (*ptr == '&') { arg->reference = 1; ptr++; } end = skip_symbol(ptr); if (!strncasecmp(ptr, "handle", end - ptr) && (end - ptr) == 6) { arg->arg.type = HANDLE; } else if (!strncasecmp(ptr, "double", end - ptr) && (end - ptr) == 6) { arg->arg.type = DOUBLE; } else if (!strncasecmp(ptr, "string", end - ptr) && (end - ptr) == 6) { arg->arg.type = STRING; } ptr = skip_space(end); } return (function_table_size - 1); }