File:  [gforth] / gforth / vmgen-ex / support.c
Revision 1.8: download - view: text, annotated - select for diffs
Mon Dec 31 19:02:25 2007 UTC (11 years, 10 months ago) by anton
Branches: MAIN
CVS tags: v0-7-0, HEAD
updated copyright year after changing license notice

    1: /* support functions and main() for vmgen example
    2: 
    3:   Copyright (C) 2001,2003,2007 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 3
   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, see http://www.gnu.org/licenses/.
   19: */
   20: 
   21: #include <stdlib.h>
   22: #include <stdio.h>
   23: #include <unistd.h>
   24: extern int optind;
   25: 
   26: #include <assert.h>
   27: #include "mini.h"
   28: 
   29: void genarg_i(Inst **vmcodepp, Cell i)
   30: {
   31:   *((Cell *) *vmcodepp) = i;
   32:   (*vmcodepp)++;
   33: }
   34: 
   35: void genarg_target(Inst **vmcodepp, Inst *target)
   36: {
   37:   *((Inst **) *vmcodepp) = target;
   38:   (*vmcodepp)++;
   39: }
   40: 
   41: void printarg_i(Cell 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);
   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: Cell 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: Cell 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 Cell (*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;
  158:   Inst *vm_code=(Inst *)calloc(CODE_SIZE,sizeof(Inst));
  159:   Inst *start;
  160:   Cell *stack=(Cell *)calloc(STACK_SIZE,sizeof(Cell));
  161:   engine_t runvm=engine;
  162: 
  163:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
  164:     switch (c) {
  165:     default:
  166:     case 'h':
  167:     help:
  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",
  169: 	      argv[0]);
  170:       exit(1);
  171:     case 'd':
  172:       disassembling=1;
  173:       break;
  174:     case 'p':
  175:       profiling=1;
  176:       use_super=0; /* we don't want superinstructions in the profile */
  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>