source: branches/easy compiler/USourceGenerator.pas

Last change on this file was 150, checked in by chronos, 7 years ago
  • Added: Load/Save example source code from/to file instead of hardcoded text in application source code.
File size: 5.8 KB
Line 
1unit USourceGenerator;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, USourceCode;
9
10type
11 { TSourceGenerator }
12
13 TSourceGenerator = class
14 private
15 Indent: Integer;
16 function GenerateBeginEnd(BeginEnd: TCommandBeginEnd): string;
17 function GenerateCommand(Command: TSourceCommand): string;
18 function GenerateRef(Reference: TSourceReference): string;
19 function IndentStr: string;
20 public
21 function Generate(SourceCode: TSourceCode): string;
22 end;
23
24
25implementation
26
27{ TSourceGenerator }
28
29function TSourceGenerator.Generate(SourceCode: TSourceCode): string;
30var
31 I: Integer;
32begin
33 Indent := 0;
34 Result := '';
35 if SourceCode.Variables.Count > 0 then
36 Result := Result + IndentStr + 'var' + LineEnding;
37 Inc(Indent);
38 with SourceCode do
39 for I := 0 to Variables.Count - 1 do
40 with TSourceVariable(Variables[I]) do begin
41 Result := Result + IndentStr + Name + ': ';
42 if ValueType.Name = 'String' then
43 Result := Result + 'string'
44 else if ValueType.Name = 'Integer' then
45 Result := Result + 'Integer'
46 else if ValueType.Name = 'StringArray' then
47 Result := Result + 'array of string'
48 else if ValueType.Name = 'IntegerArray' then
49 Result := Result + 'array of Integer'
50 else raise Exception.Create('Unsupported type');
51 Result := Result + ';' + LineEnding;
52 end;
53 Dec(Indent);
54 Result := Result + GenerateBeginEnd(SourceCode.Main) + '.' + LineEnding;
55end;
56
57function TSourceGenerator.GenerateRef(Reference: TSourceReference): string;
58var
59 Value: TSourceValue;
60begin
61 Result := '';
62 if Reference is TSourceReferenceConstant then begin
63 Value := TSourceReferenceConstant(Reference).Constant.Value;
64 if Value is TSourceValueString then
65 Result := Result + '''' + TSourceValueString(Value).Value + ''''
66 else
67 if Value is TSourceValueInteger then
68 Result := Result + IntToStr(TSourceValueInteger(Value).Value);
69 end else
70 if Reference is TSourceReferenceVariable then begin
71 Result := Result + TSourceReferenceVariable(Reference).Variable.Name;
72 end else
73 if Reference is TSourceReferenceArray then begin
74 Result := Result + TSourceReferenceArray(Reference).ArrayRef.Name +
75 '[' + GenerateRef(TSourceReferenceArray(Reference).Index) + ']';
76 end else raise Exception.Create('Unsupported parameter type');
77end;
78
79function TSourceGenerator.GenerateCommand(Command: TSourceCommand): string;
80begin
81 Result := '';
82 if Command is TCommandFunctionCall then
83 with TCommandFunctionCall(Command) do begin
84 if Name = 'print' then begin
85 Result := Result + IndentStr + 'Write(' + GenerateRef(TSourceReference(Parameters[0])) + ');' +
86 LineEnding;
87 end else
88 if Name = 'println' then begin
89 Result := Result + IndentStr + 'WriteLn(' + GenerateRef(TSourceReference(Parameters[0])) + ');' +
90 LineEnding;
91 end else
92 if Name = 'assign' then begin
93 if TSourceReference(Parameters[0]) is TSourceReferenceArray then
94 Result := Result + IndentStr + 'SetLength(' + TSourceReferenceArray(Parameters[0]).ArrayRef.Name +
95 ', ' + GenerateRef(TSourceReferenceArray(Parameters[0]).Index) + ' + 1);' + LineEnding;
96 Result := Result + IndentStr + GenerateRef(TSourceReference(Parameters[0])) + ' := ' +
97 GenerateRef(TSourceReference(Parameters[1])) + ';' + LineEnding;
98 end else
99 if Name = 'inputln' then begin
100 Result := Result + IndentStr + 'ReadLn(' + GenerateRef(TSourceReference(Parameters[0])) + ');' + LineEnding;
101 end else
102 if Name = 'increment' then begin
103 Result := Result + IndentStr + 'Inc(' + GenerateRef(TSourceReference(Parameters[0])) + ', ' +
104 GenerateRef(TSourceReference(Parameters[1])) + ');' + LineEnding;
105 end else
106 if Name = 'decrement' then begin
107 Result := Result + IndentStr + 'Dec(' + GenerateRef(TSourceReference(Parameters[0])) + ', ' +
108 GenerateRef(TSourceReference(Parameters[1])) + ');' + LineEnding;
109 end else
110 raise Exception.Create('Unsupported instruction name.');
111 end else
112 if Command is TCommandBeginEnd then begin
113 Result := Result + GenerateBeginEnd(TCommandBeginEnd(Command)) +
114 ';' + LineEnding;
115 end else
116 if Command is TCommandBreak then begin
117 Result := Result + IndentStr + 'Break;' + LineEnding;
118 end else
119 if Command is TCommandContinue then begin
120 Result := Result + IndentStr + 'Continue;' + LineEnding;
121 end else
122 if Command is TCommandRepeat then begin
123 Result := Result + IndentStr + 'repeat' + LineEnding;
124 Inc(Indent);
125 Result := Result + GenerateCommand(TCommandRepeat(Command).Command);
126 Dec(Indent);
127 Result := Result + IndentStr + 'until False;' + LineEnding;
128 end else
129 if Command is TCommandIfEqual then begin
130 Result := Result + IndentStr + 'if ' +
131 GenerateRef(TCommandIfEqual(Command).Reference1) + ' = ' +
132 GenerateRef(TCommandIfEqual(Command).Reference2) + ' then ' + LineEnding;
133 end else
134 if Command is TCommandIfNotEqual then begin
135 Result := Result + IndentStr + 'if ' +
136 GenerateRef(TCommandIfNotEqual(Command).Reference1) + ' <> ' +
137 GenerateRef(TCommandIfNotEqual(Command).Reference2) + ' then ' + LineEnding;
138 end else
139 raise Exception.Create('Unsupported instruction');
140end;
141
142function TSourceGenerator.GenerateBeginEnd(BeginEnd: TCommandBeginEnd): string;
143var
144 I: Integer;
145begin
146 Result := '';
147 Result := Result + IndentStr + 'begin' + LineEnding;
148 Inc(Indent);
149 with BeginEnd do
150 for I := 0 to Commands.Count - 1 do begin
151 Result := Result + GenerateCommand(TSourceCommand(Commands[I]));
152 end;
153 Dec(Indent);
154 Result := Result + IndentStr + 'end';
155end;
156
157function TSourceGenerator.IndentStr: string;
158begin
159 SetLength(Result, Indent * 2);
160 if Indent > 0 then
161 FillChar(Result[1], Indent * 2, ' ');
162end;
163
164
165end.
166
Note: See TracBrowser for help on using the repository browser.