File:  [gforth] / gforth / vmgen-ex2 / support.c
Revision 1.5: download - view: text, annotated - select for diffs
Sun Mar 9 15:17:12 2003 UTC (16 years, 10 months ago) by anton
Branches: MAIN
CVS tags: v0-6-2, v0-6-1, v0-6-0, HEAD
updated copyright years

    1: /* support functions and main() for vmgen example
    2: 
    3:   Copyright (C) 2001,2003 Free Software Foundation, Inc.
    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>
   25: extern int optind;
   26: 
   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;
  159:   Inst *vm_code=(Inst *)calloc(CODE_SIZE,sizeof(Inst));
  160:   Inst *start;
  161:   Cell *stack=(Cell *)calloc(STACK_SIZE,sizeof(Cell));
  162:   engine_t runvm=engine;
  163: 
  164:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
  165:     switch (c) {
  166:     default:
  167:     case 'h':
  168:     help:
  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",
  170: 	      argv[0]);
  171:       exit(1);
  172:     case 'd':
  173:       disassembling=1;
  174:       break;
  175:     case 'p':
  176:       profiling=1;
  177:       use_super=0; /* we don't want superinstructions in the profile */
  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>