Changeset 56


Ignore:
Timestamp:
Nov 22, 2023, 11:37:44 PM (5 months ago)
Author:
chronos
Message:
  • Fixed: Assembler to parse correctly register names and numeric values.
Location:
branches/ByteArray
Files:
10 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;
  • branches/ByteArray/Cpu.pas

    r55 r56  
    8888    procedure InstructionDec;
    8989    procedure InstructionDecSize;
     90    procedure InstructionXor;
     91    procedure InstructionXorSize;
     92    procedure InstructionAnd;
     93    procedure InstructionAndSize;
     94    procedure InstructionOr;
     95    procedure InstructionOrSize;
    9096    procedure InitInstructions;
    9197    procedure SetRunning(AValue: Boolean);
     
    469475  RegIndex := ReadRegIndex;
    470476  Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) - 1;
     477end;
     478
     479procedure TCpu.InstructionXor;
     480var
     481  RegIndex: TRegIndex;
     482  RegIndex2: TRegIndex;
     483begin
     484  RegIndex := ReadRegIndex;
     485  RegIndex2 := ReadRegIndex;
     486  Regs[RegIndex] := Regs[RegIndex] xor Regs[RegIndex2];
     487end;
     488
     489procedure TCpu.InstructionXorSize;
     490var
     491  DataSize: TBigIntSize;
     492  RegIndex: TRegIndex;
     493  RegIndex2: TRegIndex;
     494begin
     495  DataSize := ReadSize;
     496  RegIndex := ReadRegIndex;
     497  RegIndex2 := ReadRegIndex;
     498  Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) xor Regs[RegIndex2].Copy(DataSize);
     499end;
     500
     501procedure TCpu.InstructionAnd;
     502var
     503  RegIndex: TRegIndex;
     504  RegIndex2: TRegIndex;
     505begin
     506  RegIndex := ReadRegIndex;
     507  RegIndex2 := ReadRegIndex;
     508  Regs[RegIndex] := Regs[RegIndex] and Regs[RegIndex2];
     509end;
     510
     511procedure TCpu.InstructionAndSize;
     512var
     513  DataSize: TBigIntSize;
     514  RegIndex: TRegIndex;
     515  RegIndex2: TRegIndex;
     516begin
     517  DataSize := ReadSize;
     518  RegIndex := ReadRegIndex;
     519  RegIndex2 := ReadRegIndex;
     520  Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) and Regs[RegIndex2].Copy(DataSize);
     521end;
     522
     523procedure TCpu.InstructionOr;
     524var
     525  RegIndex: TRegIndex;
     526  RegIndex2: TRegIndex;
     527begin
     528  RegIndex := ReadRegIndex;
     529  RegIndex2 := ReadRegIndex;
     530  Regs[RegIndex] := Regs[RegIndex] or Regs[RegIndex2];
     531end;
     532
     533procedure TCpu.InstructionOrSize;
     534var
     535  DataSize: TBigIntSize;
     536  RegIndex: TRegIndex;
     537  RegIndex2: TRegIndex;
     538begin
     539  DataSize := ReadSize;
     540  RegIndex := ReadRegIndex;
     541  RegIndex2 := ReadRegIndex;
     542  Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) or Regs[RegIndex2].Copy(DataSize);
    471543end;
    472544
     
    507579  FInstructions[inDec] := InstructionDec;
    508580  FInstructions[inDecSize] := InstructionDecSize;
     581  FInstructions[inXor] := InstructionXor;
     582  FInstructions[inXorSize] := InstructionXorSize;
     583  FInstructions[inAnd] := InstructionAnd;
     584  FInstructions[inAndSize] := InstructionAndSize;
     585  FInstructions[inOr] := InstructionOr;
     586  FInstructions[inOrSize] := InstructionOrSize;
    509587end;
    510588
  • branches/ByteArray/Devices/Memory.pas

    r55 r56  
    2727    function GetAddressCount: Integer; override;
    2828    procedure SetChannel(Channel: TChannel); override;
     29    procedure SaveToFile(FileName: string);
    2930    procedure Clean;
    3031    property Size: Integer read FSize write SetSize;
     
    136137end;
    137138
     139procedure TMemory.SaveToFile(FileName: string);
     140var
     141  F: TFileStream;
     142begin
     143  if FileExists(FileName) then
     144    F := TFileStream.Create(FileName, fmOpenWrite)
     145    else F := TFileStream.Create(FileName, fmCreate);
     146  try
     147    if FSize > 0 then F.Write(FData[0], FSize);
     148  finally
     149    F.Free;
     150  end;
     151end;
     152
    138153end.
    139154
  • branches/ByteArray/Forms/FormMain.pas

    r50 r56  
    170170    Reset;
    171171
     172    // LD A, 'A'
    172173    WriteInstruction(inLoadConst);
    173174    WriteRegister(riA);
    174175    Write(DataWidth, Ord('A'));
    175176
     177    // LD B, 8
    176178    WriteInstruction(inLoadConst);
    177179    WriteRegister(riB);
    178180    Write(DataWidth, Machine.Serial.BaseAddress);
    179181
     182    // OUT (B), A
    180183    WriteInstruction(inOutput);
    181184    WriteRegister(riB);
    182185    WriteRegister(riA);
    183186
     187    // LD B,
    184188    WriteInstruction(inLoadConst);
    185189    WriteRegister(riB);
  • branches/ByteArray/Forms/FormSourceEditor.lfm

    r50 r56  
    133133      Caption = 'Run'
    134134      OnExecute = ARunExecute
     135      ShortCut = 120
    135136    end
    136137    object ACompile: TAction
    137138      Caption = 'Compile'
    138139      OnExecute = ACompileExecute
     140      ShortCut = 16504
    139141    end
    140142    object ARunToCursor: TAction
    141143      Caption = 'Run to cursor'
     144      ShortCut = 115
    142145    end
    143146    object AStepIn: TAction
    144147      Caption = 'Step in'
     148      ShortCut = 118
    145149    end
    146150    object AStepOut: TAction
    147151      Caption = 'Step out'
     152      ShortCut = 8311
    148153    end
    149154    object AStepOver: TAction
    150155      Caption = 'Step over'
     156      ShortCut = 119
    151157    end
    152158    object APause: TAction
     
    156162      Caption = 'Stop'
    157163      OnExecute = AStopExecute
     164      ShortCut = 16497
    158165    end
    159166  end
  • branches/ByteArray/Forms/FormSourceEditor.pas

    r50 r56  
    113113  with Assembler do begin
    114114    Compile(FormAssembler.SynEdit1.Lines.Text);
    115     //Memory.SaveToFile('compiled.bin');
     115    Memory.SaveToFile('compiled.bin');
    116116    CompiledProgram.Assign(Memory);
    117117    Machine.Memory.Position := 0;
    118118    Machine.Memory.WriteMemoryPos(CompiledProgram);
     119    FormMessages.Messages := Messages;
    119120  end;
    120121  if FormMessages.Visible then
  • branches/ByteArray/Instructions.pas

    r55 r56  
    77
    88type
    9   TParamType = (ptNone, ptNumber, ptReg, ptRegIndirect, ptRegIndirectIndex);
     9  TParamType = (ptNone, ptNumber, ptReg, ptRegIndirect, ptRegIndirectIndex,
     10    ptSize);
    1011  TParamTypeArray = array of TParamType;
    1112
     
    7273  AddNew(inHalt, 'HALT', [], 'It terminates program execution and halts processor. Processor can be waked up by interrupt.');
    7374  AddNew(inLoadConst, 'LD', [ptReg, ptNumber], 'Sets register to immediate constant value.');
     75  AddNew(inLoadConstSize, 'LD', [ptSize, ptReg, ptNumber], 'Sets register to immediate constant value.');
    7476  AddNew(inLoad, 'LD', [ptReg, ptReg], 'Copies value from one register to another.');
    7577  AddNew(inInc, 'INC', [ptReg], 'Increments value in specified register.');
  • branches/ByteArray/Languages/ByteArray.cs.po

    r55 r56  
    1212"X-Generator: Poedit 3.0.1\n"
    1313
     14#: assembler.scompilationfinished
     15msgid "Compilation finished."
     16msgstr "Překlad dokončen."
     17
     18#: assembler.sexpectednumber
     19msgid "Expected number."
     20msgstr "Očekáváno číslo."
     21
     22#: assembler.sexpectednumericindex
     23msgid "Expected numeric register index."
     24msgstr "Očekáván číselný index registru."
     25
     26#: assembler.sexpectedregistername
     27msgid "Expected register name."
     28msgstr "Očekáváno jméno registru."
     29
     30#: assembler.sexpectedvariablename
     31msgid "Expected variable name."
     32msgstr "Očekáváno jméno proměnné."
     33
     34#: assembler.sexpectedvariablevalue
     35msgid "Expected variable value."
     36msgstr "Očekávána hodnota proměnné."
     37
     38#: assembler.sunsupportedparametertype
     39msgid "Unsupported parameter type"
     40msgstr "Nepodporovaný typ parametru"
     41
    1442#: bigint.soutofrange
    1543msgctxt "bigint.soutofrange"
  • branches/ByteArray/Languages/ByteArray.pot

    r55 r56  
    11msgid ""
    22msgstr "Content-Type: text/plain; charset=UTF-8"
     3
     4#: assembler.scompilationfinished
     5msgid "Compilation finished."
     6msgstr ""
     7
     8#: assembler.sexpectednumber
     9msgid "Expected number."
     10msgstr ""
     11
     12#: assembler.sexpectednumericindex
     13msgid "Expected numeric register index."
     14msgstr ""
     15
     16#: assembler.sexpectedregistername
     17msgid "Expected register name."
     18msgstr ""
     19
     20#: assembler.sexpectedvariablename
     21msgid "Expected variable name."
     22msgstr ""
     23
     24#: assembler.sexpectedvariablevalue
     25msgid "Expected variable value."
     26msgstr ""
     27
     28#: assembler.sunsupportedparametertype
     29msgid "Unsupported parameter type"
     30msgstr ""
    331
    432#: bigint.soutofrange
  • branches/ByteArray/Sample.asm

    r46 r56  
    1 # test
     1  NOP
     2
     3  LD A, 64
     4  LD B, 8
     5  OUT (B), A
     6  LD B, 0
     7  LD C, 10
     8  OUT (B), A
     9Loop:
     10  INC A
     11  DEC C
     12  JNZ C, Loop
     13  HALT
Note: See TracChangeset for help on using the changeset viewer.