Annotation of gforth/vmgen-ex/support.c, revision 1.5
1.1 anton 1: /* support functions and main() for vmgen example
2:
3: Copyright (C) 2001 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>
1.3 anton 25: extern int optind;
26:
1.1 anton 27: #include <assert.h>
28: #include "mini.h"
29:
30: void genarg_i(Inst **vmcodepp, Cell i)
31: {
32: *((Cell *) *vmcodepp) = i;
33: (*vmcodepp)++;
34: }
35:
36: void genarg_target(Inst **vmcodepp, Inst *target)
37: {
38: *((Inst **) *vmcodepp) = target;
39: (*vmcodepp)++;
40: }
41:
42: void printarg_i(Cell 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:
1.2 anton 57: void printarg_Cell(Cell i)
58: {
59: fprintf(vm_out, "0x%lx ", i);
60: }
61:
1.1 anton 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: Cell 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: Cell 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 Cell (*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.5 ! anton 159: Inst *vm_code=(Inst *)calloc(CODE_SIZE,sizeof(Inst));
1.1 anton 160: Inst *start;
1.5 ! 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.3 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.4 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;
1.2 anton 204: gen_main_end();
205: vmcode_end=vmcodep;
1.1 anton 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));
1.2 anton 211:
212: if (profiling)
213: vm_print_profile(vm_out);
1.1 anton 214:
215: return 0;
216: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>