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

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
                      9:   as published by the Free Software Foundation; either version 2
                     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
                     18:   along with this program; if not, write to the Free Software
                     19:   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
                     20: */
                     21: 
                     22: #include <stdlib.h>
                     23: #include <stdio.h>
                     24: #include <unistd.h>
1.2       anton      25: extern int optind;
                     26: 
1.1       anton      27: #include <assert.h>
                     28: #include "mini.h"
                     29: 
                     30: void genarg_i(Inst **vmcodepp, long i)
                     31: {
                     32:   vm_i2Cell(i, *((Cell *) *vmcodepp));
                     33:   (*vmcodepp)++;
                     34: }
                     35: 
                     36: void genarg_target(Inst **vmcodepp, Inst *target)
                     37: {
                     38:   vm_target2Cell(target, *((Cell *) *vmcodepp));
                     39:   (*vmcodepp)++;
                     40: }
                     41: 
                     42: void printarg_i(long i)
                     43: {
                     44:   fprintf(vm_out, "%ld ", i);
                     45: }
                     46: 
                     47: void printarg_target(Inst *target)
                     48: {
                     49:   fprintf(vm_out, "%p ", target);
                     50: }
                     51: 
                     52: void printarg_a(char *a)
                     53: {
                     54:   fprintf(vm_out, "%p ", a);
                     55: }
                     56: 
                     57: void printarg_Cell(Cell i)
                     58: {
                     59:   fprintf(vm_out, "0x%lx ", i.i);
                     60: }
                     61: 
                     62: /* This language has separate name spaces for functions and variables;
                     63:    this works because there are no function variables, and the syntax
                     64:    makes it possible to differentiate between function and variable
                     65:    reference */
                     66: 
                     67: typedef struct functab {
                     68:   struct functab *next;
                     69:   char *name;
                     70:   Inst *start;
                     71:   int params;
                     72:   int nonparams;
                     73: } functab;
                     74: 
                     75: functab *ftab=NULL;
                     76: 
                     77: /* note: does not check for double definitions */
                     78: void insert_func(char *name, Inst *start, int locals, int nonparams)
                     79: {
                     80:   functab *node = malloc(sizeof(functab));
                     81: 
                     82:   node->next=ftab;
                     83:   node->name=name;
                     84:   node->start=start;
                     85:   node->params=locals-nonparams;
                     86:   node->nonparams=nonparams;
                     87:   ftab=node;
                     88: }
                     89: 
                     90: functab *lookup_func(char *name)
                     91: {
                     92:   functab *p;
                     93: 
                     94:   for (p=ftab; p!=NULL; p=p->next)
                     95:     if (strcmp(p->name,name)==0)
                     96:       return p;
                     97:   fprintf(stderr, "undefined function %s", name);
                     98:   exit(1);
                     99: }
                    100: 
                    101: Inst *func_addr(char *name)
                    102: {
                    103:   return lookup_func(name)->start;
                    104: }
                    105: 
                    106: long func_calladjust(char *name)
                    107: {
                    108:   return adjust(lookup_func(name)->nonparams);
                    109: }
                    110: 
                    111: 
                    112: typedef struct vartab {
                    113:   struct vartab *next;
                    114:   char *name;
                    115:   int index;
                    116: } vartab;
                    117: 
                    118: vartab* vtab;
                    119: 
                    120: /* no checking for double definitions */
                    121: void insert_local(char *name)
                    122: {
                    123:   vartab *node = malloc(sizeof(vartab));
                    124: 
                    125:   locals++;
                    126:   node->next=vtab;
                    127:   node->name=name;
                    128:   node->index=locals;
                    129:   vtab = node;
                    130: }
                    131: 
                    132: vartab *lookup_var(char *name)
                    133: {
                    134:   vartab *p;
                    135: 
                    136:   for (p=vtab; p!=NULL; p=p->next)
                    137:     if (strcmp(p->name,name)==0)
                    138:       return p;
                    139:   fprintf(stderr, "undefined local variable %s", name);
                    140:   exit(1);
                    141: }
                    142: 
                    143: long var_offset(char *name)
                    144: {
                    145:   return (locals - lookup_var(name)->index + 2)*sizeof(Cell);
                    146: }
                    147: 
                    148: #define CODE_SIZE 65536
                    149: #define STACK_SIZE 65536
                    150: typedef long (*engine_t)(Inst *ip0, Cell* sp, char* fp);
                    151: 
                    152: char *program_name;
                    153: 
                    154: int main(int argc, char **argv)
                    155: {
                    156:   int disassembling = 0;
                    157:   int profiling = 0;
                    158:   int c;
1.4       anton     159:   Inst *vm_code=(Inst *)calloc(CODE_SIZE,sizeof(Inst));
1.1       anton     160:   Inst *start;
1.4       anton     161:   Cell *stack=(Cell *)calloc(STACK_SIZE,sizeof(Cell));
1.1       anton     162:   engine_t runvm=engine;
                    163: 
                    164:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
                    165:     switch (c) {
                    166:     default:
                    167:     case 'h':
                    168:     help:
1.2       anton     169:       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     170:              argv[0]);
                    171:       exit(1);
                    172:     case 'd':
                    173:       disassembling=1;
                    174:       break;
                    175:     case 'p':
                    176:       profiling=1;
1.3       anton     177:       use_super=0; /* we don't want superinstructions in the profile */
1.1       anton     178:       runvm = engine_debug;
                    179:       break;
                    180:     case 't':
                    181:       vm_debug=1;
                    182:       runvm = engine_debug;
                    183:       break;
                    184:     }
                    185:   }
                    186:   if (optind+1 != argc) 
                    187:     goto help;
                    188:   program_name = argv[optind];
                    189:   if ((yyin=fopen(program_name,"r"))==NULL) {
                    190:     perror(argv[optind]);
                    191:     exit(1);
                    192:   }
                    193: 
                    194:   /* initialize everything */
                    195:   vmcodep = vm_code;
                    196:   vm_out = stderr;
                    197:   (void)runvm(NULL,NULL,NULL); /* initialize vm_prim */
                    198:   init_peeptable();
                    199:   
                    200:   if (yyparse())
                    201:     exit(1);
                    202: 
                    203:   start=vmcodep;
                    204:   gen_main_end();
                    205:   vmcode_end=vmcodep;
                    206: 
                    207:   if (disassembling)
                    208:     vm_disassemble(vm_code, vmcodep, vm_prim);
                    209: 
                    210:   printf("result = %ld\n",runvm(start, stack+STACK_SIZE-1, NULL));
                    211: 
                    212:   if (profiling)
                    213:     vm_print_profile(vm_out);
                    214: 
                    215:   return 0;
                    216: }

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