5219fc48d1
[COMPILER] * BUG: JIT: Fix local variable referencing. * NEW: JIT: Implement NEW operator and array accessors. [INTERPRETER] * NEW: Support for JIT NEW operator and array accessors. [GB.JIT] * NEW: Support for object datatypes. * NEW: Implement NEW operator and array accessors.
469 lines
9.3 KiB
C
469 lines
9.3 KiB
C
/***************************************************************************
|
|
|
|
gbc_reserved_make.c
|
|
|
|
(c) 2000-2017 Benoît Minisini <g4mba5@gmail.com>
|
|
|
|
This program 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, or (at your option)
|
|
any later version.
|
|
|
|
This program 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., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#define __GBC_RESERVED_MAKE_C
|
|
|
|
#define PROJECT_COMP
|
|
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
|
|
#include "gb_common.h"
|
|
#include "gb_reserved.h"
|
|
#include "gb_type_common.h"
|
|
#include "gb_pcode.h"
|
|
#include "gb_reserved_keyword.h"
|
|
|
|
#define HASH_SIZE 109
|
|
|
|
/*uint hash(const char *key, int len)
|
|
{
|
|
int i;
|
|
uint h = 0;
|
|
for (i = 0; i < len; i++)
|
|
h = (h << 4) + (h ^ (tolower(key[i])));
|
|
|
|
return h % HASH_SIZE;
|
|
}*/
|
|
|
|
char buffer[1024];
|
|
|
|
char *read_line(FILE *f)
|
|
{
|
|
return fgets(buffer, sizeof(buffer), f);
|
|
}
|
|
|
|
void read_write_until(FILE *in, FILE *out, char *until)
|
|
{
|
|
char *line;
|
|
|
|
for(;;)
|
|
{
|
|
line = read_line(in);
|
|
if (!line)
|
|
break;
|
|
if (out) fputs(line, out);
|
|
while (*line && ((unsigned char)*line <= ' '))
|
|
line++;
|
|
if (!strncmp(line, until, strlen(until)))
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
int main(int argc, char **argv)
|
|
{
|
|
COMP_INFO *info;
|
|
SUBR_INFO *subr;
|
|
int len;
|
|
int i, p, n;
|
|
uint h;
|
|
char c;
|
|
char last[16];
|
|
char next[16];
|
|
FILE *in, *out;
|
|
|
|
in = fopen("../share/gb_reserved_temp.h", "r");
|
|
if (!in)
|
|
{
|
|
fprintf(stderr, "unable to open '../share/gb_reserved_temp.h': %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
out = fopen("../share/gb_reserved_temp.h.tmp", "w");
|
|
|
|
read_write_until(in, out, "int RESERVED_find_word(const char *word, int len)");
|
|
|
|
read_write_until(in, out, "static void *jump[] = {");
|
|
|
|
for (h = 0; h < 12; h++)
|
|
{
|
|
if ((h % 8) == 0)
|
|
fprintf(out, "\t\t");
|
|
fprintf(out, "&&__%02d, ", h);
|
|
if ((h % 8) == 7)
|
|
fprintf(out, "\n");
|
|
}
|
|
fprintf(out, "\n\t};\n\n");
|
|
|
|
//printf(" goto *jump[h %% %d];\n\n", HASH_SIZE);
|
|
fprintf(out, "\tgoto *jump[len];\n\n");
|
|
|
|
fprintf(out, "__00:\n__01:\n\treturn -1;\n");
|
|
|
|
for (h = 2; h < 12; h++)
|
|
{
|
|
fprintf(out, "__%02d:\n", h);
|
|
|
|
*last = 0;
|
|
|
|
for(;;)
|
|
{
|
|
n = -1;
|
|
|
|
*next = 0;
|
|
|
|
for (info = &COMP_res_info[1], i = 1; info->name; info++, i++)
|
|
{
|
|
len = strlen(info->name);
|
|
if (len != h)
|
|
continue;
|
|
|
|
if (strcmp(info->name, last) <= 0)
|
|
continue;
|
|
|
|
if (*next == 0 || strcmp(info->name, next) <= 0)
|
|
{
|
|
strcpy(next, info->name);
|
|
n = i;
|
|
}
|
|
}
|
|
|
|
if (n < 0)
|
|
break;
|
|
|
|
info = &COMP_res_info[n];
|
|
len = strlen(info->name);
|
|
|
|
strcpy(last, info->name);
|
|
|
|
fprintf(out, "\tif (");
|
|
for (p = 0; p < len; p++)
|
|
{
|
|
if (p)
|
|
fprintf(out, " && ");
|
|
c = info->name[p];
|
|
if (isalpha(c))
|
|
fprintf(out, "tolower(word[%d]) == '%c'", p, tolower(info->name[p]));
|
|
else if (c == '\\')
|
|
fprintf(out, "word[%d] == '\\\\'", p);
|
|
else
|
|
fprintf(out, "word[%d] == '%c'", p, info->name[p]);
|
|
}
|
|
/*printf(" if (!strncmp(\"");
|
|
for (p = 0; p < len; p++)
|
|
{
|
|
c = info->name[p];
|
|
if (c == '\\')
|
|
printf("\\\\");
|
|
else
|
|
putchar(tolower(info->name[p]));
|
|
}
|
|
printf("\", word, %d)", len);*/
|
|
fprintf(out, ") return %d;\n", n);
|
|
}
|
|
|
|
fprintf(out, "\treturn -1;\n");
|
|
}
|
|
|
|
read_write_until(in, NULL, "}");
|
|
read_write_until(in, NULL, "}");
|
|
fprintf(out, "}\n");
|
|
|
|
read_write_until(in, out, "static void *jump[] = {");
|
|
|
|
for (h = 0; h < 12; h++)
|
|
{
|
|
if ((h % 8) == 0)
|
|
fprintf(out, "\t\t");
|
|
fprintf(out, "&&__%02d, ", h);
|
|
if ((h % 8) == 7)
|
|
fprintf(out, "\n");
|
|
}
|
|
fprintf(out, "\n\t};\n\n");
|
|
|
|
fprintf(out, "\tgoto *jump[len];\n\n");
|
|
|
|
fprintf(out, "__00:\n__01:\n\treturn -1;\n");
|
|
|
|
for (h = 2; h < 12; h++)
|
|
{
|
|
fprintf(out, "__%02d:\n", h);
|
|
|
|
*last = 0;
|
|
|
|
for(;;)
|
|
{
|
|
n = -1;
|
|
|
|
*next = 0;
|
|
|
|
for (subr = &COMP_subr_info[0], i = 0; subr->name; subr++, i++)
|
|
{
|
|
len = strlen(subr->name);
|
|
if (len != h)
|
|
continue;
|
|
|
|
if (strcmp(subr->name, last) <= 0)
|
|
continue;
|
|
|
|
if (*next == 0 || strcmp(subr->name, next) <= 0)
|
|
{
|
|
strcpy(next, subr->name);
|
|
n = i;
|
|
}
|
|
}
|
|
|
|
if (n < 0)
|
|
break;
|
|
|
|
subr = &COMP_subr_info[n];
|
|
len = strlen(subr->name);
|
|
|
|
strcpy(last, subr->name);
|
|
|
|
fprintf(out, "\tif ("); //COMPARE_%d(\"%s\", word)) return %d;\n", len, len, info->name, i);
|
|
for (p = 0; p < len; p++)
|
|
{
|
|
if (p)
|
|
fprintf(out, " && ");
|
|
c = subr->name[p];
|
|
if (isalpha(c))
|
|
fprintf(out, "tolower(word[%d]) == '%c'", p, tolower(subr->name[p]));
|
|
else if (c == '\\')
|
|
fprintf(out, "word[%d] == '\\\\'", p);
|
|
else
|
|
fprintf(out, "word[%d] == '%c'", p, subr->name[p]);
|
|
}
|
|
fprintf(out, ") return %d;\n", n);
|
|
}
|
|
|
|
fprintf(out, "\treturn -1;\n");
|
|
}
|
|
|
|
fprintf(out, "}\n");
|
|
|
|
fclose(in);
|
|
fclose(out);
|
|
|
|
unlink("../share/gb_reserved_temp.h");
|
|
rename("../share/gb_reserved_temp.h.tmp", "../share/gb_reserved_temp.h");
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static int compare_name(const char *name1, const char* name2)
|
|
{
|
|
int l1 = strlen(name1);
|
|
int l2 = strlen(name2);
|
|
|
|
if (l1 < l2)
|
|
return -1;
|
|
if (l1 > l2)
|
|
return 1;
|
|
return strcasecmp(name1, name2);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
COMP_INFO *info;
|
|
SUBR_INFO *subr;
|
|
int len;
|
|
int i, p, n;
|
|
uint h;
|
|
char c;
|
|
char last[16];
|
|
char next[16];
|
|
FILE *in, *out;
|
|
|
|
in = fopen("../share/gb_reserved_temp.h", "r");
|
|
if (!in)
|
|
{
|
|
fprintf(stderr, "unable to open '../share/gb_reserved_temp.h': %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
out = fopen("../share/gb_reserved_temp.h.tmp", "w");
|
|
|
|
read_write_until(in, out, "int RESERVED_find_word(const char *word, int len)");
|
|
|
|
read_write_until(in, out, "static void *jump[] = {");
|
|
|
|
for (h = 32; h < 127; h++)
|
|
{
|
|
if ((h % 8) == 0)
|
|
fprintf(out, "\t\t");
|
|
fprintf(out, "&&__%02X, ", h);
|
|
if ((h % 8) == 7)
|
|
fprintf(out, "\n");
|
|
}
|
|
fprintf(out, "\n\t};\n\n");
|
|
|
|
//printf(" goto *jump[h %% %d];\n\n", HASH_SIZE);
|
|
fprintf(out, "\tgoto *jump[*word - 32];\n\n");
|
|
|
|
for (h = 32; h < 127; h++)
|
|
{
|
|
if (islower(h))
|
|
continue;
|
|
|
|
fprintf(out, "__%02X:\n", h);
|
|
if (isupper(h))
|
|
fprintf(out, "__%02X:\n", tolower(h));
|
|
|
|
*last = 0;
|
|
|
|
for(;;)
|
|
{
|
|
n = -1;
|
|
|
|
*next = 0;
|
|
|
|
for (info = &COMP_res_info[1], i = 1; info->name; info++, i++)
|
|
{
|
|
if (tolower(*info->name) != tolower(h) || !info->name[1])
|
|
continue;
|
|
|
|
if (compare_name(info->name, last) <= 0)
|
|
continue;
|
|
|
|
if (*next == 0 || compare_name(info->name, next) <= 0)
|
|
{
|
|
strcpy(next, info->name);
|
|
n = i;
|
|
}
|
|
}
|
|
|
|
if (n < 0)
|
|
break;
|
|
|
|
info = &COMP_res_info[n];
|
|
len = strlen(info->name);
|
|
|
|
strcpy(last, info->name);
|
|
|
|
fprintf(out, "\tif (len == %d", len);
|
|
for (p = 1; p < len; p++)
|
|
{
|
|
fprintf(out, " && ");
|
|
c = info->name[p];
|
|
if (isalpha(c))
|
|
fprintf(out, "tolower(word[%d]) == '%c'", p, tolower(info->name[p]));
|
|
else if (c == '\\')
|
|
fprintf(out, "word[%d] == '\\\\'", p);
|
|
else
|
|
fprintf(out, "word[%d] == '%c'", p, info->name[p]);
|
|
}
|
|
/*printf(" if (!strncmp(\"");
|
|
for (p = 0; p < len; p++)
|
|
{
|
|
c = info->name[p];
|
|
if (c == '\\')
|
|
printf("\\\\");
|
|
else
|
|
putchar(tolower(info->name[p]));
|
|
}
|
|
printf("\", word, %d)", len);*/
|
|
fprintf(out, ") return %d;\n", n);
|
|
}
|
|
|
|
fprintf(out, "\treturn -1;\n");
|
|
}
|
|
|
|
read_write_until(in, NULL, "}");
|
|
read_write_until(in, NULL, "}");
|
|
fprintf(out, "}\n");
|
|
|
|
read_write_until(in, out, "static void *jump[] = {");
|
|
|
|
for (h = 32; h < 127; h++)
|
|
{
|
|
if ((h % 8) == 0)
|
|
fprintf(out, "\t\t");
|
|
fprintf(out, "&&__%02X, ", h);
|
|
if ((h % 8) == 7)
|
|
fprintf(out, "\n");
|
|
}
|
|
fprintf(out, "\n\t};\n\n");
|
|
|
|
fprintf(out, "\tgoto *jump[*word - 32];\n\n");
|
|
|
|
for (h = 32; h < 127; h++)
|
|
{
|
|
if (islower(h))
|
|
continue;
|
|
|
|
fprintf(out, "__%02X:\n", h);
|
|
if (isupper(h))
|
|
fprintf(out, "__%02X:\n", tolower(h));
|
|
|
|
*last = 0;
|
|
|
|
for(;;)
|
|
{
|
|
n = -1;
|
|
|
|
*next = 0;
|
|
|
|
for (subr = &COMP_subr_info[0], i = 0; subr->name; subr++, i++)
|
|
{
|
|
if (tolower(*subr->name) != tolower(h) || !subr->name[1])
|
|
continue;
|
|
|
|
if (compare_name(subr->name, last) <= 0)
|
|
continue;
|
|
|
|
if (*next == 0 || compare_name(subr->name, next) <= 0)
|
|
{
|
|
strcpy(next, subr->name);
|
|
n = i;
|
|
}
|
|
}
|
|
|
|
if (n < 0)
|
|
break;
|
|
|
|
subr = &COMP_subr_info[n];
|
|
len = strlen(subr->name);
|
|
|
|
strcpy(last, subr->name);
|
|
|
|
fprintf(out, "\tif (len == %d", len);
|
|
for (p = 1; p < len; p++)
|
|
{
|
|
fprintf(out, " && ");
|
|
c = subr->name[p];
|
|
if (isalpha(c))
|
|
fprintf(out, "tolower(word[%d]) == '%c'", p, tolower(subr->name[p]));
|
|
else if (c == '\\')
|
|
fprintf(out, "word[%d] == '\\\\'", p);
|
|
else
|
|
fprintf(out, "word[%d] == '%c'", p, subr->name[p]);
|
|
}
|
|
fprintf(out, ") return %d;\n", n);
|
|
}
|
|
|
|
fprintf(out, "\treturn -1;\n");
|
|
}
|
|
|
|
fprintf(out, "}\n");
|
|
|
|
fclose(in);
|
|
fclose(out);
|
|
|
|
unlink("../share/gb_reserved_temp.h");
|
|
rename("../share/gb_reserved_temp.h.tmp", "../share/gb_reserved_temp.h");
|
|
|
|
return 0;
|
|
}
|