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