Changeset 56 for branches/ByteArray/Assembler.pas
- Timestamp:
- Nov 22, 2023, 11:37:44 PM (14 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ByteArray/Assembler.pas
r55 r56 29 29 function ParseLabel: Boolean; 30 30 procedure UpdateLabelRefs; 31 procedure ParseNumParam(Token: TToken); 31 function ParseNumParam(out Number: TBigInt): Boolean; 32 function ParseReg(out RegIndex: TRegIndex): Boolean; 32 33 public 33 34 InstructionSet: TInstructionSet; … … 36 37 LabelRefs: TList<TLabelRef>; 37 38 Variables: TDictionary<string, TBigInt>; 38 Message : TMessages;39 Messages: TMessages; 39 40 procedure Error(Text: string; Pos: TPoint); 40 41 procedure Compile(Source: string); … … 49 50 implementation 50 51 52 resourcestring 53 SCompilationFinished = 'Compilation finished.'; 54 SExpectedNumber = 'Expected number.'; 55 SExpectedRegisterName = 'Expected register name.'; 56 SExpectedNumericIndex = 'Expected numeric register index.'; 57 SExpectedVariableName = 'Expected variable name.'; 58 SExpectedVariableValue = 'Expected variable value.'; 59 SUnsupportedParameterType = 'Unsupported parameter type'; 60 51 61 { TLabelRef } 52 62 … … 71 81 end; 72 82 73 procedure TAssembler.ParseNumParam(Token: TToken); 74 var 75 Addr: TBigInt; 76 begin 83 function TAssembler.ParseNumParam(out Number: TBigInt): Boolean; 84 var 85 Token: TToken; 86 begin 87 Result := False; 88 Token := Parser.ReadNext; 77 89 if Token.Kind = tkNumber then begin 78 if TryStrToBigInt(Token.Value, Addr) then begin79 Memory.WritePos(1, Addr);90 if TryStrToBigInt(Token.Value, Number) then begin 91 Result := True; 80 92 end; 81 93 end else 82 94 if Token.Kind = tkIdentifier then begin; 83 if Variables.TryGetValue(Token.Value, Addr) then begin84 Memory.WritePos(1, Addr);95 if Variables.TryGetValue(Token.Value, Number) then begin 96 Result := True; 85 97 end else 86 if Labels.TryGetValue(Token.Value, Addr) then begin87 Memory.WritePos(1, Addr);98 if Labels.TryGetValue(Token.Value, Number) then begin 99 Result := True; 88 100 end else begin 89 101 LabelRefs.Add(TLabelRef.Create(Token.Value, Memory.Position)); 90 Memory.WritePos(1, 0); 102 Number := 0; 103 Result := True; 91 104 end; 92 105 end else Error('Unexpected token ' + Token.Value + '.', Token.Pos); 93 106 end; 94 107 108 function TAssembler.ParseReg(out RegIndex: TRegIndex): Boolean; 109 var 110 LastPos: TParserPos; 111 Token: TToken; 112 begin 113 Result := False; 114 LastPos := Parser.Pos; 115 Token := Parser.ReadNext; 116 if (Length(Token.Value) = 1) and (Token.Value[1] in ['A'..'H']) then begin 117 RegIndex := TRegIndex(Ord(Token.Value[1]) - Ord('A')); 118 Result := True; 119 end else Parser.Pos := LastPos; 120 end; 121 95 122 procedure TAssembler.Error(Text: string; Pos: TPoint); 96 123 begin 97 Message .AddMessage(Text, Pos);124 Messages.AddMessage(Text, Pos); 98 125 if Assigned(FOnError) then 99 126 FOnError(Text, Pos); … … 102 129 procedure TAssembler.Compile(Source: string); 103 130 begin 104 Message.Clear; 105 Memory.Size := 0; 131 Messages.Clear; 132 Memory.Size := 1000; 133 Memory.Position := 0; 106 134 Labels.Clear; 107 135 LabelRefs.Clear; … … 123 151 Parser.Expect(tkEof); 124 152 UpdateLabelRefs; 125 Error('Compilation finished.', Point(0, 0)); 153 Error(SCompilationFinished, Point(0, 0)); 154 Memory.Size := Memory.Position; 126 155 end; 127 156 … … 145 174 else Error('Expected number', TokenValue.Pos); 146 175 end else Error('Duplicate variable name ' + TokenName.Value, TokenName.Pos); 147 end else Error( 'Expected variable value.', TokenValue.Pos);148 end else Error( 'Expected variable name.', TokenName.Pos);176 end else Error(SExpectedVariableValue, TokenValue.Pos); 177 end else Error(SExpectedVariableName, TokenName.Pos); 149 178 if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin 150 179 Continue; … … 158 187 var 159 188 Token: TToken; 189 Number: TBigInt; 160 190 begin 161 191 Result := False; … … 163 193 Result := True; 164 194 while True do begin 165 Token := Parser.ReadNext; 166 if Token.Kind = tkString then begin 167 Memory.WriteStringPos(Token.Value); 168 end else 169 ParseNumParam(Token); 195 if ParseNumParam(Number) then begin 196 Memory.WritePos(1, Number); 197 end else begin 198 Token := Parser.ReadNext; 199 if Token.Kind = tkString then begin 200 Memory.WriteStringPos(Token.Value); 201 end else raise Exception.Create('Expected parameter'); 202 end; 170 203 if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin 171 204 Continue; … … 196 229 Token: TToken; 197 230 LastPos: TParserPos; 198 Number: Integer; 231 RegIndex: TRegIndex; 232 Number: TBigInt; 199 233 begin 200 234 Result := False; … … 209 243 Parser.Expect(tkSpecialSymbol, ','); 210 244 if InstructionInfo.Params[I] = ptNumber then begin 211 Token := Parser.ReadNext;212 ParseNumParam(Token);245 if ParseNumParam(Number) then Memory.WritePos(1, Number) 246 else Error(SExpectedNumber, Token.Pos); 213 247 end else 214 248 if InstructionInfo.Params[I] = ptReg then begin 215 Token := Parser.ReadNext; 216 if (Token.Value <> '') and (Token.Value[1] = 'R') then begin 217 Token.Value := Copy(Token.Value, 2, MaxInt); 218 if TryStrToInt(Token.Value, Number) then 219 Memory.WritePos(1, Number) 220 else Error('Expected numeric register index error', Token.Pos); 221 end else Error('Expected register name starting with R character.', Token.Pos); 249 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 250 else Error(SExpectedRegisterName, Token.Pos); 222 251 end else 223 252 if InstructionInfo.Params[I] = ptRegIndirect then begin 224 253 Parser.Expect(tkSpecialSymbol, '('); 225 Token := Parser.ReadNext; 226 if (Token.Value <> '') and (Token.Value[1] = 'R') then begin 227 Token.Value := Copy(Token.Value, 2, MaxInt); 228 if TryStrToInt(Token.Value, Number) then 229 Memory.WritePos(1, Number) 230 else Error('Expected numeric register index error', Token.Pos); 231 end else Error('Expected register name starting with R character.', Token.Pos); 254 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 255 else Error(SExpectedRegisterName, Token.Pos); 232 256 Parser.Expect(tkSpecialSymbol, ')'); 233 257 end else 234 258 if InstructionInfo.Params[I] = ptRegIndirectIndex then begin 235 259 Parser.Expect(tkSpecialSymbol, '('); 236 Token := Parser.ReadNext; 237 if (Token.Value <> '') and (Token.Value[1] = 'R') then begin 238 Token.Value := Copy(Token.Value, 2, MaxInt); 239 if TryStrToInt(Token.Value, Number) then begin 240 Memory.WritePos(1, Number); 241 Parser.Expect(tkSpecialSymbol, '+'); 242 Token := Parser.ReadNext; 243 ParseNumParam(Token); 244 end else Error('Expected numeric register index error', Token.Pos); 245 end else Error('Expected register name starting with R character.', Token.Pos); 260 if ParseReg(RegIndex) then begin 261 Memory.WritePos(1, Byte(RegIndex)); 262 Parser.Expect(tkSpecialSymbol, '+'); 263 Token := Parser.ReadNext; 264 if ParseNumParam(Number) then Memory.WritePos(1, Number) 265 else Error(SExpectedNumericIndex, Token.Pos); 266 end else Error(SExpectedRegisterName, Token.Pos); 246 267 Parser.Expect(tkSpecialSymbol, ')'); 247 end else Error( 'Unsupported parameter type', Token.Pos);268 end else Error(SUnsupportedParameterType, Token.Pos); 248 269 end; 249 270 end; … … 300 321 Parser := TParser.Create; 301 322 Parser.OnError := Error; 302 Message := TMessages.Create;323 Messages := TMessages.Create; 303 324 Memory := TMemory.Create; 304 325 InstructionSet := TInstructionSet.Create; … … 315 336 FreeAndNil(InstructionSet); 316 337 FreeAndNil(Memory); 317 FreeAndNil(Message );338 FreeAndNil(Messages); 318 339 FreeAndNil(Parser); 319 340 inherited;
Note:
See TracChangeset
for help on using the changeset viewer.