source: branches/Pascal Compiler/UVirtualMachine.pas

Last change on this file was 15, checked in by george, 16 years ago
  • Přidáno: Další pokusný projekt překladače.
File size: 5.6 KB
Line 
1unit UVirtualMachine;
2
3interface
4
5uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls, ComCtrls, Contnrs;
8
9type
10 TVirtualProcessor = class;
11
12 TProcessorInstruction = class
13 DataWidth: Integer;
14 FOwner: TVirtualProcessor;
15 end;
16
17 // Instruction operands
18
19 TInstructionOperand = class
20 Value: Integer;
21 end;
22
23 TOperandNonConstant = class(TInstructionOperand)
24 end;
25
26 TOperandConstant = class(TInstructionOperand)
27 end;
28
29 TOperandAddress = class(TOperandNonConstant)
30 end;
31
32 TOperandIndirectAddress = class(TOperandNonConstant)
33 end;
34
35 // Data manipulation
36
37 TInstructionCopy = class(TProcessorInstruction)
38 Source: TInstructionOperand;
39 Destination: TOperandNonConstant;
40 procedure Execute;
41 end;
42
43 // Arithmetic operation
44
45 TInstructionIncrement = class(TProcessorInstruction)
46 Address: TOperandNonConstant;
47 procedure Execute;
48 end;
49
50 TInstructionDecrement = class(TProcessorInstruction)
51 Address: TOperandNonConstant;
52 procedure Execute;
53 end;
54
55 // Program control
56
57 TInstructionJump = class(TProcessorInstruction)
58 Address: Integer;
59 procedure Execute;
60 end;
61
62 TInstructionCall = class(TProcessorInstruction)
63 Address: Integer;
64 procedure Execute;
65 end;
66
67 TInstructionReturn = class(TProcessorInstruction)
68 procedure Execute;
69 end;
70
71 // Stact manipulation
72
73 TInstructionPush = class(TProcessorInstruction)
74 Address: TOperandNonConstant;
75 procedure Execute;
76 end;
77
78 TInstructionPop = class(TProcessorInstruction)
79 Address: TOperandNonConstant;
80 procedure Execute;
81 end;
82
83 TExecutionThread = class(TThread)
84 public
85 Parent: TVirtualProcessor;
86 procedure Execute; override;
87 end;
88
89 TVirtualProcessor = class
90 private
91 ExecutionThread: TExecutionThread;
92 function GetAddress(Address: Integer): Integer;
93 public
94 Memory: array of Byte;
95 ProgramCounter: Integer;
96 Stack: TStack;
97 procedure Start;
98 procedure Stop;
99 constructor Create;
100 destructor Destroy; override;
101 end;
102
103implementation
104
105{ TVirtualProcessor }
106
107constructor TVirtualProcessor.Create;
108begin
109 ExecutionThread := TExecutionThread.Create(True);
110 ExecutionThread.Parent := Self;
111 Stack := TStack.Create;
112end;
113
114destructor TVirtualProcessor.Destroy;
115begin
116 Stack.Free;
117 ExecutionThread.Free;
118end;
119
120function TVirtualProcessor.GetAddress(Address: Integer): Integer;
121begin
122 Result := Memory[Address] or (Memory[Address + 1] shl 8) or
123 (Memory[Address + 2] shl 16) or (Memory[Address + 3] shl 24);
124end;
125
126procedure TVirtualProcessor.Start;
127begin
128 ExecutionThread.Resume;
129end;
130
131procedure TVirtualProcessor.Stop;
132begin
133 ExecutionThread.Suspend;
134end;
135
136{ TexecutionThread }
137
138procedure TExecutionThread.Execute;
139begin
140 inherited;
141 with Parent do
142 begin
143 ProgramCounter := 0;
144 repeat
145 //case Memory[ProgramCounter] of
146
147 //end;
148
149 until Terminated;
150 end;
151end;
152
153{ TInstructionIncrement }
154
155procedure TInstructionIncrement.Execute;
156begin
157 if Address is TOperandAddress then
158 Inc(FOwner.Memory[Address.Value])
159 else
160 if Address is TOperandIndirectAddress then
161 Inc(FOwner.Memory[FOwner.GetAddress(Address.Value)]);
162 Inc(FOwner.ProgramCounter);
163end;
164
165{ TInstructionCopy }
166
167procedure TInstructionCopy.Execute;
168begin
169 if Destination is TOperandAddress then begin
170 if Source is TOperandConstant then
171 FOwner.Memory[Destination.Value] := Source.Value
172 else
173 if Source is TOperandAddress then
174 FOwner.Memory[Destination.Value] := FOwner.Memory[Source.Value]
175 else
176 FOwner.Memory[Destination.Value] :=
177 FOwner.Memory[FOwner.GetAddress(Source.Value)];
178 end else
179 if Destination is TOperandIndirectAddress then begin
180 if Source is TOperandConstant then
181 FOwner.Memory[FOwner.GetAddress(Destination.Value)] := Source.Value
182 else
183 if Source is TOperandAddress then
184 FOwner.Memory[FOwner.GetAddress(Destination.Value)] := FOwner.Memory[Source.Value]
185 else
186 FOwner.Memory[FOwner.GetAddress(Destination.Value)] :=
187 FOwner.Memory[FOwner.GetAddress(Source.Value)];
188 end else
189 raise Exception.Create('COPY: Can''t copy to constant!');
190 Inc(FOwner.ProgramCounter);
191end;
192
193{ TInstructionJump }
194
195procedure TInstructionJump.Execute;
196begin
197 FOwner.ProgramCounter := Address;
198end;
199
200{ TInstructionCall }
201
202procedure TInstructionCall.Execute;
203begin
204 FOwner.Stack.Push(Pointer(FOwner.ProgramCounter));
205 FOwner.ProgramCounter := Address;
206end;
207
208{ TInstructionReturn }
209
210procedure TInstructionReturn.Execute;
211begin
212 FOwner.ProgramCounter := Integer(FOwner.Stack.Pop);
213end;
214
215{ TInstructionPush }
216
217procedure TInstructionPush.Execute;
218begin
219 if Address is TOperandAddress then
220 //FOwner.Stack.Push(FOwner.Memory[Address.Value])
221 else
222 if Address is TOperandIndirectAddress then
223 //FOwner.Stack.Push(FOwner.Memory[FOwner.GetAddress(Address.Value)]);
224 Inc(FOwner.ProgramCounter);
225end;
226
227{ TInstructionDecrement }
228
229procedure TInstructionDecrement.Execute;
230begin
231 if Address is TOperandAddress then
232 Dec(FOwner.Memory[Address.Value])
233 else
234 if Address is TOperandIndirectAddress then
235 Dec(FOwner.Memory[FOwner.GetAddress(Address.Value)]);
236 Inc(FOwner.ProgramCounter);
237end;
238
239{ TInstructionPop }
240
241procedure TInstructionPop.Execute;
242begin
243 if Address is TOperandAddress then
244 //FOwner.Memory[Address.Value] := FOwner.Stack.Pop
245 else
246 if Address is TOperandIndirectAddress then
247 //FOwner.Memory[FOwner.GetAddress(Address.Value)] := FOwner.Stack.Pop;
248 Inc(FOwner.ProgramCounter);
249end;
250
251end.
Note: See TracBrowser for help on using the repository browser.