source: trunk/Target/TargetC.pas

Last change on this file was 146, checked in by chronos, 11 months ago
  • Fixed: Build on Windows.
File size: 3.7 KB
Line 
1unit TargetC;
2
3interface
4
5uses
6 Classes, SysUtils, FileUtil, Target, BFTarget, Process, Dialogs,
7 LazFileUtils;
8
9type
10
11 { TTargetC }
12
13 TTargetC = class(TBFTarget)
14 private
15 function GetMemoryCell: string;
16 public
17 constructor Create; override;
18 procedure Compile; override;
19 procedure CompileToFile; override;
20 procedure Run; override;
21 end;
22
23
24implementation
25
26{ TTargetC }
27
28constructor TTargetC.Create;
29begin
30 inherited;
31 FName := 'C';
32 FSourceExtension := '.c';
33 FImageIndex := 23;
34 FCapabilities := [tcCompile, tcRun];
35 {$IFDEF WINDOWS}
36 CompilerPath := 'c:\Program Files\MinGW\bin\gcc.exe';
37 FCompiledExtension := '.exe';
38 FRunExtension := '';
39 {$ENDIF}
40 {$IFDEF UNIX}
41 CompilerPath := '/usr/bin/gcc';
42 FCompiledExtension := '';
43 FRunExtension := '';
44 {$ENDIF}
45end;
46
47function TTargetC.GetMemoryCell: string;
48begin
49 Result := 'Memory[Pos';
50 if FProgram[FProgramIndex].RelIndex > 0 then
51 Result := Result + ' + ' + IntToStr(FProgram[FProgramIndex].RelIndex)
52 else if FProgram[FProgramIndex].RelIndex < 0 then
53 Result := Result + ' - ' + IntToStr(Abs(FProgram[FProgramIndex].RelIndex));
54 Result := Result + ']';
55end;
56
57procedure TTargetC.Compile;
58begin
59 inherited;
60 Indent := 0;
61 FTargetCode := '';
62
63 AddLine('#include <stdio.h>');
64 AddLine('');
65 AddLine('int main()');
66 AddLine('{');
67 Inc(Indent);
68 AddLine('char Memory[' + IntToStr(MemorySize) + '];');
69 AddLine('int Pos;');
70 AddLine('char ReadChar;');
71 AddLine('');
72 AddLine('Pos = 0;');
73 FProgramIndex := 0;
74 while FProgramIndex < FProgram.Count do begin
75 case FProgram[FProgramIndex].Command of
76 cmPointerInc: AddLine('Pos = Pos + ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
77 cmPointerDec: AddLine('Pos = Pos - ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
78 cmInc: AddLine(GetMemoryCell + ' = ' + GetMemoryCell + ' + ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
79 cmDec: AddLine(GetMemoryCell + ' = ' + GetMemoryCell + ' - ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
80 cmOutput: AddLine('putchar(' + GetMemoryCell + ');');
81 cmInput: AddLine(GetMemoryCell + ' = getchar();');
82 cmSet: AddLine(GetMemoryCell + ' = ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
83 cmMultiply: AddLine(GetMemoryCell + ' = ' + GetMemoryCell + ' + Memory[Pos] * ' + IntToStr(FProgram[FProgramIndex].Parameter) + ';');
84 cmLoopStart: begin
85 AddLine('while(' + GetMemoryCell + ' != 0)');
86 AddLine('{');
87 Inc(Indent);
88 end;
89 cmLoopEnd: begin
90 Dec(Indent);
91 AddLine('}');
92 end;
93 end;
94 Inc(FProgramIndex);
95 end;
96 AddLine('return 0;');
97 Dec(Indent);
98 AddLine('}');
99
100 CompileToFile;
101end;
102
103procedure TTargetC.CompileToFile;
104var
105 Process: TProcess;
106 CompiledFile: string;
107begin
108 CompiledFile := ExtractFilePath(ProjectFileName) +
109 CompiledDir + DirectorySeparator + Name + DirectorySeparator +
110 ExtractFileNameOnly(ProjectFileName) + SourceExtension;
111 ForceDirectoriesUTF8(ExtractFilePath(CompiledFile));
112 with TStringList.Create do
113 try
114 Text := FTargetCode;
115 SaveToFile(CompiledFile);
116 finally
117 Free;
118 end;
119 if FileExistsUTF8(CompilerPath) then
120 try
121 Process := TProcess.Create(nil);
122 Process.CurrentDirectory := ExtractFilePath(CompilerPath);
123 Process.Executable := LongFileName(CompilerPath);
124 Process.Parameters.Add(LongFileName(CompiledFile));
125 Process.Parameters.Add('-o');
126 Process.Parameters.Add(LongFileName(ExtractFilePath(CompiledFile) + ExtractFileNameOnly(CompiledFile) + CompiledExtension));
127 Process.Options := [poWaitOnExit];
128 Process.Execute;
129 finally
130 Process.Free;
131 end else raise Exception.Create(Format(SCompilerNotFound, [CompilerPath]));
132end;
133
134procedure TTargetC.Run;
135begin
136 inherited;
137 RunFromFile;
138end;
139
140end.
141
Note: See TracBrowser for help on using the repository browser.