Ignore:
Timestamp:
Nov 22, 2023, 11:37:44 PM (6 months ago)
Author:
chronos
Message:
  • Fixed: Assembler to parse correctly register names and numeric values.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ByteArray/Assembler.pas

    r55 r56  
    2929    function ParseLabel: Boolean;
    3030    procedure UpdateLabelRefs;
    31     procedure ParseNumParam(Token: TToken);
     31    function ParseNumParam(out Number: TBigInt): Boolean;
     32    function ParseReg(out RegIndex: TRegIndex): Boolean;
    3233  public
    3334    InstructionSet: TInstructionSet;
     
    3637    LabelRefs: TList<TLabelRef>;
    3738    Variables: TDictionary<string, TBigInt>;
    38     Message: TMessages;
     39    Messages: TMessages;
    3940    procedure Error(Text: string; Pos: TPoint);
    4041    procedure Compile(Source: string);
     
    4950implementation
    5051
     52resourcestring
     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
    5161{ TLabelRef }
    5262
     
    7181end;
    7282
    73 procedure TAssembler.ParseNumParam(Token: TToken);
    74 var
    75   Addr: TBigInt;
    76 begin
     83function TAssembler.ParseNumParam(out Number: TBigInt): Boolean;
     84var
     85  Token: TToken;
     86begin
     87  Result := False;
     88  Token := Parser.ReadNext;
    7789  if Token.Kind = tkNumber then begin
    78     if TryStrToBigInt(Token.Value, Addr) then begin
    79       Memory.WritePos(1, Addr);
     90    if TryStrToBigInt(Token.Value, Number) then begin
     91      Result := True;
    8092    end;
    8193  end else
    8294  if Token.Kind = tkIdentifier then begin;
    83     if Variables.TryGetValue(Token.Value, Addr) then begin
    84       Memory.WritePos(1, Addr);
     95    if Variables.TryGetValue(Token.Value, Number) then begin
     96      Result := True;
    8597    end else
    86     if Labels.TryGetValue(Token.Value, Addr) then begin
    87       Memory.WritePos(1, Addr);
     98    if Labels.TryGetValue(Token.Value, Number) then begin
     99      Result := True;
    88100    end else begin
    89101      LabelRefs.Add(TLabelRef.Create(Token.Value, Memory.Position));
    90       Memory.WritePos(1, 0);
     102      Number := 0;
     103      Result := True;
    91104    end;
    92105  end else Error('Unexpected token ' + Token.Value + '.', Token.Pos);
    93106end;
    94107
     108function TAssembler.ParseReg(out RegIndex: TRegIndex): Boolean;
     109var
     110  LastPos: TParserPos;
     111  Token: TToken;
     112begin
     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;
     120end;
     121
    95122procedure TAssembler.Error(Text: string; Pos: TPoint);
    96123begin
    97   Message.AddMessage(Text, Pos);
     124  Messages.AddMessage(Text, Pos);
    98125  if Assigned(FOnError) then
    99126    FOnError(Text, Pos);
     
    102129procedure TAssembler.Compile(Source: string);
    103130begin
    104   Message.Clear;
    105   Memory.Size := 0;
     131  Messages.Clear;
     132  Memory.Size := 1000;
     133  Memory.Position := 0;
    106134  Labels.Clear;
    107135  LabelRefs.Clear;
     
    123151  Parser.Expect(tkEof);
    124152  UpdateLabelRefs;
    125   Error('Compilation finished.', Point(0, 0));
     153  Error(SCompilationFinished, Point(0, 0));
     154  Memory.Size := Memory.Position;
    126155end;
    127156
     
    145174            else Error('Expected number', TokenValue.Pos);
    146175          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);
    149178      if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin
    150179        Continue;
     
    158187var
    159188  Token: TToken;
     189  Number: TBigInt;
    160190begin
    161191  Result := False;
     
    163193    Result := True;
    164194    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;
    170203      if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin
    171204        Continue;
     
    196229  Token: TToken;
    197230  LastPos: TParserPos;
    198   Number: Integer;
     231  RegIndex: TRegIndex;
     232  Number: TBigInt;
    199233begin
    200234  Result := False;
     
    209243        Parser.Expect(tkSpecialSymbol, ',');
    210244      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);
    213247      end else
    214248      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);
    222251      end else
    223252      if InstructionInfo.Params[I] = ptRegIndirect then begin
    224253        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);
    232256        Parser.Expect(tkSpecialSymbol, ')');
    233257      end else
    234258      if InstructionInfo.Params[I] = ptRegIndirectIndex then begin
    235259        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);
    246267        Parser.Expect(tkSpecialSymbol, ')');
    247       end else Error('Unsupported parameter type', Token.Pos);
     268      end else Error(SUnsupportedParameterType, Token.Pos);
    248269    end;
    249270  end;
     
    300321  Parser := TParser.Create;
    301322  Parser.OnError := Error;
    302   Message := TMessages.Create;
     323  Messages := TMessages.Create;
    303324  Memory := TMemory.Create;
    304325  InstructionSet := TInstructionSet.Create;
     
    315336  FreeAndNil(InstructionSet);
    316337  FreeAndNil(Memory);
    317   FreeAndNil(Message);
     338  FreeAndNil(Messages);
    318339  FreeAndNil(Parser);
    319340  inherited;
Note: See TracChangeset for help on using the changeset viewer.