Changeset 142
- Timestamp:
- Jan 16, 2018, 3:19:23 PM (7 years ago)
- Location:
- branches/easy compiler
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/easy compiler/Steps.txt
r141 r142 1 2 1 3 2 Add abstract compiler … … 17 16 Add integer type 18 17 - support for mutiple types 18 Add begin-end block support 19 - local variables, constants, types -
branches/easy compiler/UCompiler.pas
r141 r142 41 41 private 42 42 Tokenizer: TTokenizer; 43 procedure Parse(Tokens: TSourceTokens; Code: TSourceCode); 43 procedure Parse(Code: TSourceCode); 44 procedure ParseBeginEnd(BeginEnd: TSourceBeginEnd); 44 45 public 45 46 procedure Compile(Source: string; SourceCode: TSourceCode); … … 168 169 { TCompiler } 169 170 170 procedure TCompiler.Parse(Tokens: TSourceTokens; Code: TSourceCode); 171 procedure TCompiler.Parse(Code: TSourceCode); 172 begin 173 Tokenizer.TokenIndex := 0; 174 ParseBeginEnd(Code.Main); 175 end; 176 177 procedure TCompiler.ParseBeginEnd(BeginEnd: TSourceBeginEnd); 171 178 var 172 179 Token: TSourceToken; … … 186 193 NewReference := TSourceReferenceConstant.Create; 187 194 TSourceReferenceConstant(NewReference).Constant := 188 Code.Constants.AddNewString(Token.Text);195 BeginEnd.SourceCode.Constants.AddNewString(Token.Text); 189 196 end else 190 197 if Token.Kind = stIdentifier then begin 191 198 NewReference := TSourceReferenceVariable.Create; 192 199 TSourceReferenceVariable(NewReference).Variable := 193 Code.Variables.Search(Token.Text);200 BeginEnd.SourceCode.Variables.Search(Token.Text); 194 201 if TSourceReferenceVariable(NewReference).Variable = nil then 195 202 raise Exception.Create('Variable not found: ' + Token.Text); … … 198 205 NewReference := TSourceReferenceConstant.Create; 199 206 TSourceReferenceConstant(NewReference).Constant := 200 Code.Constants.AddNewInteger(StrToInt(Token.Text));207 BeginEnd.SourceCode.Constants.AddNewInteger(StrToInt(Token.Text)); 201 208 end else 202 209 raise Exception.Create('Unexpected parameter'); … … 210 217 NewReference := TSourceReferenceVariable.Create; 211 218 TSourceReferenceVariable(NewReference).Variable := 212 Code.Variables.Search(Token.Text);219 BeginEnd.SourceCode.Variables.Search(Token.Text); 213 220 if TSourceReferenceVariable(NewReference).Variable = nil then 214 221 raise Exception.Create('Variable not found: ' + Token.Text); … … 219 226 220 227 begin 221 Tokenizer.TokenIndex := 0; 222 while Tokenizer.TokenIndex < Length(Tokens.Tokens) do begin 228 while True do begin 223 229 Token := Tokenizer.GetNext; 230 if Token.Kind = stEof then Break 231 else 224 232 if Token.Kind = stIdentifier then begin 225 233 Keyword := LowerCase(Token.Text); … … 229 237 if Token2.Kind <> stIdentifier then 230 238 raise Exception.Create('Expected type parameter'); 231 Variable := Code.Variables.Search(Token.Text);239 Variable := BeginEnd.SourceCode.Variables.Search(Token.Text); 232 240 if not Assigned(Variable) then begin 233 ValueType := Code.Types.Search(Token2.Text);241 ValueType := BeginEnd.SourceCode.Types.Search(Token2.Text); 234 242 if not Assigned(ValueType) then 235 243 raise Exception.Create('Unsupported type: ' + Token2.Text); 236 Variable := Code.Variables.AddNew(Token.Text,244 Variable := BeginEnd.SourceCode.Variables.AddNew(Token.Text, 237 245 ValueType); 238 end else raise Exception.Create('Variable redefined'); 239 end else begin 240 Funct := Code.Functions.Search(Keyword); 246 end else raise Exception.Create('Variable redefined: ' + Token.Text); 247 end else 248 if Keyword = 'begin' then begin 249 Instruction := TSourceBeginEnd.Create; 250 BeginEnd.Instructions.Add(Instruction); 251 TSourceBeginEnd(Instruction).SourceCode := BeginEnd.SourceCode; 252 ParseBeginEnd(TSourceBeginEnd(Instruction)); 253 end else 254 if Keyword = 'end' then begin 255 Break; 256 end else 257 begin 258 Funct := BeginEnd.SourceCode.Functions.Search(Keyword); 241 259 if Assigned(Funct) then begin 242 Instruction := TSource InstructionFunction.Create;243 TSource InstructionFunction(Instruction).Name := Keyword;260 Instruction := TSourceFunctionCall.Create; 261 TSourceFunctionCall(Instruction).Name := Keyword; 244 262 for Param in Funct.Parameters do 245 263 if Param.Kind = pkString then begin 246 TSource InstructionFunction(Instruction).AddParameter(ParseReference)264 TSourceFunctionCall(Instruction).AddParameter(ParseReference) 247 265 end else 248 266 if Param.Kind = pkVariable then begin 249 TSource InstructionFunction(Instruction).AddParameter(ParseReferenceVariable(True));267 TSourceFunctionCall(Instruction).AddParameter(ParseReferenceVariable(True)); 250 268 end else 251 269 raise Exception.Create('Unsupported parameter type.'); 252 Code.Instructions.Add(Instruction);270 BeginEnd.Instructions.Add(Instruction); 253 271 end else raise Exception.Create('Unsupported keyword: ' + Token.Text); 254 272 end; … … 265 283 266 284 Tokenizer.Tokenize(Source, SourceTokens); 267 Parse(Source Tokens, SourceCode);285 Parse(SourceCode); 268 286 269 287 Tokenizer.Free; … … 277 295 TargetInstruction: TTargetInstruction; 278 296 begin 279 Target.Instructions.Count := 0;297 { Target.Instructions.Count := 0; 280 298 for I := 0 to SourceCode.Instructions.Count - 1 do begin 281 299 Instruction := TSourceInstruction(SourceCode.Instructions[I]); 282 if Instruction is TSource InstructionFunctionthen begin300 if Instruction is TSourceFunctionCall then begin 283 301 TargetInstruction := TTargetInstruction.Create; 284 302 TargetInstruction.Kind := tiFunction; 285 TargetInstruction.Name := TSource InstructionFunction(Instruction).Name;303 TargetInstruction.Name := TSourceFunctionCall(Instruction).Name; 286 304 Target.Instructions.Add(TargetInstruction) 287 305 end else raise Exception.Create('Unsupported source instruction'); 288 306 end; 307 } 289 308 end; 290 309 -
branches/easy compiler/UFormMain.pas
r141 r142 63 63 Add('InputLn Value2'); 64 64 65 Add('begin'); 65 66 Add('Assign Result Value1'); 66 67 Add('Increment Result Value2'); 67 68 Add('Print ''Sum of two values is: '''); 68 69 Add('PrintLn Result'); 70 Add('end'); 69 71 end; 70 72 { with MemoSource.Lines do begin … … 99 101 Add('Assign AnimalCount 2'); 100 102 Add('Repeat'); 101 Add('Begin Block');103 Add('Begin'); 102 104 Add('PrintLn ''Think an animal.'''); 103 105 Add('Assign I 0'); 104 106 Add('Repeat'); 105 Add('Begin Block');107 Add('Begin'); 106 108 Add('Print AnimalProperty[I]'); 107 109 Add('Print ''? (y/n)'''); 108 110 Add('InputLn Answer'); 109 111 Add('IfEqual Answer ''y'''); 110 Add('Begin Block');112 Add('Begin'); 111 113 Add('PrintLn ''That''s clear. It is '''); 112 114 Add('PrintLn AnimalName[I]'); 113 115 Add('Break'); 114 Add('End Block');116 Add('End'); 115 117 Add('Increment I'); 116 118 Add('IfHigherOrEqual I AnimalCount'); 117 119 Add('Break'); 118 Add('End Block');120 Add('End'); 119 121 Add('PrintLn ''I am lost. What is the animal?'''); 120 122 Add('InputLn AnimalName[I]'); … … 124 126 Add('Increment AnimalCount 1'); 125 127 Add('PrintLn '''''); 126 Add('End Block');128 Add('End'); 127 129 end; 128 130 } -
branches/easy compiler/USourceCode.pas
r141 r142 116 116 end; 117 117 118 { TSource InstructionFunction}119 120 TSource InstructionFunction= class(TSourceInstruction)118 { TSourceFunctionCall } 119 120 TSourceFunctionCall = class(TSourceInstruction) 121 121 Name: string; 122 122 Parameters: array of TSourceReference; 123 123 procedure AddParameter(Value: TSourceReference); 124 end; 125 126 TSourceCode = class; 127 128 { TSourceBeginEnd } 129 130 TSourceBeginEnd = class(TSourceInstruction) 131 SourceCode: TSourceCode; 132 Instructions: TSourceInstructions; 133 constructor Create; 134 destructor Destroy; override; 124 135 end; 125 136 … … 134 145 Constants: TSourceConstants; 135 146 Functions: TSourceFunctions; 136 Instructions: TSourceInstructions;147 Main: TSourceBeginEnd; 137 148 constructor Create; 138 149 destructor Destroy; override; … … 141 152 142 153 implementation 154 155 { TSourceBeginEnd } 156 157 constructor TSourceBeginEnd.Create; 158 begin 159 Instructions := TSourceInstructions.Create; 160 end; 161 162 destructor TSourceBeginEnd.Destroy; 163 begin 164 Instructions.Free; 165 inherited Destroy; 166 end; 143 167 144 168 { TSourceTypes } … … 290 314 end; 291 315 292 { TSource InstructionFunction}293 294 procedure TSource InstructionFunction.AddParameter(Value: TSourceReference);316 { TSourceFunctionCall } 317 318 procedure TSourceFunctionCall.AddParameter(Value: TSourceReference); 295 319 begin 296 320 SetLength(Parameters, Length(Parameters) + 1); … … 339 363 Constants := TSourceConstants.Create; 340 364 Functions := TSourceFunctions.Create; 341 Instructions := TSourceInstructions.Create; 365 Main := TSourceBeginEnd.Create; 366 Main.SourceCode := Self; 342 367 InitFunctions; 343 368 end; … … 345 370 destructor TSourceCode.Destroy; 346 371 begin 347 Instructions.Free;372 Main.Free; 348 373 Functions.Free; 349 374 Variables.Free; -
branches/easy compiler/USourceExecutor.pas
r141 r142 28 28 FOnOutput: TOutputEvent; 29 29 Variables: TExecutorVariables; 30 procedure ExecuteBeginEnd(BeginEnd: TSourceBeginEnd); 30 31 public 31 32 constructor Create; … … 68 69 69 70 procedure TSourceExecutor.Execute(SourceCode: TSourceCode); 71 begin 72 ExecuteBeginEnd(SourceCode.Main); 73 end; 74 75 procedure TSourceExecutor.ExecuteBeginEnd(BeginEnd: TSourceBeginEnd); 70 76 var 71 77 IP: Integer; … … 96 102 begin 97 103 IP := 0; 98 while IP < SourceCode.Instructions.Count do begin99 Instruction := TSourceInstruction( SourceCode.Instructions[IP]);100 if Instruction is TSource InstructionFunctionthen101 with TSource InstructionFunction(Instruction) do begin104 while IP < BeginEnd.Instructions.Count do begin 105 Instruction := TSourceInstruction(BeginEnd.Instructions[IP]); 106 if Instruction is TSourceFunctionCall then 107 with TSourceFunctionCall(Instruction) do begin 102 108 if Name = 'print' then begin 103 109 if Assigned(FOnOutput) then begin … … 156 162 else raise Exception.Create('Wrong type for increment'); 157 163 end else 158 raise Exception.Create('Unsupported function: ' + TSourceInstructionFunction(Instruction).Name); 159 end else raise Exception.Create('Unsupported instruction'); 164 raise Exception.Create('Unsupported function: ' + TSourceFunctionCall(Instruction).Name); 165 end else 166 if Instruction is TSourceBeginEnd then begin 167 ExecuteBeginEnd(TSourceBeginEnd(Instruction)); 168 end else 169 raise Exception.Create('Unsupported instruction'); 160 170 Inc(IP); 161 171 end; -
branches/easy compiler/USourceGenerator.pas
r141 r142 12 12 13 13 TSourceGenerator = class 14 private 15 function GenerateBeginEnd(BeginEnd: TSourceBeginEnd): string; 16 public 14 17 function Generate(SourceCode: TSourceCode): string; 15 18 end; … … 21 24 22 25 function TSourceGenerator.Generate(SourceCode: TSourceCode): string; 26 var 27 I: Integer; 28 begin 29 Result := ''; 30 if SourceCode.Variables.Count > 0 then 31 Result := Result + 'var' + LineEnding; 32 with SourceCode do 33 for I := 0 to Variables.Count - 1 do 34 with TSourceVariable(Variables[I]) do begin 35 Result := Result + ' ' + Name + ': '; 36 if ValueType.Name = 'String' then 37 Result := Result + 'string' 38 else if ValueType.Name = 'Integer' then 39 Result := Result + 'Integer' 40 else raise Exception.Create('Unsupported type'); 41 Result := Result + ';' + LineEnding; 42 end; 43 Result := Result + GenerateBeginEnd(SourceCode.Main) + '.' + LineEnding; 44 end; 45 46 function TSourceGenerator.GenerateBeginEnd(BeginEnd: TSourceBeginEnd): string; 23 47 var 24 48 Output: string; … … 45 69 begin 46 70 Output := ''; 47 if SourceCode.Variables.Count > 0 then48 Output := Output + 'var' + LineEnding;49 with SourceCode do50 for I := 0 to Variables.Count - 1 do51 with TSourceVariable(Variables[I]) do begin52 Output := Output + ' ' + Name + ': ';53 if ValueType.Name = 'String' then54 Output := Output + 'string'55 else if ValueType.Name = 'Integer' then56 Output := Output + 'Integer'57 else raise Exception.Create('Unsupported type');58 Output := Output + ';' + LineEnding;59 end;60 71 Output := Output + 'begin' + LineEnding; 61 with SourceCodedo72 with BeginEnd do 62 73 for I := 0 to Instructions.Count - 1 do begin 63 74 Instruction := TSourceInstruction(Instructions[I]); 64 if Instruction is TSource InstructionFunctionthen65 with TSource InstructionFunction(Instruction) do begin75 if Instruction is TSourceFunctionCall then 76 with TSourceFunctionCall(Instruction) do begin 66 77 if Name = 'print' then begin 67 78 Output := Output + ' Write(' + GenerateRef(Parameters[0]) + ');' + … … 84 95 end else 85 96 raise Exception.Create('Unsupported instruction name.'); 86 end else raise Exception.Create('Unsupported instruction'); 97 end else 98 if Instruction is TSourceBeginEnd then begin 99 Output := Output + GenerateBeginEnd(TSourceBeginEnd(Instruction)) + 100 ';' + LineEnding; 101 end else 102 raise Exception.Create('Unsupported instruction'); 87 103 end; 88 Output := Output + 'end .' + LineEnding;104 Output := Output + 'end'; 89 105 Result := Output; 90 106 end;
Note:
See TracChangeset
for help on using the changeset viewer.