Annotation of gforth/vmgen-ex2/support.c, revision 1.6

1.1       anton       1: /* support functions and main() for vmgen example
                      2: 
1.5       anton       3:   Copyright (C) 2001,2003 Free Software Foundation, Inc.
1.1       anton       4: 
                      5:   This file is part of Gforth.
                      6: 
                      7:   Gforth is free software; you can redistribute it and/or
                      8:   modify it under the terms of the GNU General Public License
1.6     ! anton       9:   as published by the Free Software Foundation, either version 3
1.1       anton      10:   of the License, or (at your option) any later version.
                     11: 
                     12:   This program is distributed in the hope that it will be useful,
                     13:   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:   GNU General Public License for more details.
                     16: 
                     17:   You should have received a copy of the GNU General Public License
1.6     ! anton      18:   along with this program; if not, see http://www.gnu.org/licenses/.
1.1       anton      19: */
                     20: 
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <unistd.h>
1.2       anton      24: extern int optind;
                     25: 
1.1       anton      26: #include <assert.h>
                     27: #include "mini.h"
                     28: 
                     29: void genarg_i(Inst **vmcodepp, long i)
                     30: {
                     31:   vm_i2Cell(i, *((Cell *) *vmcodepp));
                     32:   (*vmcodepp)++;
                     33: }
                     34: 
                     35: void genarg_target(Inst **vmcodepp, Inst *target)
                     36: {
                     37:   vm_target2Cell(target, *((Cell *) *vmcodepp));
                     38:   (*vmcodepp)++;
                     39: }
                     40: 
                     41: void printarg_i(long i)
                     42: {
                     43:   fprintf(vm_out, "%ld ", i);
                     44: }
                     45: 
                     46: void printarg_target(Inst *target)
                     47: {
                     48:   fprintf(vm_out, "%p ", target);
                     49: }
                     50: 
                     51: void printarg_a(char *a)
                     52: {
                     53:   fprintf(vm_out, "%p ", a);
                     54: }
                     55: 
                     56: void printarg_Cell(Cell i)
                     57: {
                     58:   fprintf(vm_out, "0x%lx ", i.i);
                     59: }
                     60: 
                     61: /* This language has separate name spaces for functions and variables;
                     62:    this works because there are no function variables, and the syntax
                     63:    makes it possible to differentiate between function and variable
                     64:    reference */
                     65: 
                     66: typedef struct functab {
                     67:   struct functab *next;
                     68:   char *name;
                     69:   Inst *start;
                     70:   int params;
                     71:   int nonparams;
                     72: } functab;
                     73: 
                     74: functab *ftab=NULL;
                     75: 
                     76: /* note: does not check for double definitions */
                     77: void insert_func(char *name, Inst *start, int locals, int nonparams)
                     78: {
                     79:   functab *node = malloc(sizeof(functab));
                     80: 
                     81:   node->next=ftab;
                     82:   node->name=name;
                     83:   node->start=start;
                     84:   node->params=locals-nonparams;
                     85:   node->nonparams=nonparams;
                     86:   ftab=node;
                     87: }
                     88: 
                     89: functab *lookup_func(char *name)
                     90: {
                     91:   functab *p;
                     92: 
                     93:   for (p=ftab; p!=NULL; p=p->next)
                     94:     if (strcmp(p->name,name)==0)
                     95:       return p;
                     96:   fprintf(stderr, "undefined function %s", name);
                     97:   exit(1);
                     98: }
                     99: 
                    100: Inst *func_addr(char *name)
                    101: {
                    102:   return lookup_func(name)->start;
                    103: }
                    104: 
                    105: long func_calladjust(char *name)
                    106: {
                    107:   return adjust(lookup_func(name)->nonparams);
                    108: }
                    109: 
                    110: 
                    111: typedef struct vartab {
                    112:   struct vartab *next;
                    113:   char *name;
                    114:   int index;
                    115: } vartab;
                    116: 
                    117: vartab* vtab;
                    118: 
                    119: /* no checking for double definitions */
                    120: void insert_local(char *name)
                    121: {
                    122:   vartab *node = malloc(sizeof(vartab));
                    123: 
                    124:   locals++;
                    125:   node->next=vtab;
                    126:   node->name=name;
                    127:   node->index=locals;
                    128:   vtab = node;
                    129: }
                    130: 
                    131: vartab *lookup_var(char *name)
                    132: {
                    133:   vartab *p;
                    134: 
                    135:   for (p=vtab; p!=NULL; p=p->next)
                    136:     if (strcmp(p->name,name)==0)
                    137:       return p;
                    138:   fprintf(stderr, "undefined local variable %s", name);
                    139:   exit(1);
                    140: }
                    141: 
                    142: long var_offset(char *name)
                    143: {
                    144:   return (locals - lookup_var(name)->index + 2)*sizeof(Cell);
                    145: }
                    146: 
                    147: #define CODE_SIZE 65536
                    148: #define STACK_SIZE 65536
                    149: typedef long (*engine_t)(Inst *ip0, Cell* sp, char* fp);
                    150: 
                    151: char *program_name;
                    152: 
                    153: int main(int argc, char **argv)
                    154: {
                    155:   int disassembling = 0;
                    156:   int profiling = 0;
                    157:   int c;
1.4       anton     158:   Inst *vm_code=(Inst *)calloc(CODE_SIZE,sizeof(Inst));
1.1       anton     159:   Inst *start;
1.4       anton     160:   Cell *stack=(Cell *)calloc(STACK_SIZE,sizeof(Cell));
1.1       anton     161:   engine_t runvm=engine;
                    162: 
                    163:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
                    164:     switch (c) {
                    165:     default:
                    166:     case 'h':
                    167:     help:
1.2       anton     168:       fprintf(stderr, "Usage: %s [options] file\nOptions:\n-h  Print this message and exit\n-d disassemble VM program before execution\n-p     profile VM code sequences (output on stderr)\n-t        trace VM code execution (output on stderr)\n",
1.1       anton     169:              argv[0]);
                    170:       exit(1);
                    171:     case 'd':
                    172:       disassembling=1;
                    173:       break;
                    174:     case 'p':
                    175:       profiling=1;
1.3       anton     176:       use_super=0; /* we don't want superinstructions in the profile */
1.1       anton     177:       runvm = engine_debug;
                    178:       break;
                    179:     case 't':
                    180:       vm_debug=1;
                    181:       runvm = engine_debug;
                    182:       break;
                    183:     }
                    184:   }
                    185:   if (optind+1 != argc) 
                    186:     goto help;
                    187:   program_name = argv[optind];
                    188:   if ((yyin=fopen(program_name,"r"))==NULL) {
                    189:     perror(argv[optind]);
                    190:     exit(1);
                    191:   }
                    192: 
                    193:   /* initialize everything */
                    194:   vmcodep = vm_code;
                    195:   vm_out = stderr;
                    196:   (void)runvm(NULL,NULL,NULL); /* initialize vm_prim */
                    197:   init_peeptable();
                    198:   
                    199:   if (yyparse())
                    200:     exit(1);
                    201: 
                    202:   start=vmcodep;
                    203:   gen_main_end();
                    204:   vmcode_end=vmcodep;
                    205: 
                    206:   if (disassembling)
                    207:     vm_disassemble(vm_code, vmcodep, vm_prim);
                    208: 
                    209:   printf("result = %ld\n",runvm(start, stack+STACK_SIZE-1, NULL));
                    210: 
                    211:   if (profiling)
                    212:     vm_print_profile(vm_out);
                    213: 
                    214:   return 0;
                    215: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>