git @ Cat's Eye Technologies Kosheri / master src / geninstr.c
master

Tree @master (Download .tar.gz)

geninstr.c @masterraw · history · blame

/*
 * geninstr.c
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

static int
parse_descriptor_line(const char *line, char *name, char *mode)
{
        while (isspace((int)*line) && (*line != '\0')) {
                line++;
        }
        if (*line != '%')
                return 0;
        line++;
        while (isspace((int)*line) && (*line != '\0')) {
                line++;
        }
        while (!isspace((int)*line) && (*line != '\0')) {
                *name = *line;
                name++;
                line++;
        }
        *name = '\0';
        while (isspace((int)*line) && (*line != '\0')) {
                line++;
        }
        while (!isspace((int)*line) && (*line != '\0')) {
                *mode = *line;
                mode++;
                line++;
        }
        *mode = '\0';
        return 1;
}

int
main(int argc, char **argv)
{
        FILE *instrtab, *instrenum, *instrlab, *vm, *localtypes;
        static char line[512], name[80], mode[80];

        argc = argc;
        argv = argv;

        if ((instrtab = fopen("instrtab.c", "w")) == NULL) {
            perror("Couldn't open instrtab.c for writing");
            exit(1);
        }
        if ((instrenum = fopen("instrenum.h", "w")) == NULL) {
            perror("Couldn't open instrenum.h for writing");
            exit(1);
        }
        if ((instrlab = fopen("instrlab.h", "w")) == NULL) {
            perror("Couldn't open instrlab.h for writing");
            exit(1);
        }
        if ((vm = fopen("vm.c", "r")) == NULL) {
            perror("Couldn't open vm.c for reading");
            exit(1);
        }
	fputs(
"/*\n"
" * instrtab.c\n"
" * Table of VM instructions, mapping names to opcodes.\n"
" * NOTE: THIS FILE WAS AUTOMATICALLY GENERATED from vm.c by geninstr\n"
" */\n"
"\n"
"#include \"lib.h\"\n"
"\n"
"#include \"instrtab.h\"\n"
"\n"
"struct opcode_entry opcode_table[] = {\n", instrtab);
	fputs(
"/*\n"
" * instrenum.h\n"
" * C 'enum' type for VM instructions.\n"
" * NOTE: THIS FILE WAS AUTOMATICALLY GENERATED from vm.c by geninstr\n"
" */\n"
"\n"
"#ifndef __INSTRENUM_H_\n"
"#define __INSTRENUM_H_\n"
"\n"
"enum opcode {\n", instrenum);
	fputs(
"/*\n"
" * instrlab.h\n"
" * gcc labels for VM instructions, to support direct threading.\n"
" * NOTE: THIS FILE WAS AUTOMATICALLY GENERATED from vm.c by geninstr\n"
" */\n"
"\n"
"#ifndef __INSTRLAB_H_\n"
"#define __INSTRLAB_H_\n"
"\n"
"static clabel instr_label[] = {\n", instrlab);

        while (fgets(line, 510, vm)) {
                int arity = 1;
                const char *optype = "NONE";

                if (!parse_descriptor_line(line, name, mode))
                        continue;

                switch (mode[0]) {
                    case 'i':
                        optype = "INT";
                        break;
                    case 'a':
                        optype = "ADDR";
                        break;
                    case 'v':
                        optype = "VALUE";
                        break;
                    default:
                        arity = 0;
                        break;
                }

                fprintf(instrtab, "\t{ \"%s\",\tINSTR_%s,\t%d,\tOPTYPE_%s\t},\n",
                        name, name, arity, optype);
                fprintf(instrenum, "\tINSTR_%s,\n", name);
                fprintf(instrlab, "\t&&LABEL_INSTR_%s,\n", name);
        }
        fclose(vm);
        fputs("\t{ NULL,\t\tINSTR_NULL,\t0,\tOPTYPE_NONE }\n};\n", instrtab);
        fclose(instrtab);
        fputs("\tINSTR_NULL\n};\n\n#endif /* !__INSTRENUM_H_ */\n", instrenum);
        fclose(instrenum);
        fputs("\tNULL\n};\n\n#endif /* !__INSTRLAB_H_ */\n", instrlab);
        fclose(instrlab);

        if ((localtypes = fopen("localtypes.h", "w")) == NULL) {
            perror("Couldn't open localtypes.h for writing");
            exit(1);
        }
	fputs(
"/*\n"
" * localtypes.h\n"
" * Define some types for the local system.\n"
" * NOTE: THIS FILE WAS AUTOMATICALLY GENERATED by geninstr\n"
" */\n"
"\n"
"#ifndef __LOCALTYPES_H_\n"
"#define __LOCALTYPES_H_\n"
"\n", localtypes);
        if (sizeof(void *) == sizeof(unsigned int)) {
                fputs("#define PTR_INT unsigned int\n", localtypes);
        } else if (sizeof(void *) == sizeof(unsigned long int)) {
                fputs("#define PTR_INT unsigned long int\n", localtypes);
        } else {
                fputs("#define PTR_INT not_supported\n", localtypes);
        }
	fputs("\n#endif /* !__LOCALTYPES_H_ */\n", localtypes);
        fclose(localtypes);

        exit(0);
}